Support Vector Machine (SVM)
Introduzione a SVM
Le Support Vector Machine (SVM) sono algoritmi di apprendimento automatico supervisionato potenti ma flessibili che vengono utilizzati sia per la classificazione che per la regressione. Ma generalmente vengono utilizzati nei problemi di classificazione. Negli anni '60, gli SVM furono introdotti per la prima volta ma in seguito furono perfezionati nel 1990. Gli SVM hanno il loro modo di implementazione unico rispetto ad altri algoritmi di apprendimento automatico. Ultimamente sono estremamente popolari per la loro capacità di gestire più variabili continue e categoriali.
Funzionamento di SVM
Un modello SVM è fondamentalmente una rappresentazione di classi differenti in un iperpiano nello spazio multidimensionale. L'iperpiano verrà generato in modo iterativo da SVM in modo che l'errore possa essere ridotto al minimo. L'obiettivo di SVM è dividere i set di dati in classi per trovare un iperpiano marginale massimo (MMH).
I seguenti sono concetti importanti in SVM:
Support Vectors- I punti dati più vicini all'iperpiano sono chiamati vettori di supporto. La linea di separazione verrà definita con l'aiuto di questi punti dati.
Hyperplane - Come possiamo vedere nel diagramma sopra, è un piano o spazio decisionale che è diviso tra un insieme di oggetti aventi classi diverse.
Margin- Può essere definito come il divario tra due linee sui punti dati dell'armadio di classi diverse. Può essere calcolato come la distanza perpendicolare dalla linea ai vettori di supporto. Un margine ampio è considerato un buon margine e un margine piccolo è considerato un margine negativo.
L'obiettivo principale di SVM è dividere i set di dati in classi per trovare un iperpiano marginale massimo (MMH) e può essere fatto nei due passaggi seguenti:
Innanzitutto, SVM genererà iperpiani in modo iterativo che segrega le classi nel modo migliore.
Quindi, sceglierà l'iperpiano che separa correttamente le classi.
Implementazione di SVM in Python
Per implementare SVM in Python inizieremo con l'importazione delle librerie standard come segue:
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
import seaborn as sns; sns.set()
Successivamente, stiamo creando un set di dati di esempio, con dati separabili linearmente, da sklearn.dataset.sample_generator per la classificazione utilizzando SVM -
from sklearn.datasets.samples_generator import make_blobs
X, y = make_blobs(n_samples=100, centers=2, random_state=0, cluster_std=0.50)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer');
Il seguente sarebbe l'output dopo la generazione di un set di dati campione con 100 campioni e 2 cluster:
Sappiamo che SVM supporta la classificazione discriminante. divide le classi tra loro trovando semplicemente una linea nel caso di due dimensioni o collettore nel caso di più dimensioni. È implementato sul set di dati sopra come segue:
xfit = np.linspace(-1, 3.5)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer')
plt.plot([0.6], [2.1], 'x', color='black', markeredgewidth=4, markersize=12)
for m, b in [(1, 0.65), (0.5, 1.6), (-0.2, 2.9)]:
plt.plot(xfit, m * xfit + b, '-k')
plt.xlim(-1, 3.5);
L'output è il seguente:
Possiamo vedere dall'output di cui sopra che ci sono tre diversi separatori che discriminano perfettamente i campioni sopra.
Come discusso, l'obiettivo principale di SVM è dividere i set di dati in classi per trovare un iperpiano marginale massimo (MMH), quindi invece di tracciare una linea zero tra le classi possiamo disegnare attorno a ciascuna linea un margine di una certa larghezza fino al punto più vicino. Può essere fatto come segue:
xfit = np.linspace(-1, 3.5)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer')
for m, b, d in [(1, 0.65, 0.33), (0.5, 1.6, 0.55), (-0.2, 2.9, 0.2)]:
yfit = m * xfit + b
plt.plot(xfit, yfit, '-k')
plt.fill_between(xfit, yfit - d, yfit + d, edgecolor='none',
color='#AAAAAA', alpha=0.4)
plt.xlim(-1, 3.5);
Dall'immagine sopra in output, possiamo facilmente osservare i “margini” all'interno dei classificatori discriminanti. SVM sceglierà la linea che massimizza il margine.
Successivamente, utilizzeremo il classificatore di vettori di supporto di Scikit-Learn per addestrare un modello SVM su questi dati. Qui, stiamo usando il kernel lineare per adattare SVM come segue:
from sklearn.svm import SVC # "Support vector classifier"
model = SVC(kernel='linear', C=1E10)
model.fit(X, y)
L'output è il seguente:
SVC(C=10000000000.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma='auto_deprecated',
kernel='linear', max_iter=-1, probability=False, random_state=None,
shrinking=True, tol=0.001, verbose=False)
Ora, per una migliore comprensione, quanto segue traccerà le funzioni decisionali per SVC 2D:
def decision_function(model, ax=None, plot_support=True):
if ax is None:
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
Per valutare il modello, dobbiamo creare la griglia come segue:
x = np.linspace(xlim[0], xlim[1], 30)
y = np.linspace(ylim[0], ylim[1], 30)
Y, X = np.meshgrid(y, x)
xy = np.vstack([X.ravel(), Y.ravel()]).T
P = model.decision_function(xy).reshape(X.shape)
Successivamente, dobbiamo tracciare i confini e i margini decisionali come segue:
ax.contour(X, Y, P, colors='k',
levels=[-1, 0, 1], alpha=0.5,
linestyles=['--', '-', '--'])
Ora traccia in modo simile i vettori di supporto come segue:
if plot_support:
ax.scatter(model.support_vectors_[:, 0],
model.support_vectors_[:, 1],
s=300, linewidth=1, facecolors='none');
ax.set_xlim(xlim)
ax.set_ylim(ylim)
Ora, usa questa funzione per adattare i nostri modelli come segue:
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer')
decision_function(model);
Possiamo osservare dall'output di cui sopra che un classificatore SVM si adatta ai dati con margini, cioè linee tratteggiate e vettori di supporto, gli elementi cardine di questo adattamento, che toccano la linea tratteggiata. Questi punti del vettore di supporto sono memorizzati nell'attributo support_vectors_ del classificatore come segue:
model.support_vectors_
L'output è il seguente:
array([[0.5323772 , 3.31338909],
[2.11114739, 3.57660449],
[1.46870582, 1.86947425]])
Kernels SVM
In pratica, l'algoritmo SVM è implementato con il kernel che trasforma uno spazio dati di input nella forma richiesta. SVM utilizza una tecnica chiamata trucco del kernel in cui il kernel prende uno spazio di input di dimensioni ridotte e lo trasforma in uno spazio dimensionale superiore. In parole semplici, il kernel converte problemi non separabili in problemi separabili aggiungendovi più dimensioni. Rende SVM più potente, flessibile e preciso. I seguenti sono alcuni dei tipi di kernel usati da SVM:
Kernel lineare
Può essere utilizzato come prodotto scalare tra due osservazioni qualsiasi. La formula del kernel lineare è la seguente:
k (x, x i ) = somma (x * x i )
Dalla formula sopra, possiamo vedere che il prodotto tra due vettori dice & è la somma della moltiplicazione di ciascuna coppia di valori di input.
Kernel polinomiale
È una forma più generalizzata di kernel lineare e distingue lo spazio di input curvo o non lineare. Di seguito è riportata la formula per il kernel polinomiale:
K (x, xi) = 1 + somma (x * xi) ^ d
Qui d è il grado di polinomio, che dobbiamo specificare manualmente nell'algoritmo di apprendimento.
Kernel della funzione a base radiale (RBF)
Il kernel RBF, utilizzato principalmente nella classificazione SVM, mappa lo spazio di input in uno spazio dimensionale indefinito. La seguente formula lo spiega matematicamente:
K (x, xi) = exp (-gamma * sum ((x - xi ^ 2))
Qui, gamma varia da 0 a 1. Dobbiamo specificarlo manualmente nell'algoritmo di apprendimento. Un buon valore predefinito di gamma è 0,1.
Poiché abbiamo implementato SVM per dati separabili linearmente, possiamo implementarlo in Python per i dati che non sono separabili linearmente. Può essere fatto usando i kernel.
Esempio
Quello che segue è un esempio per la creazione di un classificatore SVM utilizzando i kernel. Useremo il set di dati iris di scikit-learn -
Inizieremo importando i seguenti pacchetti:
import pandas as pd
import numpy as np
from sklearn import svm, datasets
import matplotlib.pyplot as plt
Ora, dobbiamo caricare i dati di input -
iris = datasets.load_iris()
Da questo set di dati, prendiamo le prime due funzionalità come segue:
X = iris.data[:, :2]
y = iris.target
Successivamente, tracceremo i confini SVM con i dati originali come segue:
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
h = (x_max / x_min)/100
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
np.arange(y_min, y_max, h))
X_plot = np.c_[xx.ravel(), yy.ravel()]
Ora, dobbiamo fornire il valore del parametro di regolarizzazione come segue:
C = 1.0
Successivamente, l'oggetto classificatore SVM può essere creato come segue:
Svc_classifier = svm.SVC (kernel = 'lineare', C = C) .fit (X, y)
Z = svc_classifier.predict(X_plot)
Z = Z.reshape(xx.shape)
plt.figure(figsize=(15, 5))
plt.subplot(121)
plt.contourf(xx, yy, Z, cmap=plt.cm.tab10, alpha=0.3)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Set1)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('Support Vector Classifier with linear kernel')
Produzione
Text(0.5, 1.0, 'Support Vector Classifier with linear kernel')
Per creare un classificatore SVM con rbf kernel, possiamo cambiare il kernel in rbf come segue -
Svc_classifier = svm.SVC(kernel='rbf', gamma =‘auto’,C=C).fit(X, y)
Z = svc_classifier.predict(X_plot)
Z = Z.reshape(xx.shape)
plt.figure(figsize=(15, 5))
plt.subplot(121)
plt.contourf(xx, yy, Z, cmap=plt.cm.tab10, alpha=0.3)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Set1)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('Support Vector Classifier with rbf kernel')
Produzione
Text(0.5, 1.0, 'Support Vector Classifier with rbf kernel')
Mettiamo il valore di gamma su "auto" ma puoi anche fornire il suo valore tra 0 e 1.
Pro e contro dei classificatori SVM
Pro dei classificatori SVM
I classificatori SVM offrono una grande precisione e funzionano bene con spazi ad alta dimensione. I classificatori SVM utilizzano fondamentalmente un sottoinsieme di punti di allenamento, quindi di conseguenza utilizza molto meno memoria.
Contro dei classificatori SVM
Hanno un tempo di formazione elevato, quindi in pratica non sono adatti per set di dati di grandi dimensioni. Un altro svantaggio è che i classificatori SVM non funzionano bene con classi sovrapposte.