Klassifikation

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.