Bitte erstell ein neues Jupyter-Notebook und nennen es
Klassifikation
.
Wir nutzen ein Datenset, das handschriftliche Ziffern in Form von 8x8
Feldern mit Werten der Farbstärkte darstellt. Eine Beschreibung des
Datensets gib es bei
scikit-learn
und im UC Irvine Machine Learning
Repository. Dieses
Datenset bringt scikit-learn
selber mit.
Wir importieren eine Funktion zum Laden des Datensets und rufen dieses auf.
from sklearn.datasets import load_digits
digits = load_digits()
Die Daten und Metadaten sind in einem sogenannten Bunch
-Objekt organisiert
type(digits)
Dieser Bunch hat folgende Attribute.
dir(digits)
Schauen wir uns mal die Beschreibung an
print(digits.DESCR)
Die eigentlichen Daten sind in einem numpy-Array abgelegt.
type(digits.data)
Schauen wir es uns mal an.
digits.data
Schauen wir uns die Dimension der Matrix an - es handelt sich um eine zweidimentionsale Matrix mit 1797 Zeilen und 64 Spalten. Es sind 1797 Bilder (also weniger als die originalen 5620) und 64 Features (eine lineare Darstellung der 8x8 Felder-Farbintensitätswerte) .
digits.data.shape
Das Target-Attribute ist ebenfalls ein numpy-array …
type(digits.target)
… allerding mit nur einer Dimension.
digits.target.shape
Jeder Wert entspricht der geschriebenen Nummer
digits.target
Das Bunch-Objekt hat noch das Attribute target_names
.
Normalerweise wird jeder Zahl in targent
hier ein Name zugeordnen.
Da es sich aber tatsächlich um Ziffern von 0 - 9 handelt, ist das in diesem
nicht nötig.
digits.target_names
In diesem Datenset gibt es zusätzlich noch ein Attribute images
.
Es enthält für jede geschrieben Ziffer die Farbwerte in ein 8x8-Matrix.
len(digits.images)
Schauen wir uns zum Beispiel das erste Bild an …
digits.images[0]
… oder das zehnte Bild
digits.images[9]
Wir können die in dieser Form gespeicherten Farbintensitäten
auch mit matplotlib
anzeigen lassen. Hier zum Beispiel für die
ersten 30 Bilder (wenn man mehr haben möchte, muss man in subplot
mehr als 3 Zeilen angeben).
import matplotlib.pyplot as plt
%matplotlib inline
fig, axes = plt.subplots(3, 10, figsize=(10, 5))
for ax, img in zip(axes.ravel(), digits.images):
ax.imshow(img, cmap=plt.cm.gray_r)
Um einen Klassifikator für ein Klassifikation zu trainieren
und dann später seine Güte zu bewerten, wird das Datenset
(genauer gesagt die Attribute data
und target
) in
ein Trainingsset (75%) und Testset (25%) aufgeteilt. Die Konvention
ist hier eine großes X
für den Variablen der Datenmatrix und ein kleines y
für den Target-Vektor zu nutzen.
Anmerkung: Bei einigen der folgenden Schritte wird
von zufälligen Zuständen ausgegagen. Um diese
fest zu setzen und somit die Analyse reproduzierbar zu machen,
kann man den Parameter random_state
nutzen und mit einer Zahl
versehen.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
digits['data'], digits['target'], random_state=1)
Die Maße der zweidimensionalen Trainigs-Daten-Matrix:
X_train.shape
Die Maße der zweidimensionalen Test-Daten-Matrix:
X_test.shape
Die Länge des Trainingsvektor entspricht der Anzahl an Zeilen der Trianingsmatrix.
y_train.shape
Die Länge des Testsvektors entspricht der Anzahl an Zeilen der Testsmatrix.
y_test.shape
Wir werden zuerst mit einem k-Nearest-Neighbor-Klassifizierer Arbeiten und laden dazu die Klasse …
from sklearn.neighbors import KNeighborsClassifier
… und erzeugen ein Objekt davon. Hierbei können wird die Anzahl an zu betrachteten Nachbarn angeben:
knn_clf = KNeighborsClassifier(n_neighbors=1)
Jetzt trainieren wir den Klassifikator mit den Trainingsdaten.
Dafür wird in scikit-learn
unabhängig von Klassifikator die
Methode fit
genutzt.
knn_clf.fit(X_train, y_train)
Herzlichen Glückwunsch - wir haben unser aller erstes Klassifikator-Modell gebaut und trainiert. Jetzt kann mit diesem neue Daten (also Vektoren der Länger 64, die die 8x8 Bilder darstellen) klassifizieren - in diesem Fall also um vorauszusagen, welche Ziffer dargestellt wurde.
Wir haben unsere Testdaten noch verfügbar und können die Methode predict
des trainierten Klassifiers nutzen und erhalten die Voraussagen.
knn_clf.predict(X_test)
Da wir für das Testset wissen welche Ziffern tatsächlich herauskommen
sollte, können wir die Methode score
des Klassifiers nutzen. Diese
führt die Voraussage durch und vergleicht sie mit den tatsächlichen
Target-Werten. Am Ende bekommen wir einen Wert zwischen 0 (schlecht)
und 1 (gut).
knn_clf.score(X_test, y_test)
Führen sie das gleich Verfahren mit einen k-Nearest-Neighbor-Klassifizierer selbstständig durch, der 3 Nachbar betrachtet (Code hier nicht angezeigt).
Das schöne an scikit-learn
ist, dass alle Klassifikatoren
die gleichen Methoden besitzten. Sprich anderen Klassifikatoren
nutzen auch fit
, predict
und score
.
Machen wir nun eine Klassifikation mit einem Random-Forest-Klassifikator ganz äquivalent zu der vorherigen Herangehensweise:
from sklearn.ensemble import RandomForestClassifier
random_forest_cfl = RandomForestClassifier(random_state=1)
random_forest_cfl.fit(X_train, y_train)
random_forest_cfl.score(X_test, y_test)
Das gleiche machen wir nun für eine Klassifikation mit einem künstlichen, neuralen Netz (Multi-Layer-Perceptron). Standardmäßig hat das Netz ein eine Hidden-Layer mit 100 Nodes.
from sklearn.neural_network import MLPClassifier
mlpc = MLPClassifier(random_state=1)
mlpc.fit(X_train, y_train)
mlpc.score(X_test, y_test)
Wir können die Anzahl an Hidden-Layer und Anzahl an Nodes in diesen als Parameter setzen (hier 3 Schichten mit mit 200, 100 und 20 Nodes). Man kann die Schritte kondenensiert schreiben, indem man die Methodenaufrufe direkt verknüpft.
MLPClassifier(random_state=1, hidden_layer_sizes=(200, 100, 20)).fit(
X_train, y_train).score(X_test, y_test)
Es gibt noch viele weitere Klassifikatoren in scikit-learn. Für einen Einführung sollten dies 3 Bespiele aber reichen. Wir konnten hier aber sehen, wie einfach sklearn es uns auf Grund der kosistenten Methoden macht, verschiedene Klassifikationsmethode zu nutzen.