Învățare supervizată

2.7 Mașini cu vectori suport (SVM)

SVM caută granița care separă clasele cu cea mai largă „zonă de siguranță" posibilă. Cu trucul kernel, separă și date care nu pot fi despărțite de o linie dreaptă.

Teorie

Separatoare liniare și marginea maximă

Între două clase separabile există o infinitate de drepte despărțitoare. SVM o alege pe cea care maximizează marginea — distanța până la cele mai apropiate puncte din fiecare clasă. Acele puncte de la frontieră se numesc vectori suport: doar ei determină granița, restul datelor nu contează.

De ce marginea maximă? O graniță „înghesuită" lângă puncte e fragilă; una cu spațiu de siguranță generalizează mai bine pe date noi.

Parametrul C — cât de stricți suntem

C mic (0.01)C mare (100)
margine largă, tolerează puncte greșit clasificate → mai simplu, risc de underfitting pedepsește orice greșeală pe train → graniță contorsionată, risc de overfitting

Kernel și parametrul γ (gamma)

Când datele nu sunt liniar separabile, kernelul le proiectează implicit într-un spațiu cu mai multe dimensiuni, unde devin separabile. Cel mai folosit: RBF (radial). Parametrul γ controlează raza de influență a unui exemplu: γ mic → graniță netedă; γ mare → graniță care „îmbrățișează" fiecare punct (overfitting).

Implementare în scikit-learn

from sklearn.svm import SVC, LinearSVC
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline

# scalarea este OBLIGATORIE la SVM
model = make_pipeline(
    StandardScaler(),
    SVC(kernel="rbf", C=1.0, gamma="scale")
)
model.fit(X_train, y_train)
print(model.score(X_val, y_val))

# pentru probabilități: SVC(probability=True) — mai lent
# pentru date multe și liniar separabile: LinearSVC (mult mai rapid)
C și γ se caută împreună pe grilă logaritmică (0.01, 0.1, 1, 10, 100) cu GridSearchCV — exact subiectul lecției 4.3.

Problemă rezolvată: vizualizarea efectului C și γ

Experiment: granițe de decizie pe date „lună" Mediu Rezolvată

Pe un dataset 2D neseparabil liniar (make_moons), desenăm granițele de decizie pentru mai multe combinații C/γ — cea mai rapidă cale de a căpăta intuiție pentru SVM.

Codul experimentului
import numpy as np, matplotlib.pyplot as plt
from sklearn.datasets import make_moons
from sklearn.svm import SVC

X, y = make_moons(n_samples=200, noise=0.25, random_state=42)

xx, yy = np.meshgrid(np.linspace(-2, 3, 300), np.linspace(-1.5, 2, 300))
combinatii = [(0.1, 0.5), (1, 0.5), (100, 0.5), (1, 0.01), (1, 1), (1, 50)]

fig, axes = plt.subplots(2, 3, figsize=(14, 8))
for ax, (C, gamma) in zip(axes.ravel(), combinatii):
    model = SVC(kernel="rbf", C=C, gamma=gamma).fit(X, y)
    Z = model.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
    ax.contourf(xx, yy, Z, alpha=0.25)
    ax.scatter(X[:, 0], X[:, 1], c=y, s=12)
    ax.set_title(f"C={C}, γ={gamma} — acc train: {model.score(X, y):.2f}")
plt.tight_layout(); plt.show()

De urmărit: γ=50 dă acuratețe ~1.00 pe train cu insulițe în jurul fiecărui punct — overfitting clasic; C=0.1 dă o graniță aproape dreaptă care taie prin ambele clase — underfitting. Echilibrul: C=1, γ=0.5.

Probleme propuse

1. Vectorii suport la lucru Exercițiu

Antrenează un SVM liniar pe date 2D separabile, apoi șterge din train toate punctele care NU sunt vectori suport (model.support_) și reantrenează. Compară granițele — ce demonstrează asta?

2. Duelul modelelor Exercițiu

Pe datele diabetului (lecția 2.2), compară prin cross-validation: regresie logistică, K-NN, arbore, Random Forest și SVM cu RBF. Fă clasamentul și explică pozițiile.

3. Grid pentru C și γ Exercițiu

Caută pe grilă C, γ ∈ {0.01, 0.1, 1, 10, 100} pe orice problemă de clasificare de pe platformă și raportează combinația câștigătoare cu scorul ei.