Învățare supervizată

2.3 Regularizarea L1 și L2

Când modelul învață „pe de rost" datele de antrenare, regularizarea îl obligă să rămână simplu — penalizând coeficienții mari.

Teorie

Reducerea supraînvățării (overfitting)

Un model supraînvățat are scor excelent pe train și slab pe validare (detaliem fenomenul în lecția 4.2). La modelele liniare, simptomul tipic sunt coeficienți uriași care se compensează reciproc. Soluția: adăugăm la funcția de cost o penalizare pentru coeficienți mari:

L2 (Ridge): cost = MSE + α · Σ wᵢ²

L1 (Lasso): cost = MSE + α · Σ |wᵢ|

Parametrul α (alpha) controlează cât de dură e penalizarea: α = 0 → regresie obișnuită; α foarte mare → toți coeficienții împinși spre 0 (underfitting).

Lasso vs. Ridge — comparație

Ridge (L2)Lasso (L1)
Penalizarepătratul coeficiențilormodulul coeficienților
Efect asupra coeficiențilorîi micșorează pe toți, dar rar ajung exact 0îi duce pe unii exact la 0
Folos suplimentarstabilitate când feature-urile sunt corelateselecție automată de feature-uri
Când îl alegimulte feature-uri toate cât de cât utilebănuiești că doar câteva feature-uri contează
Există și ElasticNet, care combină L1 și L2. Iar la LogisticRegression, parametrul C este inversul lui α: C mic = regularizare puternică.

Aplicare în scikit-learn

from sklearn.linear_model import Ridge, Lasso, LinearRegression
from sklearn.preprocessing import StandardScaler

# regularizarea cere date standardizate!
sc = StandardScaler()
X_tr_s = sc.fit_transform(X_train)
X_va_s = sc.transform(X_val)

for Model, nume in [(LinearRegression, "simplu"), (Ridge, "ridge"), (Lasso, "lasso")]:
    model = Model() if nume == "simplu" else Model(alpha=1.0)
    model.fit(X_tr_s, y_train)
    print(nume, model.score(X_va_s, y_val))

lasso = Lasso(alpha=0.1).fit(X_tr_s, y_train)
pastrate = [f for f, w in zip(X_train.columns, lasso.coef_) if w != 0]
print("Feature-uri păstrate de Lasso:", pastrate)

Problemă rezolvată: overfitting provocat și vindecat

Experiment: polinoame + regularizare Mediu Rezolvată

Construim intenționat un model care supraînvață (regresie polinomială de grad 15 pe 30 de puncte), apoi îl reparăm cu Ridge — cel mai clar mod de a vedea regularizarea.

Codul experimentului
import numpy as np, matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures, StandardScaler
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.pipeline import make_pipeline

rng = np.random.RandomState(42)
X = np.sort(rng.uniform(0, 1, 30)).reshape(-1, 1)
y = np.sin(2 * np.pi * X).ravel() + rng.normal(0, 0.2, 30)

X_plot = np.linspace(0, 1, 300).reshape(-1, 1)
for model, eticheta in [
    (make_pipeline(PolynomialFeatures(15), StandardScaler(), LinearRegression()), "fără regularizare"),
    (make_pipeline(PolynomialFeatures(15), StandardScaler(), Ridge(alpha=0.1)), "Ridge α=0.1"),
]:
    model.fit(X, y)
    plt.plot(X_plot, model.predict(X_plot), label=eticheta)

plt.scatter(X, y, c="k", s=15)
plt.ylim(-2, 2); plt.legend(); plt.show()

Ce observi: modelul fără regularizare oscilează sălbatic ca să treacă prin fiecare punct (memorare); Ridge dă o curbă netedă, apropiată de sinusoida reală (generalizare).

Probleme propuse

1. Drumul coeficienților Exercițiu

Pentru α ∈ {0.001, 0.01, 0.1, 1, 10, 100}, antrenează Lasso pe un dataset cu 10+ feature-uri și desenează cum evoluează fiecare coeficient în funcție de α (scară logaritmică). Câte feature-uri supraviețuiesc la α = 10?

2. Lasso ca detector Exercițiu

Adaugă la un dataset real 5 coloane de zgomot pur aleator. Verifică dacă Lasso le elimină (coeficient 0) și dacă Ridge doar le micșorează.

3. Aplicare la concurs Platformă

Reia problema prețului caselor (lecția 2.1) și compară pe validare: LinearRegression, Ridge și Lasso cu mai multe valori α. Alegerea lui α se face corect cu cross-validation — vezi lecția 4.3.