Sie haben Ihr erstes Modell für maschinelles Lernen trainiert. Es schneidet bei Ihren Trainingsdaten hervorragend ab – 98 % Genauigkeit! Sie testen es anhand neuer Daten und es fällt auseinander: 61 % Genauigkeit. Was ist schief gelaufen?
Mit ziemlicher Sicherheit weist Ihr Modell eine Überanpassung auf. Dies ist einer der beiden häufigsten Fehlermodi beim maschinellen Lernen, und sein Verständnis – neben seinem Gegenteil, der Unteranpassung – ist für die Erstellung von Modellen, die tatsächlich in der realen Welt funktionieren, von entscheidender Bedeutung.
Bevor wir uns mit Beispielen befassen, ist es hilfreich, den theoretischen Rahmen hinter diesen Konzepten zu verstehen: den Bias-Varianz-Kompromiss.
Jedes Modell macht Vorhersagefehler. Diese Fehler können in drei Teile zerlegt werden:
Total Error = Bias² + Variance + Irreducible Noise
Bias ist der Fehler aufgrund falscher Annahmen im Modell. Ein Modell mit hoher Verzerrung ist zu einfach – es verfehlt systematisch das wahre Muster in den Daten.
Varianz ist der Fehler der Empfindlichkeit gegenüber kleinen Schwankungen in den Trainingsdaten. Ein Modell mit hoher Varianz ist zu komplex – es merkt sich die Trainingsdaten, einschließlich ihres Rauschens, anstatt das zugrunde liegende Muster zu lernen.
Irreduzibles Rauschen ist die natürliche Zufälligkeit in den Daten, die kein Modell beseitigen kann.
Der Kompromiss: Eine Verringerung der Voreingenommenheit führt tendenziell zu einer Erhöhung der Varianz und umgekehrt. Ihre Aufgabe als Praktiker des maschinellen Lernens ist es, den Sweet Spot zu finden.
Eine Unteranpassung tritt auf, wenn Ihr Modell zu einfach ist, um das wahre Muster in den Daten zu erfassen. Die Leistung ist sowohl bei Trainingsdaten als auch bei neuen Daten schlecht.
Stellen Sie sich vor, Sie verfügen über Daten, die die Immobilienpreise nach Größe zeigen. Die wahre Beziehung ist ungefähr eine sanfte Kurve – die Preise steigen mit der Größe, am oberen Ende gibt es jedoch ein gewisses Plateau.
Wenn Sie eine gerade horizontale Linie an diese Daten anpassen:
# Underfitting: overly simple model
from sklearn.linear_model import LinearRegression
import numpy as np
# True relationship is quadratic, but we're fitting a simple mean
model = DummyRegressor(strategy='mean')
model.fit(X_train, y_train)
# Training accuracy: 55%
# Test accuracy: 54%
# Both are bad — classic underfitting
Anmelden an der Diskussion teilnehmen
Das Modell ignoriert den tatsächlichen Zusammenhang zwischen Hausgröße und Preis. Es spielt keine Rolle, ob Sie Trainingsdaten oder neue Daten anzeigen – es ist in jedem Fall falsch.
Überanpassung tritt auf, wenn Ihr Modell die Trainingsdaten zu gut lernt – einschließlich ihres Rauschens und der zufälligen Variation – und es nicht schafft, sie auf neue Beispiele zu verallgemeinern.
Verwenden eines 15-Grad-Polynoms zur Anpassung derselben Hauspreisdaten:
# Overfitting: overly complex model
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
# Degree-15 polynomial — wildly complex for this problem
model = make_pipeline(PolynomialFeatures(15), LinearRegression())
model.fit(X_train, y_train)
train_score = model.score(X_train, y_train) # 0.99 — looks amazing!
test_score = model.score(X_test, y_test) # 0.43 — terrible on new data
Das Polynom hat sich zu Knoten verdreht, um jeden Trainingspunkt zu durchlaufen – einschließlich der verrauschten Ausreißer. Es hat sich den Trainingssatz gemerkt, anstatt das zugrunde liegende Muster zu lernen. Bei unsichtbaren Daten ist es nutzlos.
Ein grundlegendes Werkzeug zum Erkennen einer Überanpassung ist die Aufteilung Ihrer Daten in drei Sätze:
from sklearn.model_selection import train_test_split
# First split: hold out 20% as the final test set
X_train_val, X_test, y_train_val, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Second split: hold out 20% of remaining as validation set
X_train, X_val, y_train, y_val = train_test_split(
X_train_val, y_train_val, test_size=0.25, random_state=42
)
# Result: 60% train / 20% validation / 20% test
Das Validierungsset ist Ihr Frühwarnsystem. Wenn sich die Trainingsgenauigkeit weiter verbessert, die Validierungsgenauigkeit jedoch ein Plateau erreicht oder abnimmt, liegt eine Überanpassung vor.
Die Regularisierung fügt der Verlustfunktion einen Nachteil hinzu, der das Modell davon abhält, übermäßig komplexe Muster zu lernen.
L2-Regularisierung (Ridge) bestraft große Gewichte:
from sklearn.linear_model import Ridge
model = Ridge(alpha=1.0) # alpha controls regularisation strength
model.fit(X_train, y_train)
L1-Regularisierung (Lasso) kann einige Gewichte bis auf Null bringen und eine Funktionsauswahl durchführen:
from sklearn.linear_model import Lasso
model = Lasso(alpha=0.1)
model.fit(X_train, y_train)
Lassen Sie während des Trainings zufällig einen Teil der Neuronen „ausfallen“ (auf Null setzen):
import torch.nn as nn
model = nn.Sequential(
nn.Linear(128, 64),
nn.ReLU(),
nn.Dropout(p=0.5), # 50% of neurons randomly deactivated during training
nn.Linear(64, 1)
)
Dies verhindert, dass sich Neuronen gemeinsam anpassen, und zwingt das Netzwerk dazu, robustere, verteilte Darstellungen zu lernen.
Überwachen Sie den Validierungsverlust während des Trainings und stoppen Sie, wenn er zuzunehmen beginnt:
from tensorflow.keras.callbacks import EarlyStopping
early_stop = EarlyStopping(
monitor='val_loss',
patience=5, # stop after 5 epochs without improvement
restore_best_weights=True
)
model.fit(X_train, y_train,
validation_data=(X_val, y_val),
callbacks=[early_stop],
epochs=1000)
Mehr Daten machen es für das Modell schwieriger, sich Rauschen zu merken – es sind einfach zu viele, um genau zu passen. Wenn die Datenerfassung kostspielig ist, kann die Datenerweiterung (Erstellung modifizierter Kopien vorhandener Beispiele) hilfreich sein.
Manchmal besteht die richtige Lösung einfach darin, ein weniger komplexes Modell für das Problem auszuwählen.
Bei kleinen Datensätzen kann eine einzelne Zug-/Val-Aufteilung aufgrund der Zufälligkeit irreführend sein. K-fache Kreuzvalidierung liefert eine zuverlässigere Schätzung:
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(n_estimators=100)
# 5-fold cross-validation
scores = cross_val_score(model, X, y, cv=5, scoring='accuracy')
print(f"Mean accuracy: {scores.mean():.3f} ± {scores.std():.3f}")
# Mean accuracy: 0.847 ± 0.023
Die Daten sind in 5 Falten aufgeteilt; Das Modell trainiert auf 4 und validiert auf 1, wobei es sich jedes Mal dreht. Das Endergebnis ist der Durchschnitt aller 5 – viel zuverlässiger als eine einzelne Aufteilung.
Ein Modell erreicht bei Trainingsdaten eine Genauigkeit von 99 %, bei Testdaten jedoch nur 62 %. Was bedeutet das?