Support Vector Machine (SVM)

Einführung in SVM

Support Vector Machines (SVMs) sind leistungsstarke und dennoch flexible überwachte Algorithmen für maschinelles Lernen, die sowohl zur Klassifizierung als auch zur Regression verwendet werden. Im Allgemeinen werden sie jedoch bei Klassifizierungsproblemen verwendet. In den 1960er Jahren wurden SVMs erstmals eingeführt, später jedoch 1990 weiterentwickelt. SVMs haben im Vergleich zu anderen Algorithmen für maschinelles Lernen eine einzigartige Art der Implementierung. In letzter Zeit sind sie äußerst beliebt, da sie mehrere kontinuierliche und kategoriale Variablen verarbeiten können.

Arbeiten von SVM

Ein SVM-Modell ist im Grunde eine Darstellung verschiedener Klassen in einer Hyperebene im mehrdimensionalen Raum. Die Hyperebene wird von SVM iterativ generiert, damit der Fehler minimiert werden kann. Das Ziel von SVM ist es, die Datensätze in Klassen zu unterteilen, um eine maximale marginale Hyperebene (MMH) zu finden.

Das Folgende sind wichtige Konzepte in SVM -

  • Support Vectors- Datenpunkte, die der Hyperebene am nächsten liegen, werden als Unterstützungsvektoren bezeichnet. Mit Hilfe dieser Datenpunkte wird eine Trennlinie definiert.

  • Hyperplane - Wie wir im obigen Diagramm sehen können, handelt es sich um eine Entscheidungsebene oder einen Raum, der auf eine Reihe von Objekten mit unterschiedlichen Klassen aufgeteilt ist.

  • Margin- Es kann als die Lücke zwischen zwei Linien auf den Schrankdatenpunkten verschiedener Klassen definiert werden. Sie kann als senkrechter Abstand von der Linie zu den Stützvektoren berechnet werden. Eine große Marge wird als gute Marge und eine kleine Marge als schlechte Marge angesehen.

Das Hauptziel von SVM besteht darin, die Datensätze in Klassen zu unterteilen, um eine maximale marginale Hyperebene (MMH) zu finden. Dies kann in den folgenden zwei Schritten erfolgen:

  • Zunächst generiert SVM iterativ Hyperebenen, die die Klassen optimal trennen.

  • Anschließend wird die Hyperebene ausgewählt, die die Klassen korrekt trennt.

Implementierung von SVM in Python

Für die Implementierung von SVM in Python beginnen wir mit dem Import der Standardbibliotheken wie folgt:

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
import seaborn as sns; sns.set()

Als Nächstes erstellen wir aus sklearn.dataset.sample_generator ein Beispieldatensatz mit linear trennbaren Daten zur Klassifizierung mithilfe von 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');

Das Folgende wäre die Ausgabe nach dem Generieren eines Beispieldatensatzes mit 100 Proben und 2 Clustern -

Wir wissen, dass SVM eine diskriminierende Klassifizierung unterstützt. Es trennt die Klassen voneinander, indem es einfach eine Linie bei zwei Dimensionen oder eine Mannigfaltigkeit bei mehreren Dimensionen findet. Es wird auf dem obigen Datensatz wie folgt implementiert:

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);

Die Ausgabe ist wie folgt -

Wir können der obigen Ausgabe entnehmen, dass es drei verschiedene Separatoren gibt, die die obigen Proben perfekt unterscheiden.

Wie bereits erwähnt, besteht das Hauptziel von SVM darin, die Datensätze in Klassen zu unterteilen, um eine maximale marginale Hyperebene (MMH) zu finden. Anstatt eine Nulllinie zwischen Klassen zu zeichnen, können wir um jede Linie einen Rand mit einer gewissen Breite bis zum nächsten Punkt zeichnen. Dies kann wie folgt erfolgen:

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);

Aus dem obigen Bild in der Ausgabe können wir leicht die "Ränder" innerhalb der diskriminierenden Klassifikatoren beobachten. SVM wählt die Linie aus, die den Rand maximiert.

Als Nächstes verwenden wir den Support-Vektor-Klassifikator von Scikit-Learn, um ein SVM-Modell für diese Daten zu trainieren. Hier verwenden wir einen linearen Kernel, um SVM wie folgt anzupassen:

from sklearn.svm import SVC # "Support vector classifier"
model = SVC(kernel='linear', C=1E10)
model.fit(X, y)

Die Ausgabe ist wie folgt -

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)

Zum besseren Verständnis werden im Folgenden die Entscheidungsfunktionen für 2D-SVC dargestellt:

def decision_function(model, ax=None, plot_support=True):
   if ax is None:
      ax = plt.gca()
   xlim = ax.get_xlim()
   ylim = ax.get_ylim()

Für die Bewertung des Modells müssen wir ein Raster wie folgt erstellen:

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)

Als nächstes müssen wir Entscheidungsgrenzen und -ränder wie folgt zeichnen:

ax.contour(X, Y, P, colors='k',
   levels=[-1, 0, 1], alpha=0.5,
   linestyles=['--', '-', '--'])

Zeichnen Sie nun auf ähnliche Weise die Unterstützungsvektoren wie folgt:

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)

Verwenden Sie diese Funktion nun, um unsere Modelle wie folgt anzupassen:

plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='summer')
decision_function(model);

Aus der obigen Ausgabe können wir ersehen, dass ein SVM-Klassifikator mit Rändern, dh gestrichelten Linien und Unterstützungsvektoren, an die Daten passt, wobei die zentralen Elemente dieser Anpassung die gestrichelte Linie berühren. Diese Unterstützungsvektorpunkte werden wie folgt im Attribut support_vectors_ des Klassifizierers gespeichert:

model.support_vectors_

Die Ausgabe ist wie folgt -

array([[0.5323772 , 3.31338909],
   [2.11114739, 3.57660449],
   [1.46870582, 1.86947425]])

SVM-Kernel

In der Praxis wird der SVM-Algorithmus mit einem Kernel implementiert, der einen Eingabedatenraum in die erforderliche Form umwandelt. SVM verwendet eine Technik namens Kernel-Trick, bei der der Kernel einen niedrigdimensionalen Eingaberaum nimmt und ihn in einen höherdimensionalen Raum umwandelt. Mit einfachen Worten, der Kernel konvertiert nicht trennbare Probleme in trennbare Probleme, indem er weitere Dimensionen hinzufügt. Es macht SVM leistungsfähiger, flexibler und genauer. Im Folgenden sind einige der von SVM verwendeten Kerneltypen aufgeführt:

Linearer Kernel

Es kann als Punktprodukt zwischen zwei beliebigen Beobachtungen verwendet werden. Die Formel des linearen Kernels lautet wie folgt:

k (x, x i ) = Summe (x * x i )

Aus der obigen Formel können wir sehen, dass das Produkt zwischen zwei Vektoren & ist die Summe der Multiplikation jedes Paares von Eingabewerten.

Polynomkern

Es ist eine allgemeinere Form des linearen Kernels und unterscheidet gekrümmten oder nichtlinearen Eingaberaum. Es folgt die Formel für den Polynomkern -

K (x, xi) = 1 + Summe (x * xi) ^ d

Hier ist d der Grad des Polynoms, den wir manuell im Lernalgorithmus angeben müssen.

Kernel der Radial Basis Function (RBF)

Der RBF-Kernel, der hauptsächlich in der SVM-Klassifizierung verwendet wird, bildet den Eingaberaum in einem unbestimmten Dimensionsraum ab. Die folgende Formel erklärt es mathematisch -

K (x, xi) = exp (-gamma * sum ((x - xi ^ 2))

Hier reicht Gamma von 0 bis 1. Wir müssen es manuell im Lernalgorithmus angeben. Ein guter Standardwert für Gamma ist 0,1.

Da wir SVM für linear trennbare Daten implementiert haben, können wir es in Python für Daten implementieren, die nicht linear trennbar sind. Dies kann mithilfe von Kerneln erfolgen.

Beispiel

Das folgende Beispiel zeigt das Erstellen eines SVM-Klassifikators mithilfe von Kerneln. Wir werden den Iris-Datensatz von scikit-learn verwenden -

Wir werden zunächst folgende Pakete importieren:

import pandas as pd
import numpy as np
from sklearn import svm, datasets
import matplotlib.pyplot as plt

Jetzt müssen wir die Eingabedaten laden -

iris = datasets.load_iris()

Aus diesem Datensatz nehmen wir die ersten beiden Funktionen wie folgt:

X = iris.data[:, :2]
y = iris.target

Als nächstes zeichnen wir die SVM-Grenzen mit den Originaldaten wie folgt:

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()]

Nun müssen wir den Wert des Regularisierungsparameters wie folgt angeben:

C = 1.0

Als nächstes kann das SVM-Klassifiziererobjekt wie folgt erstellt werden:

Svc_classifier = svm.SVC (Kernel = 'linear', 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')

Ausgabe

Text(0.5, 1.0, 'Support Vector Classifier with linear kernel')

Zum Erstellen eines SVM-Klassifikators mit rbf Kernel, wir können den Kernel in ändern rbf wie folgt -

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')

Ausgabe

Text(0.5, 1.0, 'Support Vector Classifier with rbf kernel')

Wir setzen den Wert von Gamma auf 'auto', aber Sie können auch einen Wert zwischen 0 und 1 angeben.

Vor- und Nachteile von SVM-Klassifikatoren

Vorteile von SVM-Klassifikatoren

SVM-Klassifikatoren bieten eine hohe Genauigkeit und funktionieren gut mit hochdimensionalem Raum. SVM-Klassifizierer verwenden grundsätzlich eine Teilmenge von Trainingspunkten, weshalb das Ergebnis sehr wenig Speicher benötigt.

Nachteile von SVM-Klassifikatoren

Sie haben eine hohe Trainingszeit und sind daher in der Praxis nicht für große Datenmengen geeignet. Ein weiterer Nachteil ist, dass SVM-Klassifizierer mit überlappenden Klassen nicht gut funktionieren.