Machine Learning – kurz & gut. Oliver Zeigermann
Чтение книги онлайн.
Читать онлайн книгу Machine Learning – kurz & gut - Oliver Zeigermann страница 6
sepal_width: Breite des Kelchblatts
petal_length: Länge des Kronblatts
petal_width: Breite des Kronblatts
Diese können wir aus der 150-x-4-Matrix der Features extrahieren und haben dann jeweils einen Vektor mit 150 Einträgen:
X_sepal_length = X[:, 0]
X_sepal_width = X[:, 1]
X_petal_length = X[:, 2]
X_petal_width = X[:, 3]
Die eventuell etwas überraschende Syntax, um einen Vektor aus der Matrix zu bekommen [:, 0], bietet uns NumPy (https://docs.scipy.org/doc/numpy/user/basics.indexing.html), das von Scikit-Learn für Datenstrukturen genutzt wird. Die Syntax besagt, dass wir von der ersten Dimension alle Einträge wünschen und von der zweiten Dimension nur das nullte, erste, zweite und dritte Feature. NumPy ist eine zweite, grundlegendere Python-Bibliothek, die performante Datenstrukturen zur Verfügung stellt. Sie wird uns am Rande immer wieder begegnen und dann auch detaillierter vorgestellt werden. Wie bei vielen Programmiersprachen üblich, fängt auch bei Python die Zählung bei null und nicht bei eins an.
Wir bringen dem Computer bei, Irisblüten zu unterscheiden
Hier möchten wir nun dem Computer beibringen, die unterschiedlichen Arten der Irisblüten anhand ihrer Features zu unterscheiden. Das ist erstaunlich einfach, da wir mit Scikit-Learn eine Software nutzen, die genau für so etwas gedacht ist. Wir brauchen zuerst einen sogenannten Estimator, also eine Strategie, wie der Computer lernen soll.
Hier nutzen wir wieder das Supervised Learning, das heißt, wir trainieren unseren Estimator mit einer Reihe von Datensätzen, von denen wir die Klassifikation in eine der drei Arten kennen. Danach hoffen wir, dass unser Estimator auch Irisblüten, die wir bisher noch nicht gesehen haben, richtig klassifiziert, also anhand der Größe der Blütenblätter sagen kann, was für eine Art Iris wir vor uns haben. Dies nennt man Generalisierung.
Das mit der Hoffnung ist so eine Sache, und daher nutzen wir nicht alle unsere Datensätze zum Training, sondern halten einige zurück, um danach zu testen, wie gut das Training eigentlich funktioniert hat. Auch dabei unterstützt uns Scikit-Learn mit seinem model_selection-Paket. Damit können wir unsere Daten vom Zufall gesteuert in Trainings- und Testdaten aufteilen. Ein typisches Verhältnis sind 60% für das Training und 40% für den Test:
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test =
train_test_split(X, y, test_size=0.4)
Nun haben wir 90 Datensätze in X_train bzw. y_train und 60 in X_test bzw. y_test:
X_train.shape, y_train.shape, X_test.shape, y_test.shape
> ((90, 4), (90,), (60, 4), (60,))
Hier führen wir auch eine Konvention ein. Vom Code erzeugte Ausgaben schreiben wir direkt hinter den Code und fangen die Zeile mit einem Größerzeichen (>) an. Im Beispiel oben ist ((90, 4), (90,), (60, 4), (60,)) also nicht Teil des Codes, sondern die Ausgabe, die durch X_train.shape, y_train.shape, X_test.shape, y_test.shape im Notebook erzeugt wurde.
Nearest Neighbors
Eine wirkliche einfache Strategie heißt Nearest Neighbors Classification (http://scikit-learn.org/stable/modules/neighbors.html#classification). In der simpelsten Version wird untersucht, welchem bekannten Datensatz eine Eingabe am nächsten ist. Dann wird davon ausgegangen, dass diese neue Eingabe von derselben Art ist. Fertig. Das mag naiv klingen, aber erstaunlicherweise ist dieser Ansatz wirklich mächtig. Es ist gar nicht so weit hergeholt, diesen Ansatz mit erkenntnistheoretischen Klassikern zu vergleichen (http://37steps.com/4370/nn-rule-invention/). Vielleicht verarbeiten sogar Fliegen Gerüche mit einem ähnlichen Ansatz (https://twitter.com/dribnet/status/931830521843236864).
Wir sehen uns erst einmal den Code an und welche Ergebnisse diese Lernstrategie für unsere Daten liefert. Als Erstes erzeugen wir einen entsprechenden Estimator. Parameter 1 gibt an, dass wir nur nach dem jeweils nächsten bekannten Datenpunkt entscheiden. Das wird später noch wichtig:
from sklearn import neighbors
clf = neighbors.KNeighborsClassifier(1)
Nun haben wir in clf unseren Estimator und können diesen trainieren. Dankenswerterweise funktioniert das in Scikit-Learn immer auf dieselbe Weise, nämlich indem wir unsere Trainingsfeatures zusammen mit der zugehörigen Irisart in die fit-Methode einfüttern:
clf.fit(X_train, y_train)
Danach können wir Vorhersagen treffen. Nehmen wir an, wir haben die folgenden Angaben über die Maße der Blüte einer Iris: Länge des Kelchblatts = 6,3 cm, Breite des Kelchblatts = 2,7 cm, Länge des Kronblatts = 5,5 cm und Breite des Kronblatts = 1,5 cm. Wir füttern diese Daten nun in die predict-Methode und bekommen die Irisart 2 geliefert (wie erwähnt, werden wir Ausgaben von nun an in einer neuen Zeile darstellen, die mit einem Größerzeichen anfängt):
clf.predict([[6.3, 2.7, 5.5, 1.5]])
> 2
Das ist insofern bemerkenswert, da wir diese Werte nicht für das Training verwendet haben und dennoch eine Antwort bekommen. Woher wissen wir, wie vertrauenswürdig diese Antwort ist? War das Training insgesamt erfolgreich? Auch dafür gibt es eine Methode, die überprüft, wie gut ein Satz von Features auf einen Satz von Labels passt. Das Ergebnis befindet sich zwischen 0 und 1. 0 steht für »überhaupt nicht« und 1 für »passt perfekt«:
clf.score(X_train, y_train)
> 1.0
Hurra! 1.0 ist das bestmögliche Ergebnis, das war einfach! Aber wir wollen auch bisher nicht gesehene Daten generalisieren und machen daher den Check mit den bereits vorbereiteten Testdaten. Diese hat der Estimator ja bisher noch nicht gesehen, und daher geben sie Aufschluss über das Maß der Generalisierung:
clf.score(X_test, y_test)
> 0.94999999999999996
Dieser Wert besagt, dass wir 95% aller Testdatensätze richtig vorhersagen können. Nicht perfekt, aber auch nicht so schlecht und in der Praxis meist völlig ausreichend. Das liegt natürlich daran, dass wir einen besonders sauberen und aussagekräftigen Datensatz vorliegen haben. Bei echten Problemen sind die Ergebnisse auch mit viel Aufwand bei der Auswahl der Features, der Trainingsprozedur und der Lernstrategie oft deutlich schlechter.
Nearest Neighbors Classification
Unsere