Esercizio - Kernel e confronto tra SVM
Questa pagina non ha ancora la versione ripasso: qui sotto c'è il testo completo.
In questa pagina 6
Testo.
- Con la mappa di grado 2 si verifichi per , .
- Quattro punti (problema XOR): classe in e , classe in e . Si mostri che nessun iperpiano li separa nel piano, si trovi una feature che li rende separabili e si calcoli il margine.
- Per lo stesso problema si calcoli la matrice del kernel e si ricavi e il classificatore in forma duale.
- Kernel RBF: si calcoli per , con e si commenti.
- Quante componenti ha la mappa polinomiale completa di grado 3 per attributi? Perché si usa il kernel?
Teoria usata: Support vector machines e metodi kernelUna SVM cerca l'iperpiano $w\cdot x+b=0$ che separa due classi con il margine più largo possibile: normalizzando $y_i(w\cdot x_i+b)\ge1$ il margine totale vale $2/|w|$, quindi si risolve $\min\frac12|w|^2$ (problema convesso, nessun minimo locale). Con classi sovrapposte si ammettono errori con le variabili di scarto $\xi_i$ e il parametro $C$ (soft margin, equivalente alla hinge loss più una penalità su $|w|^2$); $C$ piccolo = margine largo e più bias, $C$ grande = margine stretto e più varianza, si sceglie per cross-validation. La soluzione dipende solo dai vettori di supporto ($w=\sum\alpha_iy_ix_i$) e solo tramite prodotti scalari, per questo si può sostituire $x_i\cdot x_j$ con un kernel $K(x_i,x_j)=\langle\phi(x_i),\phi(x_j)\rangle$ (polinomiale, RBF) senza calcolare $\phi$: così si ottengono bordi non lineari. La SVR usa lo stesso schema con un tubo di tolleranza $\varepsilon$. Nell'esame le SVM sono solo nella parte teorica.Support vector machines e metodi kernel →, Prodotto scalare, norma e angoliIl prodotto scalare aggiunge a uno spazio vettoriale lunghezze e angoli: norma, disuguaglianza di Cauchy-Schwarz, angolo tra vettori in R^n, ortogonalità, proiezione su una retta, aree e volumi con il determinante della matrice dei prodotti scalari.Prodotto scalare, norma e angoli →.
1. Verifica del kernel polinomiale
, quindi .
Con la mappa: e . Prodotto scalare componente per componente: ✓. I due calcoli coincidono, ma il primo usa un solo prodotto scalare in .
2. Il problema XOR
Non separabile. Un iperpiano (retta) dovrebbe dare e (i due punti ), e (i due ). Sommando le prime due: . Sommando le ultime due: . Contraddizione: nessuna retta separa le classi.
Feature aggiuntiva. Si usa . I due punti hanno , i due hanno : in il piano (con ) li separa. Con , : per tutti e quattro. Il margine totale è e tutti e quattro i punti sono vettori di supporto.
3. Forma duale con il kernel
Prodotti scalari : tra un punto e sé stesso, tra punti opposti, tra punti con una coordinata che cambia segno. Quindi vale sulla diagonale, tra punti opposti, negli altri casi: nell'ordine
Per simmetria i quattro punti hanno lo stesso e (la condizione vale perché ). Per il punto la condizione sul margine con dà , quindi .
Classificatore: . Con i quattro termini sono . La somma dei primi due è , quella degli ultimi due , la differenza . Quindi : coincide con la feature trovata al punto 2. Il bordo di decisione è , cioè i due assi, e la classe è .
4. Kernel RBF
, :
Con piccolo punti a distanza sono ancora «molto simili» (influenza larga, bordo liscio, rischio di underfitting); con sono già praticamente scorrelati (ogni vettore di supporto influenza solo il suo intorno, bordo frastagliato, rischio di overfitting). si sceglie per cross-validation insieme a .
5. Dimensione della mappa
I monomi di grado al più in variabili sono . Calcolare e memorizzare vettori di quella lunghezza per ogni campione è oneroso; con il kernel basta un prodotto scalare in e una potenza. Il kernel RBF corrisponde invece a una mappa di dimensione infinita, che non si potrebbe nemmeno scrivere.
Verifica numerica
import numpy as np
phi = lambda v: np.array([v[0]**2, v[1]**2, np.sqrt(2)*v[0]*v[1], np.sqrt(2)*v[0], np.sqrt(2)*v[1], 1])
x, z = np.array([2, -1]), np.array([0, 3])
print(phi(x) @ phi(z), (x @ z + 1) ** 2) # 4.0 4
from sklearn.svm import SVC
X = np.array([[1,1],[-1,-1],[1,-1],[-1,1]]); y = np.array([1,1,-1,-1])
SVC(kernel="poly", degree=2, gamma=1, coef0=1, C=1e6).fit(X, y).dual_coef_ # |alpha| = 0.125