Einführung
In diesem Lab werden wir demonstrieren, wie man Stochastic Gradient Descent (SGD) verwendet, um die Lösung eines One-Class SVM im Fall eines RBF-Kernels zu approximieren.
Wir werden die Ergebnisse dieser Approximation mit den Ergebnissen vergleichen, die man mit einem kernelisierten Ansatz für ein One-Class SVM erhält. Der Zweck dieses Labs ist es nicht, die Vorteile der Approximation in Bezug auf die Rechenzeit zu zeigen, sondern vielmehr zu demonstrieren, dass man ähnliche Ergebnisse mit SGD auf einem Toy-Datensatz erzielen kann.
VM-Tipps
Nachdem die VM gestartet ist, klicken Sie in der oberen linken Ecke, um zur Registerkarte Notebook zu wechseln und Jupyter Notebook für die Übung zu nutzen.
Manchmal müssen Sie einige Sekunden warten, bis Jupyter Notebook vollständig geladen ist. Die Validierung von Vorgängen kann aufgrund von Einschränkungen in Jupyter Notebook nicht automatisiert werden.
Wenn Sie bei der Lernphase Probleme haben, können Sie Labby gerne fragen. Geben Sie nach der Sitzung Feedback, und wir werden das Problem für Sie prompt beheben.
Bibliotheken importieren
Wir beginnen, indem wir die für dieses Lab erforderlichen Bibliotheken importieren: NumPy, Matplotlib und scikit-learn.
import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import OneClassSVM
from sklearn.linear_model import SGDOneClassSVM
from sklearn.kernel_approximation import Nystroem
from sklearn.pipeline import make_pipeline
Daten generieren
Wir werden für dieses Lab einen Toy-Datensatz generieren. Wir werden 500 Trainingsbeispiele und 20 Testbeispiele generieren. Wir werden auch 20 abnorme Beispiele generieren.
random_state = 42
rng = np.random.RandomState(random_state)
## Generiere Trainingsdaten
X = 0.3 * rng.randn(500, 2)
X_train = np.r_[X + 2, X - 2]
## Generiere einige regelmäßige neue Beobachtungen
X = 0.3 * rng.randn(20, 2)
X_test = np.r_[X + 2, X - 2]
## Generiere einige abnorme neue Beobachtungen
X_outliers = rng.uniform(low=-4, high=4, size=(20, 2))
Ein One-Class SVM anpassen
Wir werden zunächst ein One-Class SVM mit einem RBF-Kernel an unseren Datensatz anpassen.
## OCSVM-Hyperparameter
nu = 0.05
gamma = 2.0
## Passt das One-Class SVM an
clf = OneClassSVM(gamma=gamma, kernel="rbf", nu=nu)
clf.fit(X_train)
y_pred_train = clf.predict(X_train)
y_pred_test = clf.predict(X_test)
y_pred_outliers = clf.predict(X_outliers)
n_error_train = y_pred_train[y_pred_train == -1].size
n_error_test = y_pred_test[y_pred_test == -1].size
n_error_outliers = y_pred_outliers[y_pred_outliers == 1].size
Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
Ein One-Class SVM mit SGD anpassen
Als nächstes werden wir ein One-Class SVM mit SGD anpassen. Wir werden eine Kernel-Approximation verwenden, um SGD auf unseren Datensatz anzuwenden.
## Passt das One-Class SVM mit einer Kernel-Approximation und SGD an
transform = Nystroem(gamma=gamma, random_state=random_state)
clf_sgd = SGDOneClassSVM(
nu=nu, shuffle=True, fit_intercept=True, random_state=random_state, tol=1e-4
)
pipe_sgd = make_pipeline(transform, clf_sgd)
pipe_sgd.fit(X_train)
y_pred_train_sgd = pipe_sgd.predict(X_train)
y_pred_test_sgd = pipe_sgd.predict(X_test)
y_pred_outliers_sgd = pipe_sgd.predict(X_outliers)
n_error_train_sgd = y_pred_train_sgd[y_pred_train_sgd == -1].size
n_error_test_sgd = y_pred_test_sgd[y_pred_test_sgd == -1].size
n_error_outliers_sgd = y_pred_outliers_sgd[y_pred_outliers_sgd == 1].size
Z_sgd = pipe_sgd.decision_function(np.c_[xx.ravel(), yy.ravel()])
Z_sgd = Z_sgd.reshape(xx.shape)
Ergebnisse plotten
Schließlich werden wir die Ergebnisse unseres One-Class SVM und unseres One-Class SVM mit SGD plotten.
## plot die Ebenen der Entscheidungsfunktion
plt.figure(figsize=(9, 6))
plt.title("One Class SVM")
plt.contourf(xx, yy, Z, levels=np.linspace(Z.min(), 0, 7), cmap=plt.cm.PuBu)
a = plt.contour(xx, yy, Z, levels=[0], linewidths=2, colors="darkred")
plt.contourf(xx, yy, Z, levels=[0, Z.max()], colors="palevioletred")
s = 20
b1 = plt.scatter(X_train[:, 0], X_train[:, 1], c="white", s=s, edgecolors="k")
b2 = plt.scatter(X_test[:, 0], X_test[:, 1], c="blueviolet", s=s, edgecolors="k")
c = plt.scatter(X_outliers[:, 0], X_outliers[:, 1], c="gold", s=s, edgecolors="k")
plt.axis("tight")
plt.xlim((-4.5, 4.5))
plt.ylim((-4.5, 4.5))
plt.legend(
[a.collections[0], b1, b2, c],
[
"lernte Grenze",
"Trainingsbeobachtungen",
"neue regelmäßige Beobachtungen",
"neue abnorme Beobachtungen",
],
loc="upper left",
)
plt.xlabel(
"Fehler Train: %d/%d; Fehler neue regelmäßige: %d/%d; Fehler neue abnorme: %d/%d"
% (
n_error_train,
X_train.shape[0],
n_error_test,
X_test.shape[0],
n_error_outliers,
X_outliers.shape[0],
)
)
plt.show()
plt.figure(figsize=(9, 6))
plt.title("Online One-Class SVM")
plt.contourf(xx, yy, Z_sgd, levels=np.linspace(Z_sgd.min(), 0, 7), cmap=plt.cm.PuBu)
a = plt.contour(xx, yy, Z_sgd, levels=[0], linewidths=2, colors="darkred")
plt.contourf(xx, yy, Z_sgd, levels=[0, Z_sgd.max()], colors="palevioletred")
s = 20
b1 = plt.scatter(X_train[:, 0], X_train[:, 1], c="white", s=s, edgecolors="k")
b2 = plt.scatter(X_test[:, 0], X_test[:, 1], c="blueviolet", s=s, edgecolors="k")
c = plt.scatter(X_outliers[:, 0], X_outliers[:, 1], c="gold", s=s, edgecolors="k")
plt.axis("tight")
plt.xlim((-4.5, 4.5))
plt.ylim((-4.5, 4.5))
plt.legend(
[a.collections[0], b1, b2, c],
[
"lernte Grenze",
"Trainingsbeobachtungen",
"neue regelmäßige Beobachtungen",
"neue abnorme Beobachtungen",
],
loc="upper left",
)
plt.xlabel(
"Fehler Train: %d/%d; Fehler neue regelmäßige: %d/%d; Fehler neue abnorme: %d/%d"
% (
n_error_train_sgd,
X_train.shape[0],
n_error_test_sgd,
X_test.shape[0],
n_error_outliers_sgd,
X_outliers.shape[0],
)
)
plt.show()
Zusammenfassung
In diesem Lab haben wir gezeigt, wie man Stochastic Gradient Descent (SGD) verwendet, um die Lösung eines One-Class SVM mit einem RBF-Kernel zu approximieren. Wir haben die Ergebnisse dieser Approximation mit den Ergebnissen verglichen, die man erhält, wenn man einen One-Class SVM mit einem kernelisierten Ansatz verwendet. Wir haben einen Toy-Datensatz generiert und die Ergebnisse unserer Modelle geplottet.