Schritt für Schritt zur Theorie, Implementierung in Python und Analyse mit scikit-learn über den Algorithmus, der zuvor in "Klassifikation des maschinellen Lernens" verwendet wurde. Ich werde mit lernen. Ich schreibe es zum persönlichen Lernen, daher möchte ich, dass Sie alle Fehler übersehen.
Ab diesem Zeitpunkt werde ich mit dem Klassifizierungsproblem beginnen. Zunächst aus dem grundlegenden Perceptron.
Die folgenden Seiten wurden auf diese Zeit verwiesen. Vielen Dank.
Die Klassifizierung in zwei Klassen bezieht sich auf die Ausgabe von "1" oder "0" (oder "1" oder "-1") für eine Eingabe. Anstatt "mit einer Wahrscheinlichkeit von 60% zusammenbrechen", setzen Sie Schwarzweiß ein, um zu sehen, ob es zusammenbricht. Es gibt verschiedene Arten der Zwei-Klassen-Klassifizierung, und ** Perceptron ** ist die grundlegendste Klassifizierungsmaschine.
Perceptron ist ein von Nervenzellen inspiriertes Modell, das einer großen Anzahl von Ein- und Ausgängen 1 Gewichte hinzufügt, wenn ein bestimmter Schwellenwert überschritten wird. Es ist dieses Bild, das Sie oft sehen, wenn es illustriert wird.
n gibt $ \ boldsymbol {x} = (x_0, x_1, \ cdots, x_ {n}) $ ein, gewichtet $ \ boldsymbol {w} = (w_0, w_1, \ cdots, w_ {n}) $ Und alles zusammen addieren,
w_0x_0+w_1x_1+\cdots+w_{n}x_{n} \\\
=\sum_{i=0}^{n}w_ix_i \\\
= \boldsymbol{w}^T\boldsymbol{x}
Es wird ausgedrückt als. T ist die Translokationsmatrix. Wenn dieser Wert positiv ist, wird 1 ausgegeben, und wenn er negativ ist, wird -1 ausgegeben. Eine Funktion, die einen solchen Wert von -1 oder 1 anzeigt, wird als Sprungfunktion bezeichnet.
Der für die Eingabe irrelevante Anfangswert wird als ** Bias-Term ** bezeichnet. Wenn der Bias-Term jedoch $ w_0 $ und $ x_0 = 1 $ ist, kann die obige Formel unverändert verwendet werden.
Da Python das Produkt von Matrizen mit "@" berechnen kann, wird die Eingabe in Perceptron eingegeben und die Ausgabe ausgegeben
import numpy as np
w = np.array([1.,-2.,3.,-4.])
x = np.array([1.,2.,3.,4.])
input = w.T @ x
output = 1 if input>=0 else -1
Es ist einfach.
Perceptron ist sogenanntes "überwachtes Lernen". Wenn für das angegebene $ \ boldsymbol {x} $ eine korrekte Bezeichnung $ \ boldsymbol {t} = (t_0, t_1, \ cdots, t_n) $ vorhanden ist, dann $ \ boldsymbol {w} ^ T \ boldsymbol {x Sie müssen $ \ boldsymbol {w} $ finden, damit} $ die richtige Bezeichnung korrekt zurückgibt.
Dies muss anhand der Lehrerdaten wie im Fall der Regression gelernt werden. Für Perceptron ist der gleiche Ansatz zum Bestimmen der Verlustfunktion und Aktualisieren des Parameters $ \ boldsymbol {w} $ zur Minimierung des Verlusts wirksam.
Welche Art von Verlustfunktion sollten wir also einstellen? Die Idee ist, dass wenn die Antwort richtig ist, es keinen Verlust gibt, und wenn die Antwort falsch ist, wird der Verlust entsprechend dem Abstand von der Grenze basierend auf der Grenze angegeben, die die zwei Klassen klassifiziert.
Die Scharnierfunktion wird häufig verwendet, um solche Anforderungen zu erfüllen. Es scheint, dass das Perzeptron des Scikit-Lernens auch die Scharnierfunktion verwendet. Für Scharnierfunktionen
Wie Sie hier sehen können, handelt es sich um eine Funktion, die ab einem bestimmten Wert erhöht wird. Wenn es sich um $$ h (x) $ handelt, kann sie als
Wenn für die Verlustfunktion die korrekte Bezeichnung $ t_n $ für jedes Element und der vorhergesagte Wert $ step (w_nx_n) $ gleich sind, gibt $ t_nw_nx_n $ einen positiven Wert an, andernfalls ist es ein negativer Wert. Je kleiner die Verlustfunktion ist, desto besser. Wenn die Verlustfunktion also $ L $ ist, ist
Teilweise Differenzierung von $ L $ in Bezug auf $ w_n $
\frac{\partial L}{\partial w_n}=-t_nx_n
Der schrittweise Ausdruck, der $ w_n $ aktualisiert, lautet also
w_{i+1}=w_{i}+\eta t_nx_n
Kann geschrieben werden. Außerdem ist $ \ eta $ die Lernrate.
Ich werde es tatsächlich mit Python implementieren. Die verwendeten Daten sind die bekannten Scikit-Learn-to-Iris-Klassifikationen. Unten finden Sie eine detaillierte Beschreibung des Datensatzes.
Da es sich um eine Zwei-Klassen-Klassifikation handelt, werden wir uns zunächst darauf spezialisieren. Es spielt keine Rolle, welche Daten Sie verwenden, aber sie sind willkürlich und voreingenommen, und die Bezeichnungen lauten "versicolor" und "virginica". Für die Merkmalsmenge wurden "Sepallänge (cm)" und "Blütenblattbreite (cm)" ausgewählt.
Visualisieren Sie zunächst die Daten.
mport numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.datasets import load_iris
iris = load_iris()
df_iris = pd.DataFrame(iris.data, columns=iris.feature_names)
df_iris['target'] = iris.target_names[iris.target]
fig, ax = plt.subplots()
x1 = df_iris[df_iris['target']=='versicolor'].iloc[:,3].values
y1 = df_iris[df_iris['target']=='versicolor'].iloc[:,0].values
x2 = df_iris[df_iris['target']=='virginica'].iloc[:,3].values
y2 = df_iris[df_iris['target']=='virginica'].iloc[:,0].values
ax.scatter(x1, y1, color='red', marker='o', label='versicolor')
ax.scatter(x2, y2, color='blue', marker='s', label='virginica')
ax.set_xlabel("petal width (cm)")
ax.set_ylabel("sepal length (cm)")
ax.legend()
plt.plot()
Es scheint, dass es irgendwie klassifiziert werden kann (es wird auch gesagt, dass solche Daten ausgewählt wurden).
Implementieren Sie die Perceptron-Klasse. Ein Bias-Term wird absichtlich hinzugefügt.
class Perceptron:
def __init__(self, eta=0.1, n_iter=1000):
self.eta=eta
self.n_iter=n_iter
self.w = np.array([])
def fit(self, x, y):
self.w = np.ones(len(x[0])+1)
x = np.hstack([np.ones((len(x),1)), x])
for _ in range(self.n_iter):
for i in range(len(x)):
loss = np.max([0, -y[i] * self.w.T @ x[i]])
if (loss!=0):
self.w += self.eta * y[i] * x[i]
def predict(self, x):
x = np.hstack([1., x])
return 1 if self.w.T @ x>=0 else -1
@property
def w_(self):
return self.w
Die Scharnierverlustfunktion wird für jede Daten berechnet, und wenn die Antwort falsch ist, wird das Gewicht durch die Methode mit dem steilsten Gradienten aktualisiert. Die Berechnung wird gestoppt, wenn die Anzahl der Aktualisierungen die angegebene Anzahl erreicht. Dies kann jedoch gestoppt werden, wenn der Fehler einen bestimmten Wert unterschreitet.
Nachdem Sie die Daten in die vorherige Klasse eingefügt und trainiert haben, ziehen wir eine Grenze.
df = df_iris[df_iris['target']!='setosa']
df = df.drop(df.columns[[1,2]], axis=1)
df['target'] = df['target'].map({'versicolor':1, 'virginica':-1})
x = df.iloc[:,0:2].values
y = df['target'].values
model = Perceptron()
model.fit(x, y)
#Zeichnen eines Diagramms
fig, ax = plt.subplots()
x1 = df_iris[df_iris['target']=='versicolor'].iloc[:,3].values
y1 = df_iris[df_iris['target']=='versicolor'].iloc[:,0].values
x2 = df_iris[df_iris['target']=='virginica'].iloc[:,3].values
y2 = df_iris[df_iris['target']=='virginica'].iloc[:,0].values
ax.scatter(x1, y1, color='red', marker='o', label='versicolor')
ax.scatter(x2, y2, color='blue', marker='s', label='virginica')
ax.set_xlabel("petal width (cm)")
ax.set_ylabel("sepal length (cm)")
#Klassifizierungsgrenzen zeichnen
w = model.w_
x_fig = np.linspace(1.,2.5,100)
y_fig = [-w[2]/w[1]*xi-w[0]/w[1] for xi in x_fig]
ax.plot(x_fig, y_fig)
ax.set_ylim(4.8,8.2)
ax.legend()
plt.show()
Es scheint, dass Virginica korrekt klassifiziert werden kann, Visicolor jedoch nicht. Ist es so etwas?
df = df_iris[df_iris['target']!='setosa']
df = df.drop(df.columns[[1,2]], axis=1)
df['target'] = df['target'].map({'versicolor':1, 'virginica':-1})
x = df.iloc[:,0:2].values
y = df['target'].values
from sklearn.linear_model import Perceptron
model = Perceptron(max_iter=40, eta0=0.1)
model.fit(x,y)
#Der Graphenteil wird weggelassen
Nun, die Versicolor kann in umgekehrter Weise klassifiziert werden. Die Verlustfunktion mag etwas anders sein, aber ich habe sie nicht überprüft.
Ich dachte an Perceptron, das die Basis des Klassifikators ist. Da Deep Learning ein Modell ist, das eine große Anzahl von Perceptrons kombiniert, wird das Verständnis von Perceptrons wichtiger.
Recommended Posts