Das Buch, das ich gelesen habe
"[2. Auflage] Python Machine Learning Programming Experte Datenwissenschaftler Theorie und Praxis (beeindrucken Sie Top Gear)"
↑ Ich spiele mit verschiedenen Daten herum, aber im Grunde habe ich gerade Kapitel 2 dieses Buches gemacht.
Perceptrons Regeln für frühes Lernen
Initialisieren Sie das Gewicht $ \ mathbf {w} $ mit 0 oder einer kleinen Zufallszahl
Gehen Sie für jedes Trainingsbeispiel $ \ mathbf {x} ^ {(i)} $ wie folgt vor:
Berechnen Sie den Ausgabewert $ \ hat {y} $
Aktualisieren Sie das Gewicht
$ \ eta $ ist die Lernrate (normalerweise größer als 0,0 und kleiner oder gleich 1,0). $ y ^ {(i)} $ ist die wahre Klassenbezeichnung der i-ten Trainingsstichprobe. $ \ hat {y} ^ {(i)} $ ist die vorhergesagte Klassenbezeichnung.
Der vorhergesagte Wert $ \ hat {y} ^ {(i)} $ ist
und
Wird bestimmt durch.
Perceptron ist linear trennbar und Konvergenz ist nur dann garantiert, wenn die Lernrate klein genug ist.
import numpy as np
class Perceptron(object):
"""Perceptron-Klassifikator
Parameter
-----------
eta : float
Lernrate(0.Größer als 0 1.Wert kleiner oder gleich 0)
n_iter : int
Anzahl der Trainings in Trainingsdaten
random_state : int
Zufälliger Startwert für die Gewichtsinitialisierung
Attribut
-----------
w_ :1-dimensionales Array
Gewicht nach Anpassung
errors_ :aufführen
Anzahl der Fehlklassifizierungen (Aktualisierungen) in jeder Epoche
"""
def __init__(self, eta=0.01, n_iter=50, random_state=1):
self.eta = eta
self.n_iter = n_iter
self.random_state = random_state
def fit(self, X, y):
"""Passt zu Trainingsdaten
Parameter
------------
X : {Array-ähnliche Datenstruktur}, shape = [n_samples, n_features]
Trainingsdaten
n_Proben ist die Anzahl der Proben, n_Features ist die Anzahl der Features
y :Array-ähnliche Datenstruktur, shape = [n_samples]
Objektive Variable
Rückgabewert
------------
self : object
"""
rgen = np.random.RandomState(self.random_state)
self.w_ = rgen.normal(loc=0.0, scale=0.01, size=1 + X.shape[1])
self.errors_ = []
for _ in range(self.n_iter): #Wiederholen Sie die Trainingsdaten für die Anzahl der Trainings
errors = 0
for xi, target in zip(X, y): #Aktualisieren Sie die Gewichte in jeder Probe
#Gewicht w_1, ..., w_m Update
# Δw_j = η (y^(i)wahrer Wert- y^(i)Prognose) x_j (j = 1, ..., m)
update = self.eta * (target - self.predict(xi))
self.w_[1:] += update * xi
#Gewicht w_Update 0 Δw_0 = η (y^(i)wahrer Wert- y^(i)Prognose)
self.w_[0] += update
#Wenn die Gewichtsaktualisierung nicht 0 ist, wird sie als Fehlklassifizierung gezählt.
errors += int(update != 0.0)
#Speicherfehler für jede Iteration
self.errors_.append(errors)
return self
def net_input(self, X):
"""Berechnen Sie die Gesamteingabe"""
return np.dot(X, self.w_[1:]) + self.w_[0]
def predict(self, X):
"""Gibt die Klassenbezeichnung nach einem Schritt zurück"""
return np.where(self.net_input(X) >= 0.0, 1, -1)
from sklearn.datasets import load_iris
import pandas as pd
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['target'] = iris.target
# df.loc[df['target'] == 0, 'target'] = "setosa"
# df.loc[df['target'] == 1, 'target'] = "versicolor"
# df.loc[df['target'] == 2, 'target'] = "virginica"
df.head()
sepal length (cm) | sepal width (cm) | petal length (cm) | petal width (cm) | target | |
---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | 0 |
1 | 4.9 | 3.0 | 1.4 | 0.2 | 0 |
2 | 4.7 | 3.2 | 1.3 | 0.2 | 0 |
3 | 4.6 | 3.1 | 1.5 | 0.2 | 0 |
4 | 5.0 | 3.6 | 1.4 | 0.2 | 0 |
import seaborn as sns
sns.pairplot(df, hue='target')
Da es sich um eine binäre Klassifikation handelt, werden wir auf zwei Typen eingrenzen, die linear getrennt werden können.
Darüber hinaus ist die Merkmalsmenge zweidimensional, so dass sie visuell leicht erkennbar ist.
Die Bezeichnungen 0 und 2 sollten angemessen sein und können grob getrennt werden. (Ich möchte etwas anderes als das Buch verwenden)
import numpy as np
import matplotlib.pyplot as plt
df2 = df.query("target != 1").copy() #Etikett 1 ausschließen
df2["target"] -= 1 #Etikett 1-Auf 1 ausrichten
plt.scatter(df2.iloc[:50, 3], df2.iloc[:50, 1], color='blue', marker='o', label='setosa')
plt.scatter(df2.iloc[50:, 3], df2.iloc[50:, 1], color='green', marker='o', label='virginica')
plt.xlabel('petal width [cm]')
plt.ylabel('sepal width [cm]')
plt.legend(loc='upper left')
plt.show()
Das obige Paardiagramm wurde auf die gleiche Weise wie das erste von rechts und das zweite von oben extrahiert und aufgezeichnet.
Diese Daten werden verwendet, um den Perceptron-Algorithmus zu trainieren.
X = df2[['petal width (cm)', 'sepal width (cm)']].values
Y = df2['target'].values
ppn = Perceptron(eta=0.1, n_iter=10)
ppn.fit(X, Y)
plt.plot(range(1, len(ppn.errors_) + 1), ppn.errors_, marker='o')
plt.xlabel('Epochs')
plt.ylabel('Number of update')
plt.show()
Es ist zu sehen, dass das Perceptron in der 6. Epoche konvergierte.
Implementieren Sie eine einfache und bequeme Funktion zur Visualisierung der Entscheidungsgrenzen.
from matplotlib.colors import ListedColormap
def plot_decision_regions(X, y, classifier, resolution=0.02):
#Vorbereitung von Markern und Farbkarten
markers = ('s', 'x', 'o', '^', 'v')
colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
cmap = ListedColormap(colors[:len(np.unique(y))])
#Entscheidungsbereichsdiagramm
x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
#Generieren Sie Rasterpunkte
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
np.arange(x2_min, x2_max, resolution))
#Vorhersage durch Konvertieren jedes Features in ein eindimensionales Array
Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
#Konvertieren Sie Vorhersageergebnisse in die ursprüngliche Größe der Rasterpunktdaten
Z = Z.reshape(xx1.shape)
#Rasterpunktkonturdiagramm
plt.contourf(xx1, xx2, Z, alpha=0.3, cmap=cmap)
#Einstellung des Achsenbereichs
plt.xlim(xx1.min(), xx1.max())
plt.ylim(xx2.min(), xx2.max())
#Zeichnen Sie die Proben nach Klassen
for idx, cl in enumerate(np.unique(y)):
plt.scatter(x=X[y == cl, 0],
y=X[y == cl, 1],
alpha=0.8,
c=colors[idx],
marker=markers[idx],
label=cl,
edgecolor='black')
#Entscheidungsbereichsdiagramm
plot_decision_regions(X, Y, classifier=ppn)
plt.xlabel('petal width [cm]')
plt.ylabel('sepal width [cm]')
plt.legend(loc='upper left')
plt.show()
Wenn Sie es nicht teilen können, versuchen Sie es.
Vorhersage: Es konvergiert nicht und stoppt an der Grenze der Anzahl der Epochen. Fehler ist wahrscheinlich besser.
import numpy as np
import matplotlib.pyplot as plt
df3 = df.query("target != 0").copy() #Label 0 ausschließen
y = df3.iloc[:, 4].values
y = np.where(y == 1, -1, 1) #Etikett 1-Stellen Sie 1 auf 1 und andere (Etikett 2) auf 1.
plt.scatter(df3.iloc[:50, 1], df3.iloc[:50, 0], color='orange', marker='o', label='versicolor')
plt.scatter(df3.iloc[50:, 1], df3.iloc[50:, 0], color='green', marker='o', label='virginica')
plt.xlabel('sepal width [cm]')
plt.ylabel('sepal length [cm]')
plt.legend(loc='upper left')
plt.show()
Es wurde auf die gleiche Weise extrahiert und geplottet wie das dritte von rechts und das erste von oben im Paardiagramm oben.
X2 = df3[['sepal width (cm)', 'sepal length (cm)']].values
ppn = Perceptron(eta=0.1, n_iter=100)
ppn.fit(X2, y)
plt.plot(range(1, len(ppn.errors_) + 1), ppn.errors_, marker='o')
plt.xlabel('Epochs')
plt.ylabel('Number of update')
plt.show()
#Entscheidungsbereichsdiagramm
plot_decision_regions(X2, y, classifier=ppn)
plt.xlabel('sepal width [cm]')
plt.ylabel('sepal length [cm]')
plt.legend(loc='upper left')
plt.show()
Überhaupt nicht klassifiziert. Visuell ist das Label 1 umso größer, je größer y ist. Daher dachte ich, dass es bei y = 6 richtig getrennt werden würde, aber es scheint, dass dies nicht der Fall ist.
Als nächstes werde ich ADALINE machen.
Recommended Posts