Schritte:
X
und eines Zielvektors y
/ einer Zielmatrix Y
KNeighborsClassifier
, MLPClassifier
, LinearRegression
, ...model.fit(X, y)
model.predict(...)
Beispiel: Klassifizierung von Iris-Pflanzen
Bekannte Daten: Maße und Klassifizierung von 150 Iris-Pflanzen (Schwertlilien)
Aufgabe: Trainieren eines Algorithmus, der anhand der Maße einer Iris-Pflanze eine Klassifizierung vornehmen kann
Beispieldaten (sepal length, sepal width, petal length, petal width, name):
[5.1, 3.5, 1.4, 0.2]
→ "Iris-setosa"
[7.0, 3.2, 4.7, 1.4]
→ "Iris-versicolor"
[6.3, 3.3, 6.0, 2.5]
→ "Iris-virginica"
in unseren Daten: setosa=0, versicolor=1, virginica=2
Vorbereiten der Daten:
from sklearn import datasets
iris = datasets.load_iris()
X = iris.data
y = iris.target
Trainieren eines Algorithmus:
from sklearn.neighbors import KNeighborsClassifier
model = KNeighborsClassifier()
model.fit(X, y)
Anwenden des Erlernten auf neue Daten:
test_data = [
[5.3, 3.4, 1.9, 0.6],
[6.0, 3.0, 4.7, 1.5],
[6.5, 3.1, 5.0, 1.7]
]
y_pred = model.predict(test_data)
# [0, 1, 1]
y_pred_proba = model.predict_proba(test_data)
# [[1. 0. 0. ]
# [0. 0.8 0.2]
# [0. 0.6 0.4]]
Aufgabe: Verwenden anderer Klassifikatoren, z.B.:
sklearn.neural_network.MLPClassifier
sklearn.svm.SVC
sklearn.tree.DecisionTreeClassifier
sklearn.naive_bayes.GaussianNB
Eingangsdaten: Graustufenbilder von 1797 handgeschriebenen Ziffern
Zieldaten: Ziffer (z.B. 0, 1, 2, 3, ...)
from sklearn import datasets
digits = datasets.load_digits()
Bilder in digits.images
Label in digits.target
Aufgabe:
Zeige manche der Bilder und ihre zugehörigen Labels mittels der Funktion imshow
von pyplot
Einfache Lösung:
plt.imshow(digits.images[3], cmap="gray")
plt.axis("off")
plt.title(digits.target[3])
Aufgabe:
"flattening" des Eingangsarray von 1797x8x8 zu 1797x64
explizite Lösung:
x = digits.images.reshape(1797, 64)
robuste Lösung:
x = digits.images.reshape(digits.images.shape[0], -1)
Aufgabe: Wähle die ersten 1500 Einträge als Trainingsdaten und trainiere das Modell
Lösung:
from sklearn.neighbors import KNeighborsClassifier
x_train = x[:1500]
y_train = y[:1500]
model = KNeighborsClassifier(1)
model.fit(x_train, y_train)
Aufgabe: Verwende die verbleibenden Einträge als Testdaten und berechte den Prozentsatz an richtigen Klassifizierungen
Lösung:
x_test = x[1500:]
y_test = y[1500:]
y_pred = model.predict(x_test)
import numpy as np
num_correct = np.sum(y_pred == y_test)
print(num_correct / y_test.size)
erwünschtes Datenformat für Machine Learning Algorithmen:
Aufgaben:
Klassen zum vorbereiten der Daten besitzen folgende Methoden:
.fit
: erlernt anhand vorgegebener Eingangsdaten (X1
) eine passende Umwandlung für das Modell.transform
: wandelt gegebene Eingangsdaten (X2
) anhand des gelernten in die neue Form um.fit_transform
: beides in einem Schritt (für die gleichen Daten).inverse_transform
: umgekehrte Transformation (nicht für alle Transformationen vorhanden)Zentrieren und Skalieren der Werte, sodass ihr Mittelwert 0 und ihre Standardabweichung 1 ist:
from sklearn import preprocessing
import numpy as np
stars = np.array([[ 7.0e7, 2.0e30, 5.8e3],
[ 6.5e7, 2.2e30, 5.2e3],
[ 7.0e9, 2.1e30, 3.1e3]])
scaler = preprocessing.StandardScaler().fit(stars)
X = scaler.transform(stars)
Skalierte Werte:
array([[-0.70634165, -1.22474487, 0.95025527],
[-0.70787163, 1.22474487, 0.43193421],
[ 1.41421329, 0. , -1.38218948]])
Interpolation:
import numpy as np
from sklearn.impute import SimpleImputer
X = np.array([[ np.nan, 0, 3 ],
[ 3, 7, 9 ],
[ 3, 5, 2 ],
[ 4, np.nan, 6 ],
[ 8, 8, 1 ]])
imputer = SimpleImputer(strategy="mean").fit(X)
imputer.transform(X)
imputer.transform(np.array([[np.nan, 1, 1]]))
Preprocessors:
OrdinalEncoder
(Ordinale für Eingangskategorien)LabelEncoder
(Ordinale für Zielkategorien)OneHotEncoder
(One-Hot-Encoding für Eingangskategorien, standardmäßig sparse)LabelBinarizer
(One-Hot-Encoding für Zielkategorien)Beispiel:
from sklearn.preprocessing import LabelBinarizer
encoder = LabelBinarizer().fit(iris_species)
iris_species_one_hot = encoder.transform(iris_species)
Beispiel für das Preprocessing von Textdaten: Zählen von Worten
from sklearn.feature_extraction.text import CountVectorizer
sample = ['problem of evil',
'evil queen',
'horizon problem']
vectorizer = CountVectorizer().fit(sample)
print(vectorizer.vocabulary_)
X = vectorizer.transform(sample)
print(X)
print(X.todense())
import pandas as pd
iris = pd.read_csv(
"http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data",
header=None)
erste Zeile: 5.1,3.5,1.4,0.2,Iris-setosa
Aufgaben:
Pipelines können aus mehreren transformierenden Algorithmen und einem vorhersagenden Algorithmus zusammengesetzt werden:
from sklearn.pipeline import make_pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
model = make_pipeline(
SimpleImputer(strategy='mean'),
StandardScaler(),
LinearRegression()
)
Aufgabe:
Erstelle eine Pipeline für die Kategorisierung von Iris-Daten
Ein trainiertes Modell kann für spätere Verwendung gespeichert werden
In Python können Objekte mittels des pickle
-Moduls gespeichert / geladen werden
import pickle
with open("model.pickle", mode="wb") as picklefile:
pickle.dump(model, picklefile)
import pickle
with open("model.pickle", mode="rb") as picklefile:
model = pickle.load(picklefile)
model.predict(data)
Regression:
sklearn.linear_model.LinearRegression
sklearn.neural_network.MLPRegressor
Klassifizierung:
sklearn.neighbors.KNeighborsClassifier
sklearn.tree.DecisionTreeClassifier
sklearn.ensemble.RandomForestClassifier
sklearn.linear_model.LogisticRegression
sklearn.naive_bayes.GaussianNB
sklearn.naive_bayes.MultinomialNB
sklearn.svm.SVC
sklearn.neural_network.MLPClassifier
sklearn.neighbors.KNeighborsClassifier
Die Anzahl k
der betrachteten Nachbarn kann festgesetzt werden (Standardwert = 5)
Siehe auch: https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html
siehe: Python Data Science Handbook - Decision Trees and Random Forests
Random Forests: Die Daten werden in verschiedene Untermengen zerlegt. Mittels jeder Untermenge wird ein einzelner Decision Tree erstellt. Die Gesamtheit der Decision Trees wird zu einem sogenannten Random Forest zusammengeführt.
RandomForestClassifier(n_estimators=100)
Beispiel: https://scikit-learn.org/stable/auto_examples/linear_model/plot_logistic.html
LogisticRegression(solver="liblinear", multi_class="auto")
siehe:
Beispiel: verschiedene Einkäufe bei verschiedenen Supermärkten:
from sklearn.linear_model import LinearRegression
X = [[1, 1], [2, 3], [3, 2], [0, 0]]
y = [4.60, 14.50, 12.00, 0.0]
model = LinearRegression()
model.fit(X, y)
yfit = model.predict([[1, 0], [0, 1], [2, 2]])
print(yfit)
# [1.18333333 3.78333333 9.78333333]
Kennzahlen der "erlernten" Regression:
model.coef_
model.intercept_
Übung: Abschätzen der petal width (Spaltenindex 3) basierend auf der petal length (Spaltenindex 2) bei den Iris-Daten
from sklearn import datasets
iris = datasets.load_iris()
Manche Daten passen nicht in das Schema eines linearen Zusammenhangs wie:
y = a*x + b
.
Wir könnten einen polynomialen Zusammenhang annehmen, z.B.:
y = a*x^2 + b*x + c
y = a*x^3 + b*x^2 + c*x + d
scikit-learn bietet einen Preprocessor namens PolynomialFeatures
.
from sklearn.preprocessing import PolynomialFeatures
poly_model = make_pipeline(
PolynomialFeatures(2),
LinearRegression()
)
poly_model.fit(x, y)
Iris-Datensatz: Abschätzen der Spalte 0 basierend auf Spalten 1 und 2
from sklearn import datasets
from sklearn.neural_network import MLPRegressor
iris = datasets.load_iris()
X = iris.data[:,1:3]
y = iris.data[:, 0]
model = MLPRegressor(
hidden_layer_sizes=(8, 8),
alpha=1.0,
max_iter=2000
)
model.fit(X, y)
test_data = [
[3.4, 1.9],
[3.0, 4.7],
[3.1, 5.0]
]
y_pred = model.predict(test_data)
print(y_pred)
Klassifizierung:
Regression:
Wie gut kategorisiert ein bestimmter Algorithmus die Iris-Daten?
from sklearn import metrics
y_prediction = model.predict(x_test)
print(metrics.accuracy_score(y_test, y_prediction))
print(metrics.confusion_matrix(y_test, y_prediction))
print(list(metrics.precision_recall_fscore_support(
y_test, y_prediction)))
Hilfsfunktion in scikit-learn:
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X, Y)
optionale Parameter:
test_size
(Standardwert 0.25
)random_state
(Integer-Seed für Zufallsauswahl)Bei der Kreuzvalidierung (cross-validation) werden die Daten wiederholt in unterschiedliche Trainings- und Testdaten unterteilt, sodass jeder Eintrag einmal in den Testdaten vorkommt.
from sklearn.model_selection import cross_validate
test_results = cross_validate(
model, X, y, cv=5, scoring="accuracy"
)
print(test_results["test_score"])
Bestimmen der ROC mit scikit-learn:
# false positive rates, true positive rates, thresholds
fpr, tpr, thresholds = metrics.roc_curve(
y_test,
classifier.predict_proba(X_test)[:, 0]
)
ideale Kombination: false positive rate = 0, true positive rate = 1
Zeichnen der ROC:
plt.plot(fpr, tpr, marker="o")
Bestimmen der AUC:
auc = metrics.auc(fpr, tpr)
Pipelines können das Verarbeiten von Eingangswerten x abstrahieren
Eigene Klassen können das Verarbeiten von sowohl x als auch y abstrahieren
direkte Verwendung eines Modells, um Ãœberleben auf der Titanic vorherzusagen:
model.predict([[2, 0, 28.0, 0]])
# [0]
abstrahiertes Interface:
classifier.predict_survival(
pclass=2, sex="male", age=28.0, sibsp=0
)
# False
Eingangsdaten: Schwarz-weiß-Bilder bekannter Personen (Größe 62 x 47) und deren Namen
Ziel: erkennen der Personen mittels eines neuronalen Netzwerks
from sklearn.datasets import fetch_lfw_people
faces = fetch_lfw_people(min_faces_per_person=60)
Einträge:
faces.images
: Array von Bildern (1248 x 62 x 47)faces.target
: Array von numerischen Labeln (1, 3, 3, 3, 5, ...)faces.target_names
: Array von Labelnamen (0="Ariel Sharon", 1="Colin Powell", ...)num_images = faces.images.shape[0]
num_pixels = faces.images.shape[1] * faces.images.shape[2]
X = faces.images.reshape(num_images, num_pixels)
from sklearn.preprocessing import LabelBinarizer
encoder = LabelBinarizer().fit(faces.target)
Y = encoder.transform(faces.target)
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X, Y)
from sklearn.neural_network import MLPClassifier
model = MLPClassifier(hidden_layer_sizes=(250, 150, 100),
early_stopping=True,
n_iter_no_change=100,
max_iter=2000,
verbose=True)
model.fit(X_train, Y_train)
Konfiguration des Algorithmus:
from sklearn import metrics
real_labels = Y_test.argmax(axis=1)
pred_labels = model.predict_proba(X_test).argmax(axis=1)
print(metrics.accuracy_score(real_labels, pred_labels))
argmax
gibt den index des größten Eintrags im Array zurück
Anzeigen eines zufälligen Gesichts, des echten Namens und des vorhergesagten Namens:
import matplotlib.pyplot as plt
from random import randrange
# randomly select a face
index = randrange(X_test.shape[0])
plt.imshow(X_test[index].reshape(62, 47), cmap="gray")
real_label = real_labels[index]
pred_label = pred_labels[index]
print("real name:", faces.target_names[real_label])
print("predicted name:", faces.target_names[pred_label])