EKI02 - Maschinelles Lernen: Klassifikation
Supervised Learning am "Hello World"-Beispiel Titanic: Datensatz analysieren, mit pandas laden, vorverarbeiten, einen Entscheidungsbaum (DecisionTreeClassifier) per Entropie/Entropieverlust trainieren und Vorhersagen fuer neue Faelle erzeugen.
Überblick
Dieses Kapitel fuehrt in das maschinelle Lernen (machine learning) und speziell in die Klassifikation (classification) ein. Die Folien nutzen durchgaengig ein einziges Beispiel - die Vorhersage der Ueberlebenden der Titanic aus dem Kaggle-Wettbewerb - und gehen den vollstaendigen Workflow durch: Daten analysieren, laden, vorverarbeiten, ein Modell trainieren und damit vorhersagen.
Kerndefinition der Folien:
Machine Learning = Erzeugen eines Modells, basierend auf Eingaben ("Training") und die Nutzung des Modells fuer Vorhersagen ("produktive Anwendung"). Das Modell wird also nicht explizit programmiert.
Der behandelte Ablauf (Foliengliederung "Aufbau"):
- Ueberblick
- ML Anwendungen
- Kategorien von ML Aufgaben
- Beispiel: Klassifikation der Ueberlebenden der Titanic
- Kaggle
- Analysieren von Datensaetzen
- Datensaetze laden
- Datensaetze vorverarbeiten
- ML Training
- ML Modell zur Vorhersage anwenden
- Mini-Test
Hinweis: Der Foliensatz behandelt als eigentliches Lernverfahren ausschliesslich den Entscheidungsbaum. Themen wie Confusion Matrix, Accuracy/Precision/Recall/F1, Overfitting/Underfitting, Cross-Validation sowie die Verfahren k-NN, Naive Bayes und SVM als eigenstaendige Methoden kommen im Deck nicht vor. k-NN, Naive Bayes und SVM tauchen nur als Namen in zwei uebernommenen Uebersichtsgrafiken auf (KI-Landkarte, scikit-learn Cheat Sheet). Dieses Kapitel bleibt bewusst auf den Folieninhalt beschraenkt.
Die KI-Landkarte
Zur Einordnung zeigen die Folien eine "KI-Landkarte" (Quelle: B. Humm, "Applied Artificial Intelligence"). Sie unterscheidet zwei Achsen - Acquiring intelligence (Intelligenz erwerben) und Applying intelligence (Intelligenz anwenden) - und zwei grosse Bloecke:
- Non-symbolic AI / Machine learning (nicht-symbolische KI)
- Symbolic AI / Knowledge-based AI (symbolische, wissensbasierte KI)
Die faehigkeitsbezogenen Felder sind: Perceiving (Computer vision, Sensor technology), Communicating (Natural language processing), Reasoning (Logic programming, Probabilistic reasoning, Complex event processing), Acting (Planning, Agent technology, Robotics), Learning (Machine learning, Information retrieval, Data mining) und Knowing (Knowledge representation).
Dem Bereich Learning / Machine Learning sind auf der Grafik u.a. zugeordnet: Artificial neural networks, Support vector machines, Linear/logistic regression, Random forest, Gradient boosting tree, K-Nearest neighbors, K-means, Naive Bayes. Dem symbolischen Teil u.a.: Bayes networks, Hidden Markov models, Decision tree learning, Inductive logic programming.
Hinweis: Diese Verfahrensnamen dienen in EKI02 nur der Landkarten-Uebersicht. Pruefungsrelevant als Verfahren ist aus diesem Deck nur der Entscheidungsbaum.
Was ist Machine Learning?
Zwei Phasen bestimmen jedes ML-Vorhaben:
- Training: Aus Eingabedaten wird ein Modell erzeugt ("Fitting").
- Produktive Anwendung: Das trainierte Modell macht Vorhersagen fuer neue, bisher unbekannte Daten.
Der zentrale Punkt: Das Modell wird gelernt, nicht von Hand programmiert.
ML Anwendungen
Die Folien nennen zwei anschauliche Anwendungsfaelle:
| Anwendung | Aufgabe | ML-Kategorie |
|---|---|---|
| Spam Filtering | Klassifiziere neue E-Mails danach, ob sie Spam oder nicht Spam sind | Klassifikation |
| Wertpapierhandel | Mache Empfehlungen, welche Aktien gekauft bzw. verkauft werden sollen | (Prediction -> Recommendation) |
Beim Spam-Filter zeigt die Folie einen Rueckkopplungskreislauf: manuell klassifizierte Beispiele dienen als Training input, neue E-Mails werden automatisch klassifiziert (Not spam / Spam), und Nutzerkorrekturen (Corrections) fliessen wieder als Trainingsdaten zurueck.
flowchart LR
A["Manually classified samples"] -->|"Training input"| B["Spam filter"]
C["New emails"] --> B
B --> D["Not spam"]
B --> E["Spam"]
D --> F["User"]
E --> F
F -->|"Corrections"| A
Kategorien von ML Aufgaben
Die Folien gliedern ML in drei Bereiche (Area) mit zugehoerigen Aufgaben (Task):
flowchart TD
ML["Machine Learning"] --> SL["Supervised Learning"]
ML --> UL["Unsupervised Learning"]
ML --> RL["Reinforcement Learning"]
SL --> C["Classification"]
SL --> R["Regression"]
UL --> CL["Clustering"]
UL --> FS["Feature selection / extraction"]
UL --> TM["Topic modeling"]
Der Fokus des Kapitels liegt auf Supervised Learning (ueberwachtes Lernen) mit den Aufgaben Klassifikation und Regression.
Aufgaben des Supervised Learning
Klassifikation (classification)
- Gegeben: Datensaetze als Eingabe fuer das Training, welche in zwei oder mehrere Klassen ("Kategorien") eingeteilt sind.
- Ziel: Ein Modell erzeugen, welches neue, bisher unbekannte Datensaetze klassifizieren kann.
- Beispiele: Spam-Filter, Fraud-Detection, ...
Regression (regression)
- Gegeben: Datensaetze als Eingabe fuer das Training, welche einen numerischen Ausgabewert besitzen.
- Ziel: Ein Modell erzeugen, welches fuer neue, bisher unbekannte Datensaetze den Ausgabewert vorhersagen kann.
- Beispiel: Aktienkurs-Vorhersage
Der Unterschied: Klassifikation sagt eine Kategorie voraus, Regression einen numerischen Wert.
Beispiel: Klassifikation der Ueberlebenden der Titanic
- "Hello World"-Beispiel fuer ML, viele Tutorials online verfuegbar (z.B. das Kaggle-Titanic-Tutorial).
- Eingabe: Informationen ("Features") ueber die Passagiere, z.B. Alter, Geschlecht, ...
- Ausgabe: Klassifikation nach zwei Kategorien: Ueberlebt bzw. Gestorben (binaere Klassifikation).
Die Aufgabenstellung lautet: "What sorts of people were more likely to survive?" - anhand von Passagierdaten (Name, Alter, Geschlecht, sozio-oekonomische Klasse etc.).
Die Folie stellt auch die kritische Frage: Was gefaellt mir nicht an dem Titanic-Beispiel? - "Es ist kein realistisches ML-Beispiel, aber warum?" Dies bleibt in den Folien als Denkanstoss offen (keine ausformulierte Antwort im Deck).
Kaggle
Kaggle ist eine Community-Plattform mit Datensaetzen, Wettbewerben etc. Fuer den Titanic-Wettbewerb laedt man von Kaggle herunter:
- train.csv - Trainingsdaten (mit bekanntem Label
Survived) - test.csv - Testdaten (ohne Label; die Vorhersagen dafuer werden eingereicht)
- Format fuer die Wettbewerbs-Einreichung
Ablauf: Loesung als CSV einreichen, Position im Leaderboard pruefen.
Hinweis: Die Kaggle-
test.csvist der Einreichungs-Datensatz ohne Labels, nicht ein lokal beschrifteter Hold-out-Testsatz. Eine lokale Guetemessung (z.B. Accuracy auf einem beschrifteten Testsatz, Train/Validation/Test-Split, Kreuzvalidierung) wird im Deck nicht gezeigt; die Bewertung erfolgt extern ueber das Kaggle-Leaderboard.
Analysieren von Datensaetzen
Vor jeder Verarbeitung muss man den Datensatz verstehen. Die Attribute des Titanic-Datensatzes:
| Spalte | Rolle | Bedeutung |
|---|---|---|
| PassengerId | (nicht benutzt) | Eindeutige Passagier-ID, nicht fuer die Klassifikation |
| Survived | Label (ML Ausgabe) | Ziel der Klassifikation: 0 = Gestorben, 1 = Ueberlebt |
| Pclass | Feature | Passagierklasse: 1 = Erste Klasse, 3 = Dritte Klasse |
| Name | Feature | Name |
| Sex | Feature | Geschlecht |
| Age | Feature | Alter in Jahren |
| SibSp | Feature | Anzahl siblings + spouse (Geschwister + Ehepartner) |
| Parch | Feature | Anzahl Eltern + Kinder |
| Ticket | Feature | Ticketnummer |
| Fare | Feature | Fahrpreis |
| Cabin | Feature | Kabine |
| Embarked | Feature | Einstiegshafen: C = Cherbourg, S = Southampton, Q = Queenstown; NaN = fehlende Werte |
Beispielzeilen aus dem Datensatz (Folie 2.19):
| PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 690 | 1 | 1 | Madill, Miss. Georgette Alexandra | female | 15.0 | 0 | 1 | 24160 | 211.3375 | B5 | S |
| 526 | 0 | 3 | Farrell, Mr. James | male | 40.5 | 0 | 0 | 367232 | 7.7500 | NaN | Q |
| 279 | 0 | 3 | Rice, Master. Eric | male | 7.0 | 4 | 1 | 382652 | 29.1250 | NaN | Q |
Datentypen und fehlende Werte
| Spalte | Kategorie | Datentyp | Fehlende Daten? |
|---|---|---|---|
| Survived | Kategorisch, binaer | int | nein |
| Pclass | Kategorisch, ordinal | int | nein |
| Name | Text | string | nein |
| Sex | Kategorisch | string | nein |
| Age | Numerisch | float | ja |
| SibSp | Numerisch | int | nein |
| Parch | Numerisch | int | nein |
| Ticket | Text | int | nein |
| Fare | Numerisch | float | ja |
| Cabin | Text | string | ja |
| Embarked | Kategorisch | string | ja |
Hinweis: In der Folientabelle ist
Ticketals Kategorie "Text" gefuehrt, der Datentyp aber alsint. Das ist inkonsistent (Ticketnummern koennen auch nicht-numerische Zeichen enthalten); die Folie ist hier so uebernommen, ohne stille Korrektur.
Warum die Analyse wichtig ist: Man erkennt, welche Spalten Features und welche das Label sind, welche Datentypen vorliegen (kategorisch/numerisch/Text) und wo fehlende Werte (NaN) auftreten - genau diese muessen spaeter vorverarbeitet werden.
Datensaetze laden
Genutzt wird das Datenanalyse-Paket pandas (Installation z.B. pip install pandas). Die primaere Datenstruktur ist der pd.DataFrame - eine zweidimensionale, beschriftete Tabelle (Zeilen und Spalten).
CSV-Dateien einlesen:
import pandas as pd
train_data = pd.read_csv('data/train.csv')
test_data = pd.read_csv('data/test.csv')
pd.read_csv liest eine CSV-Datei (relativer Pfad zum Notebook) in einen pd.DataFrame. Es gibt viele optionale Parameter, z.B. encoding, delimiter, quotechar.
Datensaetze vorverarbeiten
Relevante Spalten extrahieren
# Labels extrahieren
y = train_data["Survived"]
# Relevante Spalten (features) extrahieren (wird spaeter vielleicht erweitert)
features = ["Pclass", "Sex", "SibSp", "Parch"]
X = train_data[features]
Regel fuer den Zugriff: Ein Spaltenname -> Vektor, Liste von Spaltennamen -> Matrix.
Namenskonventionen aus der Mathematik (in den Folien betont):
- Matrix: Grossbuchstaben, z.B.
X - Vektor: Kleinbuchstaben, z.B.
y - Input:
x(oderX), Output:y(oderY)
Fehlende Werte auffuellen
# Fehlende Werte (n/a values) mit einem bestimmten Wert auffuellen
data['Embarked'] = data['Embarked'].fillna('S')
# Fehlende Werte mit dem Mittelwert aller Werte auffuellen
import numpy as np
from sklearn.impute import SimpleImputer
imp = SimpleImputer(missing_values=np.nan, strategy='mean')
data['Age'] = imp.fit_transform(data[['Age']])
Wichtige Details der Folien:
DataFrame.fillnaliefert einen modifizierten DataFrame zurueck (der Original-DataFrame wird nicht veraendert). Daher die Zuweisung, um ihn zu ueberschreiben.SimpleImputer(aus scikit-learn) kennt verschiedene Strategien, um fehlende Werte aufzufuellen; hierstrategy='mean'(Mittelwert).
Genutzte Hilfspakete: NumPy (Scientific Computing) und scikit-learn (ML). Als weitere Vorverarbeitungs-Idee wirft die Folie die offene Frage auf "Weitere Ideen fuer die Vorverarbeitung der Daten?" (ohne festgelegte Antwort im Deck).
ML Training
Der in den Folien ausgewaehlte Ansatz ist der DecisionTreeClassifier aus scikit-learn.
# ML Modell erzeugen
model = DecisionTreeClassifier()
# ML Modell trainieren
model.fit(X, y)
Das Trainieren ("fitting") des Modells erfolgt mit den Features (X) und den Labels (y).
Lernen mit einem Entscheidungsbaum
Ein Entscheidungsbaum (decision tree) ist ein Baum mit den Klassen als Blaettern (hier: ueberlebt, gestorben). Die Entscheidungen stehen in den inneren Knoten (z.B. "maennlich?") und die Werte an den Kanten des Baums (z.B. Ja, Nein).
Der Lernvorgang: automatisch einen Entscheidungsbaum aus den Trainingsdaten (Features und Labels) aufbauen.
Beispielbaum fuer die Titanic-Klassifikation (Folie 2.35, nachgezeichnet; Blattwerte = vorhergesagte Ueberlebenswahrscheinlichkeit und Anteil der Faelle):
flowchart TD
A["is sex male?"] -->|"yes"| B["is age > 9.5?"]
A -->|"no"| C["survived (0.73, 36%)"]
B -->|"yes"| D["died (0.17, 61%)"]
B -->|"no"| E["is sibsp > 2.5?"]
E -->|"yes"| F["died (0.05, 2%)"]
E -->|"no"| G["survived (0.89, 2%)"]
Entropie
Zum Bewerten, wie "gemischt" eine Datenmenge bezueglich der Klassen ist, wird die Entropie verwendet. Sie ist maximal bei ausgeglichener Klassenverteilung (50/50) und minimal (0), wenn alle Elemente derselben Klasse angehoeren.
Dabei sind die relativen Anteile der einzelnen Klassen in der Menge .
Worked Example aus der Folie (Menge mit 3 Elementen der einen und 7 der anderen Klasse, also 10 insgesamt):
Entropieverlust (Information Gain)
Beim Aufbau waehlt man an jedem Knoten ein Feature und einen Wert, so dass ein moeglichst grosser Entropieverlust entsteht. Ein Split "Feature < Wert" teilt die Menge in (Bedingung erfuellt) und (Bedingung nicht erfuellt).
Das ist der gewichtete Entropieverlust: die Ausgangsentropie minus die mit den Teilmengengroessen gewichteten Entropien der beiden Teilmengen.
Worked Example: bester Split (Folien 2.38 - 2.43)
Ausgangsmenge: 20 Datensaetze (IDs 1-20) mit Features f1-f5 und Label A/B. Die Ausgangsentropie betraegt (Verteilung 11x A, 9x B).
Fuer jedes Feature wird ein Schwellwert getestet und der Entropieverlust berechnet:
| Split | Entropieverlust | ||||
|---|---|---|---|---|---|
| f1 < 404.3 | 10 | 0.721 | 10 | 0.881 | 0.191 |
| f2 < 34.7 | 15 | 0.97 | 5 | 0.0 | 0.264 |
| f3 < 0.92 | 17 | 0.997 | 3 | 0.0 | 0.144 |
| f4 < 809.1 | 14 | 0.94 | 6 | 0.0 | 0.334 |
| f5 < 61.9 | 2 | 0.0 | 18 | 0.964 | 0.125 |
Beispielrechnung fuer den Gewinner f4 < 809.1:
Der groesste Entropieverlust (0,334) gehoert zu f4 < 809.1 - dieses Feature/Wert-Paar wird als erster Split gewaehlt.
Zwischenergebnis
Nach dem ersten Split (Folie 2.43):
flowchart TD
T["T: H(T) = 0.992"] --> Q["f4 < 809.1 ?"]
Q -->|"Ja"| L["T_lower: H = 0.94 (weiter aufteilen)"]
Q -->|"Nein"| R["A (Blatt, H = 0)"]
Der Zweig "Nein" (, 6 Faelle) hat Entropie 0 - alle Labels sind A, also wird er zum Blatt "A". Der Zweig "Ja" (, 14 Faelle) hat noch und wird rekursiv nach demselben Verfahren weiter aufgeteilt.
Hinweis: Auf Folie 2.38 wird in der Summenformel einmal mit kleinem
tgeschrieben, waehrend sonst durchgehend mit grossemTverwendet wird. Gemeint ist dieselbe Groesse; es handelt sich um einen reinen Schreibfehler in der Folie.
Ideen fuer weitere ML Ansaetze
Als Ausblick verweisen die Folien auf das scikit-learn algorithm cheat sheet - eine Entscheidungshilfe zur Auswahl eines Verfahrens je nach Datenlage. Fuer den Zweig classification nennt es u.a. SVC, Ensemble Classifiers, KNeighbors Classifier, SGD Classifier, Naive Bayes und Linear SVC; daneben stehen Zweige fuer regression, clustering und dimensionality reduction.
Hinweis: Diese Verfahren werden im Deck nicht erklaert, sondern nur als moegliche Alternativen zum Entscheidungsbaum genannt.
ML Modell zur Vorhersage anwenden
Das trainierte Modell sagt die Labels aller Faelle im Testdatensatz voraus:
# Labels fuer den Testdatensatz vorhersagen
predictions = model.predict(X_test)
Wichtig (Folie): Der Testdatensatz muss genau so wie der Trainingsdatensatz vorverarbeitet worden sein (gleiche Spaltenauswahl, gleiches Auffuellen fehlender Werte etc.).
Einreichung bei Kaggle erzeugen
Kaggle erwartet eine CSV mit den zwei Spalten PassengerId und Survived:
# Erzeugen der CSV-Datei mit den Vorhersagen des Modells
output = pd.DataFrame({'PassengerId': test_data.PassengerId, 'Survived': predictions})
output.to_csv('data/submission.csv', index=False)
Anschliessend wird die Datei im Kaggle-Wettbewerb eingereicht und die eigene Position im Leaderboard geprueft.
scikit-learn Workflow (Zusammenfassung)
Der komplette Ablauf des Titanic-Beispiels in der Reihenfolge der Folien:
flowchart TD
A["train.csv / test.csv laden (pd.read_csv)"] --> B["Analysieren: Features, Label, Datentypen, NaN"]
B --> C["Vorverarbeiten: Spalten waehlen, fehlende Werte auffuellen"]
C --> D["Modell erzeugen: DecisionTreeClassifier()"]
D --> E["Trainieren: model.fit(X, y)"]
E --> F["Vorhersagen: model.predict(X_test)"]
F --> G["submission.csv schreiben und bei Kaggle einreichen"]
Prüfungsrelevanz
- ML-Definition: Modell aus Eingaben erzeugen (Training) + fuer Vorhersagen nutzen (produktive Anwendung); das Modell wird nicht explizit programmiert.
- ML-Kategorien: Supervised, Unsupervised, Reinforcement Learning (Bereiche); Supervised -> Klassifikation + Regression (Aufgaben).
- Klassifikation vs. Regression: Kategorie vorhersagen vs. numerischen Wert vorhersagen.
- Titanic: binaere Klassifikation (Survived 0/1); Features = Passagierinfos; PassengerId ist kein Feature.
- Features vs. Label: Features = ML-Eingabe (X, Matrix), Label = ML-Ausgabe (y, Vektor); mathematische Namenskonventionen kennen.
- Vorverarbeitung: Warum wichtig;
fillna(fester Wert) undSimpleImputer(strategy='mean')(Mittelwert); Testdaten identisch zu Trainingsdaten vorverarbeiten. - Entscheidungsbaum: Klassen = Blaetter, Entscheidungen = innere Knoten, Werte = Kanten; automatischer Aufbau aus Trainingsdaten.
- Entropie: ; maximal bei 50/50, 0 bei reiner Klasse; Rechnung nachvollziehen koennen.
- Entropieverlust / Information Gain: ; Split mit groesstem Verlust waehlen (im Beispiel
f4 < 809.1mit 0,334). - scikit-learn Workflow:
read_csv-> vorverarbeiten ->DecisionTreeClassifier()->fit(X, y)->predict(X_test)->to_csv. - Kaggle: Community mit Datensaetzen/Wettbewerben; train/test-Dateien, submission.csv, Leaderboard.
Nicht im Deck (daher nicht pruefungsrelevant aus EKI02): Confusion Matrix, Accuracy/Precision/Recall/F1, Overfitting/Underfitting, Cross-Validation, sowie k-NN/Naive Bayes/SVM als erklaerte Verfahren. Falls diese in der Klausur vorkommen, stammen sie aus anderen Kapiteln.
Mini-Test
Die folgenden Fragen stammen wortwoertlich aus der Mini-Test-Folie ("Mini-Test 'ML Klassifikation'", Folie 2.52):
- Was ist ML?
- Wann soll man ML benutzen, wann nicht?
- Nennen Sie ML Anwendungen
- Erklaeren Sie die ML Kategorie "Supervised Learning"
- Erklaeren Sie die ML Aufgabe Klassifikation
- Was ist Kaggle?
- Warum ist es wichtig, einen Datensatz zu analysieren?
- Warum ist die Vorverarbeitung wichtig? Nennen Sie hierzu Beispiele
- Was ist ML Training?
- Wie baut man einen Entscheidungsbaum auf?
- Wie sagt man neue Faelle vor?