Multiple Regression
Lerne, wie multiple lineare Regression funktioniert, Koeffizienten interpretiert und Multikollinearität behandelt wird – mit scikit-learn.
Multiple lineare Regression erweitert die einfache lineare Regression, indem zwei oder mehr unabhängige Variablen zur Vorhersage eines kontinuierlichen Zielwerts verwendet werden. Anstatt eine Linie durch zwei Dimensionen zu ziehen, passt das Modell eine Hyperebene durch so viele Dimensionen an, wie es Features gibt. Das Kernwissen dieser Seite besteht darin zu verstehen, wie die Koeffizienten miteinander interagieren — und wann sie irreführend sein können.
Diese Seite behandelt:
- Die multiple Regressionsgleichung und die Bedeutung jedes Koeffizienten
- Wie man eine vollständige scikit-learn-Pipeline aufbaut: laden, vorverarbeiten, trainieren, auswerten
- Warum Feature-Skalierung wichtig ist und wie man sie korrekt durchführt
- Wie man skalierte und unskalierte Koeffizienten interpretiert und vergleicht
- Diagnose von Multikollinearität — der häufigste Fallstrick bei der multiplen Regression
- Residualanalyse zur Überprüfung der Modellannahmen
- Wann multiple Regression die richtige Wahl ist und welche Alternativen es gibt
Die Multiple Regressionsgleichung
Multiple lineare Regression modelliert den Zielwert y als lineare Kombination von n Eingabe-Features:
y = β₀ + β₁x₁ + β₂x₂ + ... + βₙxₙ + εβ₀— der Achsenabschnitt (Intercept): der vorhergesagte Wert vony, wenn jedes Feature gleich null istβ₁ … βₙ— die Koeffizienten: um wie viel sichybei einer Einheitszunahme inxᵢändert, während alle anderen Features konstant gehalten werdenε— der Fehlerterm: der Teil vony, den das Modell nicht erklären kann
Der Algorithmus findet die Koeffizienten durch Minimierung der Summe der quadrierten Residuen (Ordinary Least Squares):
SSR = Σ(yᵢ - ŷᵢ)²Dies hat eine exakte geschlossene Lösung, sodass scikit-learns LinearRegression keinen iterativen Gradientenabstieg benötigt — das Training ist selbst bei Datensätzen mit Hunderttausenden von Zeilen nahezu augenblicklich.
Unterschied zur einfachen linearen Regression
Einfache lineare Regression verwendet ein Feature. Multiple Regression fügt weitere Features hinzu, sodass jeder Koeffizient den partiellen Effekt dieses Features erfasst — seinen Einfluss auf den Zielwert, während die übrigen Features konstant gehalten werden. Das ist mächtiger, birgt aber neue Risiken, insbesondere Multikollinearität (siehe Diagnose von Multikollinearität).
Der Datensatz
Die nachfolgenden Beispiele verwenden den California Housing-Datensatz, der in scikit-learn enthalten ist. Er enthält Wohnungsstatistiken auf Volkszählungsblock-Ebene für Kalifornien im Jahr 1990 und umfasst 20.640 Datenpunkte über 8 Features.
import pandas as pd
from sklearn.datasets import fetch_california_housing
housing = fetch_california_housing()
df = pd.DataFrame(housing.data, columns=housing.feature_names)
df['MedHouseVal'] = housing.target # median house value in $100,000s
print(df.shape) # (20640, 9)
print(df.head())Die 8 Eingabe-Features sind:
| Feature | Beschreibung |
|---|---|
MedInc | Medianeinkommen im Block (in Zehntausend Dollar) |
HouseAge | Medianalter der Häuser im Block |
AveRooms | Durchschnittliche Zimmeranzahl pro Haushalt |
AveBedrms | Durchschnittliche Schlafzimmeranzahl pro Haushalt |
Population | Blockbevölkerung |
AveOccup | Durchschnittliche Haushaltsbelegung |
Latitude | Breitengrad des Blocks |
Longitude | Längengrad des Blocks |
Der Zielwert MedHouseVal ist der Median-Hauswert in Einheiten von 100.000 $, sodass ein Wert von 2.0 einem Wert von 200.000 $ entspricht.
Das Modell Schritt für Schritt aufbauen
Schritt 1 — Daten aufteilen
Teile die Daten immer auf, bevor du irgendeine Vorverarbeitung durchführst. Wenn ein Scaler auf dem vollständigen Datensatz angepasst wird, würden Testset-Statistiken in das Training einfließen, was zu einer übermäßig optimistischen Bewertung führt. Siehe Train/Test Split für eine vollständige Erklärung.
from sklearn.model_selection import train_test_split
X = df[housing.feature_names]
y = df['MedHouseVal']
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
print(f"Training samples: {len(X_train)}") # 16512
print(f"Test samples: {len(X_test)}") # 4128Schritt 2 — Features skalieren
Koeffizienten in der multiplen Regression spiegeln die Einheiten jedes Features wider. MedInc wird in Zehntausend Dollar gemessen; Population ist eine rohe Anzahl, die bis zu 35.000 erreichen kann. Ohne Skalierung wird der Koeffizient für Population winzig sein — nicht weil Bevölkerung unwichtig ist, sondern weil ihre Einheit klein ist.
StandardScaler transformiert jedes Feature so, dass es den Mittelwert null und eine Standardabweichung von eins hat, wodurch die Koeffizientenbeträge direkt vergleichbar werden. Siehe Feature Scaling für Details zu den verfügbaren Scalern.
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train) # fit ONLY on training data
X_test_scaled = scaler.transform(X_test) # apply the same transformationDie entscheidende Regel: Verwende fit_transform auf den Trainingsdaten und transform (ohne Anpassung) auf den Testdaten. Eine Anpassung auf den Testdaten würde die Auswertung verfälschen.
Schritt 3 — Modell trainieren
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X_train_scaled, y_train)LinearRegression.fit() löst das OLS-Problem analytisch. Es gibt keine Hyperparameter für die einfache multiple Regression — was du wählst, sind die einzuschließenden Features.
Schritt 4 — Modell auswerten
import numpy as np
from sklearn.metrics import mean_squared_error, r2_score
y_pred = model.predict(X_test_scaled)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)
print(f"Mean Squared Error: {mse:.4f}")
print(f"Root Mean Squared Error: {rmse:.4f} (±${rmse * 100_000:,.0f})")
print(f"R-squared: {r2:.4f}")Erwartete Ausgabe:
Mean Squared Error: 0.5559
Root Mean Squared Error: 0.7456 (±$74,558)
R-squared: 0.5758Was die Metriken bedeuten:
- MSE (Mean Squared Error) — der Durchschnitt der quadrierten Differenzen zwischen Vorhersagen und tatsächlichen Werten. Das Quadrieren bestraft große Fehler stärker als kleine. Die Einheiten sind das Quadrat des Zielwerts ($100.000²), daher ist er schwieriger direkt zu interpretieren.
- RMSE (Root Mean Squared Error) — die Quadratwurzel des MSE, zurück in denselben Einheiten wie der Zielwert. Ein RMSE von 0,75 bedeutet, dass die Vorhersagen des Modells im Durchschnitt um etwa 75.000 $ abweichen.
- R² (Bestimmtheitsmaß) — der Anteil der Varianz im Zielwert, den das Modell erklärt. Ein R² von 0,58 bedeutet, dass das Modell 58 % der Variation in den Hauspreisen erfasst. Werte reichen von 0 (nicht besser als die Vorhersage des Mittelwerts) bis 1 (perfekte Vorhersagen). Ein negativer R²-Wert ist möglich, wenn das Modell schlechter als der Mittelwert ist — das ist ein starkes Zeichen, dass etwas nicht stimmt.
Ein R² von ~0,58 ist typisch für diesen Datensatz mit einfacher linearer Regression. Die Beziehung zwischen Hauspreisen und diesen Features ist teilweise nichtlinear und beinhaltet geografische Cluster, die eine Hyperebene nicht gut erfassen kann. Algorithmen wie Gradient-Boosted Trees erreichen auf diesem Datensatz routinemäßig 0,80+.
Schritt 5 — Koeffizienten untersuchen
Nach der Skalierung sind die Koeffizientenbeträge direkt vergleichbar — sie zeigen, welche Features die Vorhersage am stärksten beeinflussen:
coef_df = pd.DataFrame({
'Feature': housing.feature_names,
'Coefficient': model.coef_
}).sort_values('Coefficient', key=abs, ascending=False)
print(coef_df.to_string(index=False))
print(f"\nIntercept: {model.intercept_:.4f}")Erwartete Ausgabe:
Feature Coefficient
Latitude -0.8969
Longitude -0.8698
MedInc 0.8544
AveBedrms 0.3393
AveRooms -0.2944
HouseAge 0.1225
AveOccup -0.0408
Population -0.0023
Intercept: 2.0719Interpretation der Koeffizienten nach Standardskalierung:
MedInc = 0.854— der mit Abstand stärkste Prädiktor. Eine Erhöhung des Medianeinkommens um eine Standardabweichung sagt einen Anstieg des Hauswerts um 85.400 $ voraus, bei konstantem Einfluss aller anderen Variablen.Latitude = -0.897undLongitude = -0.869— das Modell hat gelernt, dass nördlichere und östlichere Volkszählungsblöcke tendenziell günstiger sind. Diese beiden geografischen Features sind jedoch stark korreliert (r = -0,93), was ihre einzelnen Koeffizienten instabil machen kann (siehe Diagnose von Multikollinearität).AveBedrms = +0.339vs.AveRooms = -0.294— diese haben entgegengesetzte Vorzeichen, obwohl mehr Zimmer und mehr Schlafzimmer generell auf größere und teurere Häuser hindeuten. Dies ist ein klassisches Zeichen für Multikollinearität:AveRoomsundAveBedrmssind korreliert (r = 0,85), sodass sich ihre Koeffizienten gegenseitig ausgleichen. Interpretiere sie nicht isoliert.Population = -0.002— sehr nahe an null nach der Skalierung. Die Blockbevölkerung hat minimale Vorhersagekraft, sobald die anderen Features berücksichtigt werden.
Der Achsenabschnitt (2,07) ist der vorhergesagte MedHouseVal, wenn jedes skalierte Feature null ist — das heißt, wenn alle Features ihrem Trainings-Mittelwert entsprechen. Er entspricht dem Mittelwert der Trainingszielwerte und hat darüber hinaus keine direkte geschäftliche Bedeutung.
Schritt 6 — Vorhersagen für neue Daten treffen
# A new census block: high income, older house, San Francisco Bay Area
new_block = pd.DataFrame([[8.0, 41.0, 6.0, 1.0, 322, 2.5, 37.88, -122.23]],
columns=housing.feature_names)
new_block_scaled = scaler.transform(new_block)
prediction = model.predict(new_block_scaled)
print(f"Predicted median house value: ${prediction[0] * 100_000:,.0f}")Erwartete Ausgabe:
Predicted median house value: $410,895Der Scaler muss derselbe Scaler sein, der auf den Trainingsdaten angepasst wurde. Passe den Scaler niemals erneut auf die neuen Daten an — das würde die Eingaben relativ zu dem verschieben, was das Modell gelernt hat.
Diagnose von Multikollinearität
Multikollinearität tritt auf, wenn zwei oder mehr unabhängige Variablen stark miteinander korreliert sind. Sie verhindert nicht, dass das Modell genaue Vorhersagen macht, macht aber die einzelnen Koeffizienten unzuverlässig und schwer zu interpretieren. Koeffizienten können groß werden, das Vorzeichen wechseln oder statistisch insignifikant werden, selbst für tatsächlich wichtige Features.
Überprüfung mit einer Korrelationsmatrix
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
corr = df[housing.feature_names].corr()
print(corr.round(2))Wichtige Paare, die zu beachten sind:
| Feature-Paar | Korrelation | Bedenken |
|---|---|---|
AveRooms / AveBedrms | 0,85 | Hoch — Koeffizienten gleichen sich gegenseitig aus |
Latitude / Longitude | -0,93 | Sehr hoch — gemeinsame geografische Bewegung |
MedInc / MedHouseVal (Ziel) | 0,69 | Guter Prädiktor, kein Kollinearitätsproblem |
Eine Korrelation über 0,80 zwischen zwei Features ist ein Warnsignal. Wenn du das siehst, ziehe in Betracht:
- Eines der korrelierten Features entfernen. Wenn
AveRoomsundAveBedrmsbeide im Modell sind, versucheAveBedrmszu entfernen und prüfe, ob sich die Vorhersageleistung des Modells wesentlich ändert. - Sie kombinieren. Erstelle ein abgeleitetes Feature (z. B.
rooms_per_bedroom = AveRooms / AveBedrms), das die Beziehung ohne Redundanz erfasst. - Ein regularisiertes Modell verwenden. Ridge-Regression fügt eine L2-Penalty hinzu, die korrelierte Koeffizienten aufeinander zu schrumpft und sie stabilisiert. Lasso (L1) kann redundante Features vollständig auf null setzen.
Residualanalyse
Ein Residuum ist die Differenz zwischen einem tatsächlichen Wert und der Vorhersage des Modells: residual = y_actual - y_predicted. Das Plotten von Residuen zeigt, ob die Annahmen des Modells erfüllt sind.
residuals = y_test - y_pred
print(f"Mean of residuals: {residuals.mean():.4f}") # should be close to 0
print(f"Std of residuals: {residuals.std():.4f}")Erwartete Ausgabe:
Mean of residuals: 0.0035
Std of residuals: 0.7457Der Mittelwert liegt nahe null — ein Zeichen, dass das Modell im Durchschnitt unverzerrt ist. Die Standardabweichung von 0,75 (±75.000 $) zeigt jedoch erhebliche Streuung.
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
# Predicted vs Actual
axes[0].scatter(y_test, y_pred, alpha=0.2, s=8)
axes[0].plot([0, 5], [0, 5], 'r--')
axes[0].set_xlabel('Actual')
axes[0].set_ylabel('Predicted')
axes[0].set_title('Predicted vs Actual')
# Residuals vs Predicted
axes[1].scatter(y_pred, residuals, alpha=0.2, s=8)
axes[1].axhline(0, color='r', linestyle='--')
axes[1].set_xlabel('Predicted')
axes[1].set_ylabel('Residual')
axes[1].set_title('Residuals vs Predicted')
plt.tight_layout()
plt.savefig('residuals.png', dpi=120)
print("Saved residuals.png")Worauf zu achten ist:
- Vorhergesagt vs. Tatsächlich — im Idealfall liegen die Punkte auf der Diagonale. Systematische Abweichungen von der Diagonale (eine Kurve oder ein Abflachen bei hohen Werten) bedeuten, dass die lineare Annahme für einen Teil des Wertebereichs falsch ist.
- Residuen vs. Vorhergesagt — im Idealfall streuen die Residuen zufällig um null bei allen Vorhersageniveaus. Eine Trichterform (breitere Streuung bei höheren Vorhersagen) signalisiert Heteroskedastizität — der Fehler des Modells ist nicht konstant, was Intervallschätzungen unzuverlässig machen kann.
- Cluster — deutlich getrennte Gruppen im Residualplot können darauf hinweisen, dass der Datensatz Teilpopulationen enthält (z. B. städtisch vs. ländlich), die separate Modelle oder zusätzliche Features erfordern.
Vollständige Pipeline
Hier ist alles oben Genannte als einzelnes ausführbares Skript:
import numpy as np
import pandas as pd
from sklearn.datasets import fetch_california_housing
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, r2_score
# 1. Load data
housing = fetch_california_housing()
df = pd.DataFrame(housing.data, columns=housing.feature_names)
df['MedHouseVal'] = housing.target
# 2. Split — before any preprocessing
X = df[housing.feature_names]
y = df['MedHouseVal']
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 3. Scale
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 4. Train
model = LinearRegression()
model.fit(X_train_scaled, y_train)
# 5. Evaluate
y_pred = model.predict(X_test_scaled)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
r2 = r2_score(y_test, y_pred)
print(f"RMSE: {rmse:.4f}")
print(f"R²: {r2:.4f}")
# 6. Coefficients (most important first)
coef_df = pd.DataFrame({
'Feature': housing.feature_names,
'Coefficient': model.coef_
}).sort_values('Coefficient', key=abs, ascending=False)
print(coef_df.to_string(index=False))Wann Multiple Regression verwenden
Multiple Regression ist eine starke erste Wahl, wenn:
- Die Beziehung zwischen jedem Feature und dem Zielwert näherungsweise linear ist
- Interpretierbarkeit wichtig ist — jeder Koeffizient hat eine klare Bedeutung
- Du eine schnelle Baseline willst, bevor du komplexere Modelle ausprobierst
- Du genug Datenpunkte im Verhältnis zur Anzahl der Features hast (eine Faustregel: mindestens 10–20 Beobachtungen pro Feature)
Erwäge Alternativen, wenn:
| Situation | Alternative |
|---|---|
| Nichtlineare Feature-Ziel-Beziehungen | Polynomial Regression |
| Viele Features, Overfitting-Risiko | Ridge oder Lasso (regularisierte lineare Modelle) |
| Zielwert ist eine Kategorie, keine Zahl | Logistic Regression |
| Komplexe Interaktionen und Nichtlinearität | Gradient-Boosted Trees oder Random Forests |
Häufige Fehler
Den Scaler auf allen Daten anpassen, bevor die Daten aufgeteilt werden. Dadurch fließen Mittelwert und Varianz des Testsets in das Training ein. Teile die Daten immer zuerst auf und passe den Scaler nur auf den Trainingsanteil an.
Mehr Features helfen immer. Das Hinzufügen irrelevanter oder redundanter Features kann die Interpretierbarkeit verringern, Multikollinearität einführen und die Generalisierung beeinträchtigen. Verwende Domänenwissen oder eine Feature-Selection-Technik, um Features gezielt auszuwählen.
Koeffizienten vertrauen, wenn Features korreliert sind. Wenn AveRooms und AveBedrms beide im Modell sind, spiegelt keiner der Koeffizienten zuverlässig den wahren Effekt dieser Variable wider. Überprüfe die Korrelationsmatrix, bevor du einzelne Koeffizienten interpretierst.
Residualplots ignorieren. Ein R² von 0,58 sieht auf dem Papier vernünftig aus, aber Residualmuster können zeigen, dass das Modell für hochpreisige Immobilien oder für bestimmte geografische Regionen systematisch falsch liegt.
Über den Trainingsbereich hinaus extrapolieren. Ein lineares Modell, das auf Häusern mit Preisen zwischen 50.000 und 500.000 $ trainiert wurde, sollte nicht für die Vorhersage von 5.000.000-Dollar-Immobilien verwendet werden. Überprüfe, ob neue Eingaben im Bereich der während des Trainings gesehenen Werte liegen.
Nächste Schritte
- Linear Regression — die Grundlage: einfache (Ein-Feature-)Regression und die OLS-Methode vollständig erklärt
- Polynomial Regression — das lineare Modell erweitern, um Kurven durch das Hinzufügen polynomialer Feature-Terme zu erfassen
- Feature Scaling — Tiefeneinblick in StandardScaler, MinMaxScaler und RobustScaler
- Train/Test Split — warum korrektes Aufteilen entscheidend ist und wie man es ohne Datenlecks macht
- Cross-Validation — eine robustere Alternative zu einem einzelnen Train/Test-Split