Erhalten Sie Zugang zu diesem und mehr als 300000 Büchern ab EUR 5,99 monatlich.
Der kompakte Schnelleinstieg in Machine Learning und Deep Learning - Die 3. Auflage des Bestsellers wurde ergänzt durch Kapitel zu Large Language Models wie ChatGPT und zu MLOps - Anhand konkreter Datensätze lernst du einen typischen Workflow kennen: vom Datenimport über Datenbereinigung, Datenanalyse bis hin zur Datenvisualisierung - Nicht nur für zukünftige Data Scientists und ML-Profis geeignet, sondern durch seine durchdachte Didaktik auch für Interessierte, die nur am Rande mit ML zu tun haben, wie z.B. Softwareentwickler*innen Machine Learning beeinflusst heute beinahe alle Bereiche der Technik und der Gesellschaft. Dieses Buch bietet Interessierten, die einen technischen Hintergrund haben, die schnellstmögliche Einführung in das umfangreiche Themengebiet des maschinellen Lernens und der statistischen Datenanalyse. Dabei werden folgende Themen behandelt und mit praktischen Beispielen veranschaulicht: - Datenvorbereitung, Feature-Auswahl, Modellvalidierung - Supervised und Unsupervised Learning - Neuronale Netze und Deep Learning - Reinforcement Learning - LLMs – moderne Sprachmodelle - MLOps – Machine Learning für die Praxis Anhand von Beispieldatensätzen lernst du einen typischen Workflow kennen: vom Datenimport über Datenbereinigung, Datenanalyse bis hin zur Datenvisualisierung. Mit den Codebeispielen kannst du in Jupyter Notebooks experimentieren. Sie basieren auf Python und den Bibliotheken Scikit-Learn, Pandas, NumPy, TensorFlow und Keras. Nach der Lektüre dieses Buchs hast du einen Überblick über das gesamte Thema und kannst Ansätze einordnen und bewerten. Das Buch vermittelt dir eine solide Grundlage, um erste eigene Machine-Learning-Modelle zu trainieren und vertiefende Literatur zu verstehen.
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 248
Veröffentlichungsjahr: 2024
Das E-Book (TTS) können Sie hören im Abo „Legimi Premium” in Legimi-Apps auf:
Copyright und Urheberrechte:
Die durch die dpunkt.verlag GmbH vertriebenen digitalen Inhalte sind urheberrechtlich geschützt. Der Nutzer verpflichtet sich, die Urheberrechte anzuerkennen und einzuhalten. Es werden keine Urheber-, Nutzungs- und sonstigen Schutzrechte an den Inhalten auf den Nutzer übertragen. Der Nutzer ist nur berechtigt, den abgerufenen Inhalt zu eigenen Zwecken zu nutzen. Er ist nicht berechtigt, den Inhalt im Internet, in Intranets, in Extranets oder sonst wie Dritten zur Verwertung zur Verfügung zu stellen. Eine öffentliche Wiedergabe oder sonstige Weiterveröffentlichung und eine gewerbliche Vervielfältigung der Inhalte wird ausdrücklich ausgeschlossen. Der Nutzer darf Urheberrechtsvermerke, Markenzeichen und andere Rechtsvorbehalte im abgerufenen Inhalt nicht entfernen.
kurz & gut
Oliver Zeigermann und Chi Nhan Nguyen
Oliver Zeigermann und Chi Nhan Nguyen
Lektorat: Alexandra Follenius
Copy-Editing: Sibylle Feldmann, www.richtiger-text.de
Satz: III-Satz, www.drei-satz.de
Herstellung: Stefanie Weidner
Umschlaggestaltung: Karen Montgomery, Michael Oréal, www.oreal.de
Bibliografische Information der Deutschen Nationalbibliothek
Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.
ISBN:
978-3-96009-236-0
978-3-96010-856-6
ePub
978-3-96010-857-3
3. Auflage 2024
Copyright © 2024 dpunkt.verlag GmbH
Wieblinger Weg 17
69123 Heidelberg
Dieses Buch erscheint in Kooperation mit O’Reilly Media, Inc. unter dem Imprint »O’REILLY«. O’REILLY ist ein Markenzeichen und eine eingetragene Marke von O’Reilly Media, Inc. und wird mit Einwilligung des Eigentümers verwendet.
Schreiben Sie uns:
Falls Sie Anregungen, Wünsche und Kommentare haben, lassen Sie es uns wissen: [email protected].
Die vorliegende Publikation ist urheberrechtlich geschützt. Alle Rechte vorbehalten. Die Verwendung der Texte und Abbildungen, auch auszugsweise, ist ohne die schriftliche Zustimmung des Verlags urheberrechtswidrig und daher strafbar. Dies gilt insbesondere für die Vervielfältigung, Übersetzung oder die Verwendung in elektronischen Systemen.
Es wird darauf hingewiesen, dass die im Buch verwendeten Soft- und Hardware-Bezeichnungen sowie Markennamen und Produktbezeichnungen der jeweiligen Firmen im Allgemeinen warenzeichen-, marken- oder patentrechtlichem Schutz unterliegen.
Alle Angaben und Programme in diesem Buch wurden mit größter Sorgfalt kontrolliert. Weder Autoren noch Verlag können jedoch für Schäden haftbar gemacht werden, die in Zusammenhang mit der Verwendung dieses Buches stehen.
1Einführung
Wie du dieses Buch lesen kannst
Arten von Machine Learning – ein Überblick
2Quick-Start
Unser erstes Python-Notebook
Unser Beispiel: Irisblüten
Wir bringen dem Computer bei, Irisblüten zu unterscheiden
Nearest Neighbors Classification
Overfitting
Underfitting
Eine bessere Feature-Auswahl
Weiterführende Links
3Datenimport und -vorbereitung
Datenimport
Das vorbereitete Projekt
Preprocessing
Weiterführende Links
4Supervised Learning
Lineare Regression
Logistische Regression
Support Vector Machine
Decision-Tree-Klassifikator
Random-Forest-Klassifikator
Boosted Decision Trees
Weiterführende Links
5Feature-Auswahl
Reduzierung der Features
Auswahl der Features
Principal-Component-Analyse
Feature-Selektion
Weiterführende Links
6Modellvalidierung
Metrik für Klassifikation
Metrik für Regression
Evaluierung
Hyperparameter-Suche
Weiterführende Links
7Neuronale Netze und Deep Learning
Iris mit neuronalen Netzen
Feed Forward Networks
Deep Neural Networks
Anwendungsbeispiel: Erkennung von Verkehrsschildern
Data Augmentation
Neuere Ansätze im Bereich CNN
Weiterführende Links
8Unsupervised Learning mit Autoencodern
Das Szenario: Visuelle Regressionstests mit Autoencodern – eingeschlichene Fehler erkennen
Die Idee von Autoencodern
Aufbau unseres Autoencoders
Training und Ergebnisse
Was passiert im Autoencoder?
Fazit
Weiterführende Links
9Deep Reinforcement Learning
Grundkonzepte und Terminologie
Ein Beispiel: der hungrige Bär
Optimierung als Herausforderung
Technische Modellierung als OpenAI Environment
Training mit PPO
Training als Supervised-Deep-Learning-Problemstellung formulieren
Der Policy-Loss
Actor-Critic über das Value Network
Sample-Effizienz und katastrophale Updates
Exploration vs. Exploitation
Fazit
Weiterführende Links
10LLMs – moderne Sprachmodelle
Große Sprachmodelle
Einsatz von großen Sprachmodellen
LLMs auf einer großen Wissensbasis
Embeddings und Vektordatenbanken
Encoder-Modelle: Darf’s auch etwas weniger sein?
Fazit
Weiterführende Links
11MLOps – Machine Learning für die Praxis
Phasen eines Machine-Learning-Projekts
Unser Beispiel
KPIs – Key Performance Indicators
Training
Ergebnisse
Invarianten
MLOps – Machine Learning Operations
Monitoring und Drift-Erkennung – die Welt steht nicht still
Analyse und Interpretation – Was ist das Problem mit unserem Modell?
Re-Training …
… oder Re-Engineering?
Baselines und Fallbacks – Was machen wir, wenn unser Modell versagt?
Produktiver Einsatz
Fazit
Weiterführende Links
Index
Im Machine Learning wird ein Modell anhand von Daten trainiert und für ähnliche Daten genutzt oder darauf angewandt. Dafür stehen unterschiedliche Ansätze von einfachen linearen Modellen bis hin zu großen Sprachmodellen zur Verfügung. Da das erlernte Modell häufig nicht mehr komplett von uns Menschen verstanden werden kann, sind zudem Methoden notwendig, ein Modell als Blackbox zu validieren.
Was man mit Machine Learning machen kann und wie ein solches Training und die Validierung im Detail funktionieren, ist Gegenstand dieses Buchs.
Dies ist ein praxisorientiertes Buch mit lauffähigem Code. Alle Codebeispiele werden in Python 3 angegeben – Python-Kenntnisse sind jedoch nicht zwingend erforderlich, denn wir werden die notwendigen Grundlagen Stück für Stück in entsprechend gekennzeichneten Kästen vermitteln. Diese kannst du überspringen, falls du Python bereits beherrschst. Wenn du dir nur einen generellen Überblick verschaffen willst, ist es auch möglich, die Programmierbeispiele komplett zu überspringen, einen tieferen Einblick bekommst du aber nur mit ihrer Hilfe.
Dieses Buch ist kein Nachschlagewerk. Du kannst es gut von vorn bis hinten durchlesen. Dann dient es dir als Einführung in das Thema Machine Learning. Du kannst aber auch bestimmte Kapitel auslassen, wenn du dich nicht so sehr für das darin behandelte Thema interessierst. In jedem Fall solltest du den Schnelldurchlauf in Kapitel 2, Quick-Start, und Kapitel 4, Supervised Learning, komplett lesen. Diese Kapitel enthalten die Kernthemen dieses Buchs.
Das Buch ist in zwei Teile aufgeteilt. Die Kapitel 1 bis Kapitel 6 des ersten Teils liefern einen strukturierten Aufbau der Grundlagen. Im zweiten Teil, bestehend aus Kapitel 7 bis Kapitel 11, lernst du anhand von Anwendungsbeispielen fortgeschrittene Techniken kennen, wie neuronale Netze, Autoencoder, Deep Reinforcement Learning, MLOps und große Sprachmodelle.
In Kapitel 2, Quick-Start, findest du einen Schnelldurchlauf durch alle Stationen dieses Buchs. In Kapitel 4 werden wir uns durch die einzelnen klassischen Strategien des Supervised Learning hindurcharbeiten und dabei deren Unterschiede, Stärken und Schwächen kennenlernen.
Die Kapitel 5, Feature-Auswahl und Kapitel 6, Modellvalidierung, gehen etwas mehr in die Tiefe und beantworten Fragen, die eventuell in Kapitel 4 offengeblieben sind. Sie enthalten Formeln und erfordern ein wenig mathematisches Interesse und Verständnis.
Kapitel 3, Datenimport und -vorbereitung, liegt uns persönlich besonders am Herzen. Gute Daten sind die Voraussetzung für einen erfolgreichen Machine-Learning-Prozess. In diesem Kapitel schaffen wir zudem die technischen Grundlagen für den Umgang mit Python und seinen Bibliotheken.
Kapitel 7 handelt von Deep Learning mit neuronalen Netzen. Dies ist ebenfalls eine Strategie des Supervised Learning, ist aber in vielen Punkten anders als die zuvor in Kapitel 4 behandelten Strategien. Wir wenden alles bisher Gelernte in einer praktischen Anwendung an, indem wir versuchen, Geschwindigkeitsbeschränkungen auf Verkehrsschildern zu erkennen.
In Kapitel 8, Unsupervised Learning mit Autoencodern, und Kapitel 9, Deep Reinforcement Learning, verfolgen wir den Pfad der neuronalen Netze weiter, und du erfährst, wie man diese für unüberwachtes und verstärkendes Lernen einsetzen kann.
In Kapitel 10, LLMs – moderne Sprachmodelle, beschäftigen wir uns mit Large Language Models und was diese für den Bereich des Machine Learning bedeuten. Neben den großen Sprachmodellen wie GPT und deren bekannter Anwendung ChatGPT widmen wir uns auch den spezialisierten Transformer-Modellen. Dabei bringen wir Ordnung in den Zoo der Sprachmodelle.
Zum Abschluss des Buchs werden wir in Kapitel 11, MLOps – Machine Learning für die Praxis, mit dem Thema »Machine Learning Operations« (MLOPs) konzeptioneller. Hier steht weniger der Code oder ein spezielles Werkzeug im Vordergrund als die Idee davon, wie ein Machine-Learning-Projekt abläuft, was man beachten muss, wenn es in Betrieb gehen soll, und wie man es dort hält.
Stell dir ein System vor, das sagen soll, ob auf einem Bild ein Hund zu sehen ist oder nicht. So etwas könntest du programmatisch mit Methoden der Bildverarbeitung umsetzen. Dazu könntest du einen Satz von Regeln anlegen, anhand deren das System entscheidet, ob es einen Hund gibt oder eben nicht. So ein System ist jedoch nur schwer zu entwickeln, es wird wahrscheinlich viele Hunde gar nicht erkennen oder in manchen Bildern fälschlicherweise Hunde vermuten. Was macht man da? Man fügt neue Regeln hinzu, und andere verfeinert man manuell.
Mit einem Machine-Learning-Ansatz würde das ganz anders laufen. Du müsstest ein System konfigurieren und mit entsprechenden Hundebildern (und Bildern ohne Hund) in einer Lernphase trainieren. Das System lernt dann im Idealfall selbst die Regeln, die du sonst als Programmierer hättest explizit aufzählen müssen.
Von Machine Learning spricht man, wenn man einen Computer nicht direkt programmiert, sondern wenn diese Maschine bestimmte Fähigkeiten erlernt. In der klassischen Programmierung bringen wir ein Modell in ein Stück Code, mit dem wir eine Eingabe in eine Ausgabe wandeln. Im Machine Learning drehen wir das um und lassen die Maschine das Modell aus passenden Sätzen von Ein- und Ausgaben erlernen. Dies illustriert Abbildung 1-1. Ein solches Vorgehen nennt man auch Supervised Learning (überwachtes Lernen), da wir unser System aktiv anhand zueinander passender Datensätze trainieren.
Abbildung 1-1: Maschinelles Lernen vs. klassische Programmierung
Man kann den Bereich Machine Learning anhand unterschiedlicher Ansätze aufgliedern. Beim Supervised Learning (dem überwachten Lernen) trainierst du ein System mit Datensätzen aus Eingabe und erwarteter Ausgabe.
Für das Beispiel mit den Hundebildern musst du einen Satz von Bildern mit Hunden und ohne Hunde heraussuchen. Um den Trainingserfolg zu überprüfen, nimmst du einen anderen, bisher dem System nicht bekannten Teil der Bilder und lässt das System entscheiden, ob das Bild einen Hund enthält oder nicht. Da du für diese Bilder ja schon das richtige Ergebnis kennst, kannst du sehen, wie gut das System gelernt hat. Im Idealfall kann das System in dieser Testphase alle Bilder richtig zuordnen. Die Grenzen solcher Systeme gerade im Bereich der Bilderkennung und was du machen kannst, falls das System nicht richtig lernt, thematisieren wir in einem praktischen Beispiel in Kapitel 7, Neuronale Netze und Deep Learning.
So ein Beispiel nennt man auch eine Klassifikation. Das System lernt, Bilder in die beiden Klassen »Bild mit Hund« und »Bild ohne Hund« einzusortieren. Oft gibt es bei einer Klassifikation nur zwei Klassen, z.B. ob ein selbstfahrendes Auto in einer bestimmten Situation bremsen sollte oder nicht oder ob auf einem Ultraschallbild Krebs vermutet wird oder nicht. Häufig wird sich in einem solchen Fall nicht strikt für Ja oder Nein entschieden, stattdessen wird die Vorhersage mit einer Gewissheit versehen, meist einer Zahl zwischen 0 und 1.
Es gibt auch Klassifikationen, die zwischen einer ganzen Reihe von Klassen entscheiden, z.B. bei einer Handschriftenerkennung der Ziffern 0 bis 9, die bei Postsendungen zum Einsatz kommt. Hier haben wir zehn Klassen, nämlich für jede Ziffer von 0 bis 9 eine. Auch hier bekommen wir Wahrscheinlichkeiten pro Ziffer.
Der zweite Problembereich des Supervised Learning ist die Regression – also das Erlernen einer kontinuierlichen Funktion – anhand von Werten, die auf dieser Funktion liegen. Das wäre z.B. der Fall, wenn wir das Gewicht eines Hundes auf Basis bestimmter Parameter oder sogar eines Bilds des Tieres vorhersagen wollten.
Manchmal ist es gar nicht so einfach, den richtigen Ansatz für ein bestehendes Problem zu finden. Wenn die Ausgabe diskrete Werte sind (z.B. die Ziffern 0 bis 9), ist es wahrscheinlich ein Klassifikationsproblem. Hat man kontinuierliche Werte, wie bei dem Gewicht eines Hundes, ist es ein Regressionsproblem.
Beim Ansatz des Unsupervised Learning (des unüberwachten Lernens) sind keine Labels, also keine Vorgaben der richtigen Lösungen notwendig.
Ein Beispiel sind sogenannte Clustering-Verfahren: Sie nehmen eine automatische Kategorisierung der Daten vor und sortieren sie in zusammenhängende Gruppen bzw. »Klumpen« oder »Haufen« (Cluster). Die Kategorisierung geschieht dabei anhand ähnlicher Eigenschaften. Nehmen wir als Beispiel an, dass wir von einer Gruppe von Hunden die Größe und das Gewicht kennen. Wir nehmen dazu ein Koordinatensystem mit einer x-Achse, auf der wir die Größe auftragen, und einer y-Achse für das Gewicht. Versehen wir nun jeden Hund mit einem Punkt, der seinem Gewicht und seiner Größe entspricht, ergibt sich eine Verteilung der Hunde, wie in Abbildung 1-2 zu sehen.
Abbildung 1-2: Verteilung von Hunden (jeder Punkt ist ein Hund)
Ebenso wie wir als Menschen in der Lage wären, hier Gruppen einzutragen, ohne Ahnung von Hunden zu haben, kann das auch ein Clustering-Verfahren. Erst die Interpretation der Gruppen erfordert wieder menschliches Zutun. Ein mögliches Ergebnis ist in Abbildung 1-3 dargestellt. Andere Clusterungen sind natürlich möglich – das hängt vom jeweiligen Menschen oder Clustering-Verfahren ab.
Als kleine Übung bitten wir dich, den jeweiligen Clustern Interpretationen zu geben. Was für eine Gruppe könnte z.B. die Gruppe ganz rechts unten sein?
Abbildung 1-3: Automatisches Clustering der Hundegruppe (ohne Interpretation)
Zum Unsupervised Learning gehört auch die sogenannte Principal Component Analysis (PCA, Hauptkomponentenanalyse, https://de.wikipedia.org/wiki/Hauptkomponentenanalyseps://de.wikipedia.org/wiki/Hauptkomponentenanalyse). Durch eine Reduzierung der Dimensionen (d.h. der Anzahl der Variablen in den Datensätzen) werden dabei umfangreiche Datensätze vereinfacht, ohne dass wichtige Informationen verloren gehen. Dies werden wir ebenfalls für die Feature-Auswahl in Kapitel 5 nutzen. Das heißt, dieses Verfahren kann auch für die Datenvorverarbeitung beim Supervised Learning genutzt werden.
Als Beispiel für eine PCA kann man ICE-Fahrten von Berlin nach Hamburg betrachten. Kennt man die Abfahrtszeit, ist die geplante Ankunftszeit ungefähr daraus ableitbar. Beide Dimensionen in seinen Datensätzen zu halten, wäre unnötig. Dies herauszufinden und den Datensatz in seiner Dimension zu reduzieren (in unserem Fall von 2 auf 1), ist Aufgabe der PCA.
Kapitel 8, Unsupervised Learning mit Autoencodern, zeigt über diese Beispiele hinaus mit Autoencodern Techniken auf Basis von neuronalen Netzen.
Reinforcement Learning (bestärkendes Lernen oder verstärkendes Lernen, https://de.wikipedia.org/wiki/Best%C3%A4rkendes_Lernen) wird häufig in Spielsituationen verwendet. Ein System soll anhand positiver oder negativer Rückmeldungen auf eine ausgeführte Aktion ein optimales Verhalten innerhalb einer Situation erlernen. Diese Situation wird dem System mithilfe gewisser Eingabeparameter zusammen mit einer Bewertung des Spielstands mitgeteilt. Eine solche Bewertung kann zum Beispiel der Punktestand innerhalb eines Arcade-Spiels sein. Mit diesem könnte zusammen mit der Videodarstellung eines Spiels ein solches System gefüttert werden. Führt das System eine Aktion aus, z.B. Schießen, und führt dies zu einem höheren Punktestand, wird das Verhalten verstärkt.
Reinforcement Learning mit neuronalen Netzen wird in Kapitel 9 beschrieben.
Große Sprachmodelle (Large Language Models) haben das Potenzial, das Feld des Machine Learning neu aufzurollen. Diese vortrainierten Modelle haben die Fähigkeit, fast alle Aufgabenbereiche abzudecken, die sich mit Sprache darstellen lassen. Dabei ist durch Beispiele direkt innerhalb einer Anfrage auch eine Art Ad-hoc-Training möglich.
Die Modelle haben (noch) den Nachteil, sehr groß zu sein und sehr viel Rechenleistung zu brauchen. Zudem laufen die leistungsfähigsten Systeme, wie GPT-3 und GPT-4, Stand Anfang 2024 nur auf den Servern von OpenAI. Dies schränkt die Menge der möglichen Anwendungen zum einen aufgrund der Kosten, zum anderen wegen möglicher Probleme mit dem Datenschutz ein.
Mit diesen Modellen beschäftigen wir uns in Kapitel 10, LLMs – moderne Sprachmodelle.
In diesem Buch werden wir das auf Python basierende Framework Scikit-Learn (http://scikit-learn.org) verwenden. Oft wird auch nur der abgekürzte Name Sklearn genutzt.
Anhand eines kompletten und durchgängigen Beispiels kannst du dich hier schon einmal mit dem Vorgehen beim Machine Learning vertraut machen.
Damit du wirklich lauffähigen Code hast, aber keine Installationsarie durchlaufen musst, haben wir für dich ein sogenanntes Notebook erstellt. Das Notebook erfordert nur einen Browser für seine Darstellung. Der tatsächliche Code wird auf einem Server, auf dem auch sämtliche Software installiert ist, ausgeführt.
Für jedes Kapitel haben wir ein Notebook vorbereitet. Diese sind unter der URL https://github.com/DJCordhose/buch-machine-learning-notebooks (https://bit.ly/ml-kug) öffentlich erreichbar.
Dort kannst du dir das Notebook in der Vorschau inklusive aller Anmerkungen und Ergebnisse ansehen. Du kannst es aber auch auf deinen eigenen Computer herunterladen oder es direkt ohne Installation über die dort vorbereiteten Links auf Google Colab laufen lassen. Dieses Kapitel ist unter dem Namen kap2.ipynb erreichbar.
Notebooks
Gerade im Bereich Machine Learning führen wir oft interaktiv eine Reihe von Codeschnipseln aus, um z.B. einen Datensatz besser zu verstehen oder schnell eine andere Lernstrategie auszuprobieren. Sogenannte Notebooks erlauben uns genau das zusammen mit der Möglichkeit, so ein Notebook auch leicht teilen zu können und damit andere an unseren Ergebnissen partizipieren zu lassen.
In einem Notebook kannst du Texte und Grafiken mit Codeschnipseln mischen. Das Besondere dabei ist, dass diese Codeschnipsel wirklich ausführbar sind. Dabei wird der Code nicht notwendigerweise auf dem Rechner ausgeführt, auf dem das Ergebnis im Browser angezeigt wird. In unserem Beispiel hier wird der Code auf einem Rechner von Google ausgeführt, auf dem auch sämtliche Software installiert ist. Die Ausgabe erfolgt aber in dem Browser auf deinem Rechner, auf dem außer dem Browser nichts weiter installiert sein muss.
Im einfachsten Fall kannst du dir so ein Notebook einfach nur ansehen, ohne es überhaupt auszuführen. Das geht, weil so ein Notebook auch jedes Ergebnis, inklusive Bildern, eines Codeschnipsels speichert.
Mehr Informationen zu Notebooks findest du unterhttp://jupyter.org/.
Als Beispiel nehmen wir den Irisdatensatz, der dir im Buch immer wieder begegnen wird (siehe auch den Kasten auf der nächsten Seite). Es geht darum, anhand von vier Eigenschaften der Irisblüten (Features) drei unterschiedliche Irisarten voneinander zu unterscheiden. Features sind die zu einem Datensatz gehörigen Eingaben, Labels sind die zugehörigen Ausgaben. Diese Ausgaben sind in unserem Fall die Zahlen 0 bis 2 für die unterschiedlichen Irisarten. Man unterscheidet die Arten »Iris setosa« (0), »Iris virginica« (1) und »Iris versicolor« (2). Unser Beispiel ist dabei ein Klassifikationsproblem. Anhand der Features wollen wir das zugehörige Label erschließen. Da wir dazu das System mit Datensätzen trainieren, haben wir es mit Supervised Learning zu tun.
Dieser Irisdatensatz wird sehr gut verstanden und für viele Beispiele verwendet. Daher gibt es diverse Ressourcen dafür, und er ist sogar direkt in Scikit-Learn als Beispieldatensatz verfügbar, ohne dass du ihn dir von irgendwo besorgen müsstest. Wie erwähnt, ist Scikit-Learn eine zentrale Python-Bibliothek für Machine Learning, die wir über das ganze Buch hinweg einsetzen werden.
Ursprung des Irisdatensatzes
Der Irisdatensatz wurde von dem Botaniker Edgar Anderson (https://en.wikipedia.org/wiki/Edgar_Anderson) zusammengestellt. Bekanntheit erlangte er über die Verwendung durch den Statistiker Ronald Fisher (https://en.wikipedia.org/wiki/Ronald_Fisher). Dieser nutzte den Datensatz in einem Artikel eines Magazin zur Eugenik als Beispiel für statistische Methoden der Klassifikation. Wir distanzieren uns von Fishers Ansichten (https://en.wikipedia.org/wiki/Ronald_Fisher#Views_on_race) über Existenz und unterschiedliche mentale Fähigkeiten von menschlichen Rassen und generell von der Thematik der Eugenik.
Im ersten Schritt unseres Notebooks nutzen wir nun den Beispieldatensatz direkt aus Scikit-Learn und haben dann die kompletten Daten in der Variablen iris. Es ist bei Scikit-Learn üblich, die Features mit einem großen X und die Labels mit einem kleinen y zu bezeichnen. Der Unterschied in der Groß-/Kleinschreibung soll andeuten, dass y nur ein einfacher Vektor mit der Art der Iris ist, also 0, 1 oder 2. X hat hingegen zwei Dimensionen, da es für jeden Datensatz vier Features gibt:
Für jede der drei Arten gibt es jeweils 50 Beispiele. In jedem Beispiel ist zusammen mit der Irisart die Länge und Breite sowohl des Kelchblatts (Sepalum) als auch des Kronblatts (Petalum) erfasst. Das Kronblatt sind die bunten Blätter, die wir typischerweise als Blüte wahrnehmen. Das Kelchblatt ist meist grün wie der Stängel der Pflanze und schützt die Blüte im Knospenzustand. Bei einer blühenden Iris geht das Kelchblatt im Gegensatz zum Kronblatt ziemlich unter. Mehr dazu gibt es auf Wikipedia unter https://de.wikipedia.org/wiki/Portal:Statistik/Datensaetze#Iris.
Für uns ergibt das vier Features:
sepal_length
: Länge des Kelchblatts
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:
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.
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
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.
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:
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)
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.
Unsere Lernstrategie hat den Vorteil, wirklich einfach zu sein, sodass du schnell verstehen kannst, wie sie funktioniert. Am einfachsten geht das mit einer Grafik, in der wir auftragen, wie welcher Datensatz zu welcher Vorhersage führt. Wir sehen dabei gleich ein grundsätzliches Problem von Visualisierungen: Wir haben vier Features und ein Label, wir Menschen können aber nur wenige Dimensionen gleichzeitig erfassen, auf einem 2-D-Medium wie einem Blatt Papier oder einem Bildschirm eigentlich nur 2. Mit etwas Trickserei und Einschränkungen können es auch ein paar mehr werden, aber nicht viel mehr.
Wir entscheiden uns, nur zwei Features, Sepal width und Sepal length, darzustellen und die vorhergesagten Labels als Farbe in die Darstellung hineinzucodieren. Es ist wichtig, zu verstehen, dass wir es uns hier künstlich schwerer machen als nötig, denn mit allen vier Features haben wir es ja zu sehr guten Ergebnissen gebracht. Es geht uns eher darum, den Nearest-Neighbors-Algorithmus besser darzustellen und die Phänomene des Over- und Underfittings zu illustrieren.
Unsere Grafik mit den beiden Features siehst du in Abbildung 2-1.
Abbildung 2-1: Verteilung der Trainingsdaten für Sepal-Features
Unsere beiden Features spannen ein zweidimensionales Koordinatensystem auf. Die Punkte darin sind die einzelnen Trainingsbeispiele. Sie sind an den Stellen des Koordinatensystems angebracht, die zu ihren Features passen. Jede Farbe drückt eine Irisart aus. Diese ist quasi unsere dritte Dimension.
In derselben Grafik zeigen wir in Abbildung 2-2 nun zusätzlich an, welche Vorhersage bei welcher Koordinate gemacht wird. Dabei nutzen wir die gleichen Farben wie für die Trainingsdaten, allerdings etwas heller als Hintergrund.
Noch einmal zur Wiederholung – die Vorhersage funktioniert sehr einfach: Bei jedem Punkt wird geschaut, welche Farbe der nächstliegende Trainingspunkt hat. Es ergeben sich dabei Grenzen zwischen den einzelnen Farben der Vorhersagen, diese nennt man auch Decision Boundaries.
Abbildung 2-2: Decision Boundaries für Sepal-Features
Gerade im Zentrum der Grafik sind die Grenzen zwischen den Decision Boundaries zerklüftet und unruhig, wenig glatt und genau auf unsere Trainingsdaten angepasst. Während es für unsere Trainingsdaten gut aussieht, passen diese Grenzen nicht wirklich gut für die Testdaten, das heißt, wenn wir nur die beiden Sepal-Features nutzen, haben wir es hier mit Overfitting zu tun. Overfitting bedeutet, dass ein Modell deutlich besser auf Trainingsdaten als auf Testdaten funktioniert, also nicht gut auf unbekannte Daten generalisiert. Dieselben Decision Boundaries kannst du in Abbildung 2-3 für die Testdaten sehen.
Schau genau hin: Die Darstellung der Decision Boundaries dominiert, und so kann diese Grafik auf den ersten Blick genau so aussehen wie die vorherige. Entscheidend sind aber die Datenpunkte, die nun nicht mehr für das Training, sondern für den Test eingezeichnet sind.
Die beiden Punkte links von der Mitte passen zum Beispiel überhaupt nicht mehr zur Vorhersage, rechts von der Mitte sieht es ebenso schlecht aus. Oben passt es hingegen ganz gut. Wir werden später in Kapitel 5, Feature-Auswahl, sehen, warum manche Arten ganz gut passen und warum wir bei einer anderen Auswahl der Features plötzlich derartig schlechte Ergebnisse bekommen.
Abbildung 2-3: Unpassende Decision Boundaries für Testdaten
Nun aber hier die Ergebnisse für diese Feature-Auswahl:
clf_sepal.score(X_train_sepal_only, y_train)
> 0.9555555555555556
clf_sepal.score(X_test_sepal_only, y_test)
> 0.80000000000000004
Das passt zu unserem Eindruck aus den Grafiken: Für die Trainingsdaten sieht es nicht schlecht aus (95 % passend), aber die Testdaten liefern mit nur 80% Genauigkeit kein gutes Bild ab.
Das Bild des Overfittings verfestigt sich hier. Unser Modell ist also zu speziell und zu komplex. Es passt sich zu genau den Trainingsdaten an und ist dann nicht mehr allgemein genug für die Testdaten.
Gut, dann also ein einfacheres Modell? Erstaunlicherweise bekommen wir das hin, indem wir nicht nur die Nähe zu einem einzigen Nachbarn bei der Vorhersage in Erwägung ziehen, sondern die Nähe mehrerer. Wir probieren einmal zehn Nachbarn aus:
Abbildung 2-4 zeigt die passende Grafik für die Trainingsdaten, an der man schön die viel sanfteren Übergänge der Decision Boundaries sehen kann.
Abbildung 2-4: Glatte Decision Boundaries, aber dieses Mal sogar schwach für die Trainingsdaten
Leider kann man genauso schön sehen, dass nicht einmal die Trainingsdaten gut vorhergesagt werden können. Wir haben es jetzt also mit Underfitting zu tun. Von Underfitting spricht man, wenn ein Modell zu einfach ist und nicht einmal die Trainingsdaten annähernd reproduzieren kann.
Das bestätigen uns auch die Scores, die für Trainings- und Testdaten ähnlich schwach sind:
clf_sepal_10.score(X_train_sepal_only, y_train)
> 0.80000000000000004
clf_sepal_10.score(X_test_sepal_only, y_test)
> 0.76666666666666672
Der Sweet Spot liegt irgendwo zwischen dem zu komplexen und dem zu einfachen Modell. Wir verraten dir jetzt schon einmal: Egal wie wir unser Modell hier anpassen, wir bekommen nie gute Ergebnisse. Das liegt daran, dass dieser Satz an Features einfach nicht ausreicht, um die einzelnen Arten voneinander zu trennen. Nichts zu machen. In der Praxis ist so etwas ernüchternd. Wenn du nicht die richtigen, zu schlechte oder zu wenige Daten hast, kannst du noch so schlau sein, du wirst nie zu guten Ergebnissen kommen. Mehr dazu findest du in Kapitel 3, Datenimport und -vorbereitung, und Kapitel 5, Feature-Auswahl.
Umso erstaunlicher ist es, dass wir mit den Petal-Features sehr viel weiterkommen und fast Werte erzielen wie für alle vier Features zusammen. Wir bleiben bei zehn Nachbarn und bekommen diese Decision Boundaries, die wir in Abbildung 2-5 zuerst zusammen mit den Trainingsdaten anzeigen.
Abbildung 2-5: Petal-Features-Decision-Boundaries mit Trainingsdaten
Du kannst glatte Übergänge sehen und ebenso nur geringe Fehler bei den beiden Klassen in der Mitte und rechts. Das spiegelt sich auch in den Scores wider:
clf_petal_10.score(X_train_petal_only, y_train)
> 0.96666666666666667
Nicht perfekt, aber sehr gut, und vor allem sehr ähnliche Scores bei den Testdaten:
clf_petal_10.score(X_test_petal_only, y_test)
> 0.94999999999999996
In Abbildung 2-6 kannst du nun noch einmal dieselben Decision Boundaries sehen, dieses Mal aber mit den Testdaten. An der Decision Boundary rechts kann es keine glatte Grenze geben, die sowohl für die Trainingsdaten als auch für die Testdaten gute Ergebnisse liefert.
Abbildung 2-6: Petal-Features: Decision Boundaries mit Testdaten