Eine lineare SVM (Support Vector Machine) ist ein Modell für maschinelles Lernen, das Merkmalsräume linear trennt und klassifiziert. Wenn es nicht linear getrennt werden kann, kann es durch SVN unter Verwendung der Kernel-Methode nicht linear getrennt werden.
Bis jetzt habe ich die Kernel-Methode nicht wirklich verstanden, aber der folgende Artikel war sehr einfach zu verstehen.
Über die Kernel-Methode in Machine Learning-Memomemo
Von nun an versuche ich es in der Jupyter Notebook-Umgebung, die gemäß dem folgenden Artikel vorbereitet wurde. Einfache Installation und Inbetriebnahme von Jupyter Notebook mit Docker (unterstützt auch nbextensions und Scala) --Qiita
In dieser Umgebung können Sie mit einem Browser auf Port 8888 zugreifen und Jupyter Notebook verwenden. Sie können eine neue Notiz öffnen, indem Sie oben rechts auf Neu> Python 3 klicken.
Auch eine zufällig erstellte CSV-Datei https://github.com/suzuki-navi/sample-data/blob/master/sample-data-1.csv Ich benutze.
Liest Daten aus einer CSV-Datei und wandelt sie in ein DataFrame-Objekt um.
import pandas as pd
from sklearn import model_selection
df = pd.read_csv("sample-data-1.csv", names=["id", "target", "data1", "data2", "data3"])
df
ist ein Pandas DataFrame-Objekt.
Referenz Probieren Sie grundlegende Operationen für Pandas DataFrame auf Jupyter Notebook --Qiita aus
Die charakteristischen Variablen dieser CSV-Daten sind "data1", "data2" und "data3", aber lassen Sie uns den Zustand der Daten mit einem Streudiagramm überprüfen.
%matplotlib inline
import matplotlib.pyplot as plt
plt.scatter(df["data1"], df["data2"], c = df["target"])
plt.scatter(df["data1"], df["data3"], c = df["target"])
plt.scatter(df["data2"], df["data3"], c = df["target"])
Referenz Histogramm / Streudiagramm auf Jupyter Notebook - Qiita anzeigen
Wenn ich mir das Streudiagramm anschaue, scheint es, dass es in zwei Kategorien unterteilt werden kann: "data2" und "data3", also werde ich es versuchen.
feature = df[["data2", "data3"]]
target = df["target"]
feature
ist ein Pandas DataFrame-Objekt und target
ist ein Objekt der Pandas-Serie.
Es gibt 300 Datensätze, die in Trainingsdaten bzw. Validierungsdaten für Merkmalsvariablen und Zielvariablen unterteilt sind. Es teilt den Datensatz nur in zwei Teile, aber Sie können ihn einfach mit model_selection.train_test_split
teilen. Dies wird es zufällig teilen.
feature_train, feature_test, target_train, target_test = model_selection.train_test_split(feature, target, test_size=0.2)
test_size = 0.2
ist eine Angabe, dass 20% aller Daten als Verifizierungsdaten verwendet werden.
Feature-Variablen (df [[" data2 "," data3 "]]
, feature_train
, feature_test
) sind Pandas DataFrame-Objekte, Zielvariablen (df [" target "]
, target_train
,target_test
) Ist ein Serienobjekt.
Lernen Sie anhand der erstellten Trainingsdaten (feature_train
, target_train
).
from sklearn import svm
model = svm.SVC(kernel="linear")
model.fit(feature_train, target_train)
"SVC (kernel =" linear ")" ist ein Modell des SVM-Klassifikators, das sich linear trennt. Lass uns mit fit
lernen.
Referenz sklearn.svm.SVC — scikit-learn 0.21.3 documentation
Erstellen Sie ein Inferenzergebnis (pred_train
) aus der Merkmalsvariablen ( feature_train
) der Trainingsdaten mit dem trainierten Modell, vergleichen Sie es mit der Zielvariablen (target_train
) und bewerten Sie die Genauigkeitsrate. Sie können es einfach mit der Funktion "metrics.accuracy_score "auswerten.
from sklearn import metrics
pred_train = model.predict(feature_train)
metrics.accuracy_score(target_train, pred_train)
Aufgrund der Zufälligkeit der Logik kann das Ergebnis jedes Mal anders sein, es steht jedoch "0,95".
Bewerten Sie anhand von Trainingsdaten, ob diese übertrainiert oder verallgemeinert sind.
pred_test = model.predict(feature_test)
metrics.accuracy_score(target_test, pred_test)
Es wurde als "0.93333333333333333" angezeigt. Ich bin mir nicht sicher, ob es in Ordnung ist.
Wenn Sie "plotting.plot_decision_regions" verwenden, das im Paket "mlxtend" getrennt von scikit-learn enthalten ist, können Sie visualisieren, wie es in einem Streudiagramm klassifiziert ist. Sie müssen ein Array von NumPy anstelle eines Pandas-Objekts an "plot_decision_regions" übergeben. Konvertieren Sie es also mit der Methode "to_numpy ()".
from mlxtend import plotting
plotting.plot_decision_regions(feature.to_numpy(), target.to_numpy(), clf=model)
Gute Stimmung.
Referenz plot_decision_regions - Mlxtend.plotting - mlxtend pandas.DataFrame.to_numpy — pandas 0.25.3 documentation
Ich möchte eine nichtlineare Trennung versuchen. Verwenden wir den RBF-Kernel.
Alles was Sie tun müssen, ist "svm.SVC (kernel =" linear ")" in "svm.SVC (kernel =" rbf ", gamma =" scale ")" zu ändern. "gamma =" scale "" ist ein Hyperparameter für den RBF-Kernel. Wenn Sie "scale" angeben, wird dieser automatisch aus der Anzahl der Trainingsdaten und der Verteilung der Merkmalsvariablen berechnet.
Mit dem folgenden Code wird das Modell erstellt, trainiert, abgeleitet und sogar bewertet.
model = svm.SVC(kernel="rbf", gamma="scale")
model.fit(feature_train, target_train)
pred_train = model.predict(feature_train)
metrics.accuracy_score(target_train, pred_train)
Es wurde als "0,95" angezeigt.
Mit Trainingsdaten auswerten, um die Generalisierungsleistung zu sehen.
pred_test = model.predict(feature_test)
metrics.accuracy_score(target_test, pred_test)
Es wurde als "0,95" angezeigt. Es ist etwas besser als die lineare Trennung, die ich zuvor erwähnt habe.
plotting.plot_decision_regions(feature.to_numpy(), target.to_numpy(), clf=model)
Da es nicht linear ist, ist es sicherlich durch eine Kurve getrennt.
Diese Probe war leicht linear zu trennen, daher war es möglicherweise nicht ausreichend, sie nichtlinear zu machen.
Da data2
und data3
linear getrennt werden können, versuchen Sie den RBF-Kernel mit anderen Datenkombinationen.
Zunächst "data1" und "data2". Machen Sie nur die Figur, die aussieht, als wären sie durch den folgenden Code getrennt.
feature = df[["data1", "data2"]]
target = df["target"]
feature_train, feature_test, target_train, target_test = model_selection.train_test_split(feature, target, test_size=0.2)
model = svm.SVC(kernel="rbf", gamma="scale")
model.fit(feature_train, target_train)
plotting.plot_decision_regions(feature.to_numpy(), target.to_numpy(), clf=model)
Mal sehen, die richtige Antwortrate.
pred_train = model.predict(feature_train)
metrics.accuracy_score(target_train, pred_train)
Es war "0,75833333333333333".
pred_test = model.predict(feature_test)
metrics.accuracy_score(target_test, pred_test)
Es war "0,7833333333333333".
Übrigens, selbst wenn ich es linear (kernel =" linear "
) mit denselben Daten versuchte, waren es 0,71 bis 0,74. Wenn man sich die Abbildung ansieht, scheint die Kernel-Methode hart zu arbeiten, aber gibt es keinen großen Unterschied bei den numerischen Werten? Sollten wir nicht zu viel erwarten, nur weil wir Nichtlinearität herstellen können?
Ich habe es mit data1
und data3
versucht, aber es war ähnlich, also habe ich es weggelassen ...
das ist alles.
Folge Versuchen Sie, mit einem gemischten Gaußschen Modell auf Jupyter Notebook-Qiita zu clustern
Recommended Posts