Machine Learning von Grund auf · Lektion 4.4 · 23 von 33 fertigen Lektionen · 12 Min.
Feature Engineering
Kurz gesagt
Rebsorte 2 liegt mitten auf der Achse, keine Schwelle trennt sie ab. Eine Spalte x² bringt 77,4% statt 60,4%; 200 Rauschspalten drücken kNN auf 77,4%.
Aufwärmen Zwei Fragen aus früheren Lektionen. Eine Minute, und sie blockiert die Lektion nicht.
In Lektion 4.3 haben wir geändert, wie Merkmale geschrieben werden: die Skala der Zahlen und den Code der Kategorien. Heute machen wir aus vorhandenen Merkmalen neue. Feature Engineering heißt, Spalten hinzuzufügen, die dem Modell deutlicher zeigen, wonach es sucht: ein Quadrat, einen Quotienten, eine Differenz, die Zahl der Tage seit einem Ereignis. Ein gutes Merkmal kann aus einem schweren Problem ein leichtes machen. Viele schwache können ein Modell verderben, das funktioniert hat.
Wähle eine Antwort und wie sicher du bist.
Antworte, um das Labor freizuschalten.
Interaktives Labor
Dieses interaktive Labor läuft im Browser mit aktiviertem JavaScript. Der Text drumherum beschreibt, was es zeigt.
Antwort anzeigen
Richtige Antwort: Nein, weil Rebsorte 2 in der Mitte liegt und auf beiden Seiten Weine anderer Rebsorten hat
Nein. In der Mitte der Achse lässt eine Schwelle immer eine der beiden anderen Rebsorten auf der Seite „Rebsorte 2“. Die beste Schwelle auf den Trainingsweinen trifft 61,6%, kaum mehr als 60,0% dafür, bei jedem Wein „eine andere Rebsorte“ zu sagen, und bei den Testweinen genau gleich viel: 60,4%. Die lineare SVM im Lab sagt Rebsorte 2 nirgends vorher. Erst eine neue Spalte x² lässt es das mittlere Intervall herausschneiden.
Probier es aus
- Fang mit x allein an. Wo sagt das Modell Rebsorte 2 vorher? Wie hoch ist die Testgenauigkeit, und woher kommt sie?
- Füge die Spalte x² hinzu. Wie sieht die Grenze in der Ebene (x, x²) aus, und wie auf der Flavonoidachse allein?
- Wechsle zum Rauschen. Schiebe den Regler von 200 Spalten nach unten. Wann erkennt kNN die zurückgelegten Weine am besten?
- Achte auf den Distanzkontrast. Was passiert mit dem Abstand zwischen dem nächsten und dem fernsten Wein, wenn sich Spalten häufen?
Wenn du es im Lab geprüft hast, geben wir dem, was du siehst, einen Namen.
Die Idee in einfachen Worten
Ein lineares Modell auf einer Achse kann nur eines: eine Schwelle setzen. Rebsorte 2 liegt in der Mitte der Flavonoidachse, also kann eine Schwelle sie von keiner Seite herausschneiden: Sie trennt höchstens eine der benachbarten Rebsorten ab. Die beste solche Schwelle trennt Rebsorte 3 ab und trifft im Training 61,6%, während „eine andere Rebsorte“ bei jedem Wein 60,0% trifft. Der Gewinn ist winzig, und im Test verschwindet er. Die lineare SVM im Lab sagt Rebsorte 2 nirgends vorher und kommt auf 60,4%, den Anteil der anderen Rebsorten unter den 53 Testweinen. Fügen wir die Spalte x² hinzu, das Quadrat der standardisierten Flavonoide. Weine von beiden Enden der Achse haben ein großes x², Weine aus der Mitte ein kleines. Dasselbe lineare Modell legt jetzt eine Gerade in die Ebene (x, x²). Auf der Flavonoidachse sind das zwei Schwellen, ein Intervall von 1,11 bis 2,82. Die Genauigkeit steigt auf 77,4%. Das Modell hat sich nicht geändert, nur das, was es bekommt.
Mehr Merkmale heißt aber nicht besser. kNN (k = 5) erkennt mit 13 chemischen Messungen 98,1% der zurückgelegten Weine. Wir fügen Spalten aus reinem Rauschen hinzu, Zufallszahlen in derselben Skala. Mit 200 solchen Spalten fällt die Genauigkeit auf 77,4%. Jede Rauschspalte trägt so viel zur Distanz bei wie eine echte Messung, also sind die „nächsten“ Weine nicht mehr ähnlich. Das ist der Fluch der Dimensionalität: In vielen Dimensionen liegen alle Punkte fast gleich weit voneinander entfernt.
Jak to policzono
- Weine: Wine (Aeberhard und Forina, 1992; UCI, Lizenz CC BY 4.0), 178 Weine, 13 chemische Messungen, 3 Rebsorten. Geschichtete Aufteilung: 125 Weine zum Lernen, 53 zum Testen.
- Neues Merkmal: ein lineares Modell (eine lineare Support-Vector-Maschine, C = 1) auf den standardisierten Flavonoiden, Rebsorte 2 gegen den Rest. Mittlere Flavonoide über alle 178 Weine berechnet.
- Rauschen: kNN mit k = 5 auf den 13 standardisierten Messungen und 0 bis 200 Spalten mit Zahlen aus einer Normalverteilung (Mittelwert 0, Standardabweichung 1), mit festem Startwert gezogen.
Warum das funktioniert
Ein lineares Modell teilt den Raum mit einer Geraden (in höheren Dimensionen mit einer Ebene). Auf einer Achse ist eine Gerade ein Punkt, eine Schwelle. Die Spalte x² fügt eine zweite Achse hinzu. Weine von beiden Enden der Flavonoidachse landen hoch auf der Parabel, Weine aus der Mitte tief. Jetzt kann eine Gerade Rebsorte 2 von oben abschneiden. Bei 20 anderen Aufteilungen der Weine sagt die lineare SVM ohne x² kein einziges Mal Rebsorte 2 vorher, und die beste einzelne Schwelle aus dem Training schlägt „immer andere“ im Test nur in 1 von 20. Mit x² schneidet es immer ein Intervall heraus: im Test von 67,9 bis 84,9%.
Beim Rauschen ist es umgekehrt. Die Distanz in kNN ist eine Summe quadrierter Differenzen über alle Spalten. Mit 13 Messungen liegt der fernste Trainingswein im Mittel 296,5% weiter weg als der nächste. Mit 200 Rauschspalten nur noch 25,7%. Die Differenzen im Rauschen sind zufällig, und es gibt viele davon, also überdecken sie die 13 echten Differenzen. Über 20 Ziehungen des Rauschens geben 200 Spalten von 64,2 bis 83,0%, immer weniger als 98,1% ohne Rauschen.
Ein häufiger Fehler
Wahr oder falsch: „Mehr Merkmale ergeben ein besseres Modell.“ Falsch. Ein Merkmal hilft, wenn es Information in einer Form trägt, die das Modell nutzen kann, wie x² für Rebsorte 2. Spalten ohne Information schaden: 200 Rauschspalten drücken kNN von 98,1% auf 77,4%. Im Code unten fällt die Genauigkeit von kNN von 0,962 ohne Rauschen auf 0,689 mit 200 Spalten.
Ein gutes neues Merkmal entsteht meist aus dem Verständnis des Problems: was zählen sollte und in welcher Form. Alles hineinzuwerfen, was geht, ist eine Einladung an das Rauschen.
Quiz
Drei Fragen zur Selbstkontrolle. Wähle eine Antwort oder klappe die Lösung unter der Frage auf. Mit der Tastatur: Pfeiltasten wählen, Enter oder Leertaste bestätigt.
Das Wichtigste
- Ein Merkmal in guter Form macht aus einem schweren Problem ein leichtes: x² hebt die Genauigkeit von 60,4% auf 77,4%.
- Ein lineares Modell mit neuen Spalten bleibt linear; es ändert sich nur, was es als Eingabe bekommt.
- Spalten ohne Information schaden: 200 Rauschspalten drücken kNN von 98,1% auf 77,4%.
- In vielen Dimensionen gleichen sich Distanzen an, also verlieren distanzbasierte Modelle am meisten.
Tiefer: Formel, Code, Praxis
Die Mathematik
Das neue Merkmal: z = (x − x̄) / s, und das lineare Modell bekommt (z, z²). Die Grenze w₁ · z + w₂ · z² + b = 0 ist eine quadratische Gleichung in z, hat also bis zu zwei Nullstellen: zwei Schwellen auf der x-Achse und ein Intervall dazwischen.
Die Distanz in kNN: d(a, b)² = Σⱼ (aⱼ − bⱼ)² über alle Spalten. Bei m Rauschspalten aus N(0, 1) trägt jede im Mittel 2 zu d² bei (die Varianz der Differenz zweier unabhängiger Zahlen), unabhängig von der Rebsorte. Bei großem m überdeckt die Rauschsumme die 13 echten Terme, und der Kontrast (d_max − d_min) / d_min schrumpft.
Im Code (Python)
Dasselbe Experiment in scikit-learn: ein lineares Modell auf den Flavonoiden ohne und mit x² in einer Kreuzvalidierung 10 × 5, dann kNN auf den 13 Messungen und einer wachsenden Zahl von Rauschspalten.
import numpy as np
from sklearn.datasets import load_wine
from sklearn.model_selection import cross_val_score, RepeatedStratifiedKFold
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler, PolynomialFeatures
from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier
wine = load_wine(as_frame=True)
x, is2 = wine.data[["flavanoids"]], (wine.target == 1).astype(int)
cv = RepeatedStratifiedKFold(n_splits=5, n_repeats=10, random_state=0)
line = make_pipeline(StandardScaler(), SVC(kernel="linear", C=1))
squared = make_pipeline(StandardScaler(), PolynomialFeatures(2, include_bias=False), StandardScaler(), SVC(kernel="linear", C=1)) # die neue Spalte x²
a, b = cross_val_score(line, x, is2, cv=cv), cross_val_score(squared, x, is2, cv=cv)
print(f"cultivar 2 vs the rest from flavanoids, 10 x 5 CV: x only {a.mean():.3f}, x and x^2 {b.mean():.3f}; always 'other' {1 - is2.mean():.3f}")
print(f"x only predicts cultivar 2 for {line.fit(x, is2).predict(x).sum()} of {len(x)} wines; x and x^2 wins in {(b > a).sum()} of 50 folds")
X, y = wine.data.to_numpy(), wine.target.to_numpy()
noise = np.random.default_rng(0).normal(size=(len(X), 200)) # Spalten aus reinem Rauschen
for m in [0, 10, 50, 200]:
acc = cross_val_score(make_pipeline(StandardScaler(), KNeighborsClassifier(5)), np.hstack([X, noise[:, :m]]), y, cv=cv)
print(f"kNN on 13 measurements + {m} noise columns: {acc.mean():.3f}")
Ausgabe
cultivar 2 vs the rest from flavanoids, 10 x 5 CV: x only 0.601, x and x^2 0.755; always 'other' 0.601
x only predicts cultivar 2 for 0 of 178 wines; x and x^2 wins in 49 of 50 folds
kNN on 13 measurements + 0 noise columns: 0.962
kNN on 13 measurements + 10 noise columns: 0.940
kNN on 13 measurements + 50 noise columns: 0.842
kNN on 13 measurements + 200 noise columns: 0.689
Die Aufteilungen und das Rauschen sind andere als im Lab, also sind auch die Zahlen etwas anders. Das Bild ist dasselbe: Ohne x² sagt das Modell kein einziges Mal Rebsorte 2 vorher (0,601, so viel wie „immer eine andere“), mit x² kommt es auf 0,755 und gewinnt in 49 von 50 Validierungsteilen. Das Rauschen drückt kNN von 0,962 auf 0,689.
Notebook herunterladen (.ipynb). Öffne es in Jupyter oder lade es in Google Colab hoch; fehlende Daten lädt es selbst.
Für die Praxis
- In scikit-learn:
PolynomialFeatures(2)fügt Quadrate und Produkte von Merkmalspaaren hinzu,SplineTransformerglatte Kurven,FunctionTransformer(np.log1p)einen Logarithmus für Merkmale mit langem Schwanz. Stecke sie inmake_pipeline, damit die Kreuzvalidierung den ganzen Weg sieht. - Die besten Merkmale kommen aus dem Wissen über das Problem: ein Quotient (Preis pro Quadratmeter), eine Differenz (Tage seit dem letzten Kauf), ein Teil des Datums (Wochentag). Das Modell erfindet sie nicht, wenn es die rohen Zutaten nicht in guter Form bekommt.
- Bei vielen Merkmalen wähle sie in jeder Aufteilung getrennt aus (
SelectKBestin der Pipeline) oder nimm ein Modell mit Regularisierung (Lektion 3.4). Merkmale auf allen Daten vor der Validierung auszuwählen, ist ein Leck (Lektion 4.5). - Die Kernmethoden, die du bei den Support-Vector-Maschinen kennenlernst, rechnen das Ergebnis so, als hätten sie solche Spalten hinzugefügt, aber ohne sie ausdrücklich zu bauen.
War das hilfreich?
Danke! Das hilft uns, besser zu werden.
Mehr im Atlas
Einträge der Enzyklopädie zu den Ideen dieser Lektion: