Sklearn Lineare Regression: Vollständiger Leitfaden mit Python-Beispielen
Updated on
Du hast einen Datensatz mit Features und einer kontinuierlichen Zielvariable. Du möchtest Ergebnisse vorhersagen – Immobilienpreise, Umsatz, Temperaturtrends – bist dir aber nicht sicher, welchen Ansatz du verwenden sollst oder wie du ihn in Python korrekt aufsetzt. Die falsche Modellwahl oder fehlende Preprocessing-Schritte führen zu schlechten Vorhersagen und kosten viel Zeit beim Debuggen.
Lineare Regression ist der am häufigsten verwendete Algorithmus für kontinuierliche Vorhersageaufgaben. Ihn richtig einzusetzen bedeutet jedoch mehr, als nur .fit() und .predict() aufzurufen. Du musst verstehen, wie das Modell intern funktioniert, wann es scheitert, wie du es korrekt evaluierst und wann du zu regularisierten Varianten wie Ridge oder Lasso wechseln solltest. Wenn du diese Schritte überspringst, setzt du Modelle ein, die auf Trainingsdaten gut aussehen, aber bei neuen Beobachtungen zusammenbrechen.
Scikit-learn bietet LinearRegression zusammen mit einem vollständigen Ökosystem an Tools für Preprocessing, Evaluation und Regularisierung. Dieser Leitfaden deckt alles ab – von der grundlegenden Nutzung bis zu produktionsreifen Regression-Pipelines.
Was ist lineare Regression?
Lineare Regression modelliert die Beziehung zwischen einem oder mehreren Eingabefeatures und einer kontinuierlichen Ausgabe, indem eine Gerade (oder Hyperplane) angepasst wird, die die Summe der quadrierten Residuen minimiert. Die Gleichung für ein Modell mit n Features lautet:
y = b0 + b1*x1 + b2*x2 + ... + bn*xnDabei ist b0 der Intercept (Bias-Term), b1...bn sind die Koeffizienten (Gewichte) für jedes Feature und y ist der vorhergesagte Wert.
Das Modell findet die Koeffizienten, die die Ordinary Least Squares (OLS)-Kostenfunktion minimieren:
Cost = Sum of (y_actual - y_predicted)^2Dies hat eine Closed-Form-Lösung, daher ist das Training selbst auf großen Datensätzen schnell.
Einfache lineare Regression mit Sklearn
Einfache lineare Regression nutzt ein einzelnes Feature, um das Target vorherzusagen. Hier ist ein vollständiges Beispiel:
from sklearn.linear_model import LinearRegression
import numpy as np
# Sample data: years of experience vs salary (in thousands)
X = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]).reshape(-1, 1)
y = np.array([35, 40, 45, 55, 60, 62, 70, 75, 82, 90])
# Create and train the model
model = LinearRegression()
model.fit(X, y)
# Model parameters
print(f"Coefficient (slope): {model.coef_[0]:.4f}")
print(f"Intercept: {model.intercept_:.4f}")
# Predict salary for 12 years of experience
prediction = model.predict([[12]])
print(f"Predicted salary for 12 years: ${prediction[0]:.2f}k")
# Coefficient (slope): 5.9394
# Intercept: 28.3333
# Predicted salary for 12 years: $99.61kDas Output verstehen
| Attribute | Bedeutung | Beispielwert |
|---|---|---|
model.coef_ | Gewicht für jedes Feature | [5.94] – Gehalt steigt um ~5.940$ pro Jahr |
model.intercept_ | Vorhergesagtes y, wenn alle Features 0 sind | 28.33 – Grundgehalt von 28.330$ |
model.score(X, y) | R-squared auf den gegebenen Daten | 0.98 |
Multiple lineare Regression
Wenn du mehr als ein Feature hast, passt das Modell eine Hyperplane statt einer Linie an:
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.datasets import fetch_california_housing
import numpy as np
# Load California housing dataset
housing = fetch_california_housing()
X, y = housing.data, housing.target
feature_names = housing.feature_names
print(f"Features: {feature_names}")
print(f"Dataset shape: {X.shape}") # (20640, 8)
# Split into train and test
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Train model
model = LinearRegression()
model.fit(X_train, y_train)
# Print coefficients for each feature
print("\nFeature Coefficients:")
for name, coef in zip(feature_names, model.coef_):
print(f" {name:12s}: {coef:+.6f}")
print(f" {'Intercept':12s}: {model.intercept_:+.6f}")
# Evaluate
train_score = model.score(X_train, y_train)
test_score = model.score(X_test, y_test)
print(f"\nR² (train): {train_score:.4f}")
print(f"R² (test): {test_score:.4f}")Modellbewertung: R-squared, MSE und RMSE
R-squared allein erzählt nicht die ganze Geschichte. Nutze mehrere Metriken, um Regressionsmodelle zu bewerten:
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from sklearn.datasets import fetch_california_housing
import numpy as np
housing = fetch_california_housing()
X_train, X_test, y_train, y_test = train_test_split(
housing.data, housing.target, test_size=0.2, random_state=42
)
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# Calculate metrics
r2 = r2_score(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_pred)
print(f"R² Score: {r2:.4f}")
print(f"MSE: {mse:.4f}")
print(f"RMSE: {rmse:.4f}")
print(f"MAE: {mae:.4f}")
# R² Score: 0.5758
# MSE: 0.5559
# RMSE: 0.7456
# MAE: 0.5332Evaluationsmetriken erklärt
| Metrik | Formel | Bereich | Interpretation |
|---|---|---|---|
| R-squared (R²) | 1 - (SS_res / SS_tot) | (-inf, 1] | Anteil der erklärten Varianz. 1.0 = perfekt, 0 = nicht besser als Mittelwert |
| MSE | mean((y - y_pred)²) | [0, inf) | Durchschnittlicher quadrierter Fehler. Bestraft große Fehler stärker |
| RMSE | sqrt(MSE) | [0, inf) | Gleiche Einheit wie die Zielvariable. Leichter interpretierbar als MSE |
| MAE | mean(|y - y_pred|) | [0, inf) | Durchschnittlicher absoluter Fehler. Robust gegenüber Ausreißern |
Ein niedriges R-squared bedeutet nicht immer ein schlechtes Modell. Bei verrauschten Real-World-Daten (wie Immobilienpreisen) kann R² = 0.6 durchaus sinnvoll sein. Vergleiche RMSE immer mit der Skalierung deiner Zielvariable.
Feature-Skalierung für lineare Regression
Standard-LinearRegression benötigt keine Feature-Skalierung, weil OLS eine Closed-Form-Lösung nutzt. Skalierung wird jedoch essenziell, wenn du Regularisierung verwendest:
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.datasets import fetch_california_housing
housing = fetch_california_housing()
X_train, X_test, y_train, y_test = train_test_split(
housing.data, housing.target, test_size=0.2, random_state=42
)
# Without scaling (fine for basic LinearRegression)
model_no_scale = LinearRegression()
model_no_scale.fit(X_train, y_train)
print(f"LinearRegression R² (no scaling): {model_no_scale.score(X_test, y_test):.4f}")
# With scaling via Pipeline (required for regularized models)
pipeline = Pipeline([
('scaler', StandardScaler()),
('ridge', Ridge(alpha=1.0))
])
pipeline.fit(X_train, y_train)
print(f"Ridge R² (with scaling): {pipeline.score(X_test, y_test):.4f}")Warum Skalierung bei Regularisierung wichtig ist: Ridge und Lasso bestrafen große Koeffizienten gleich. Wenn ein Feature im Bereich 0–1 liegt und ein anderes 0–100.000, schrumpft die Strafe den Koeffizienten des klein skalierten Features unverhältnismäßig. Skalierung bringt alle Features auf die gleiche Skala, sodass die Strafe fair angewendet wird.
Polynomiale Features: Nichtlineare Beziehungen modellieren
Wenn die Beziehung zwischen Features und Target nicht linear ist, können polynomiale Features Kurven und Interaktionen abbilden:
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score
import numpy as np
# Generate non-linear data
np.random.seed(42)
X = np.linspace(0, 10, 200).reshape(-1, 1)
y = 3 * X.ravel()**2 - 5 * X.ravel() + 10 + np.random.randn(200) * 15
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Linear model
linear = LinearRegression()
linear.fit(X_train, y_train)
print(f"Linear R²: {r2_score(y_test, linear.predict(X_test)):.4f}")
# Polynomial (degree 2) model
poly_pipeline = Pipeline([
('poly', PolynomialFeatures(degree=2, include_bias=False)),
('linear', LinearRegression())
])
poly_pipeline.fit(X_train, y_train)
print(f"Poly (d=2) R²: {r2_score(y_test, poly_pipeline.predict(X_test)):.4f}")
# Polynomial (degree 3) model
poly3_pipeline = Pipeline([
('poly', PolynomialFeatures(degree=3, include_bias=False)),
('linear', LinearRegression())
])
poly3_pipeline.fit(X_train, y_train)
print(f"Poly (d=3) R²: {r2_score(y_test, poly3_pipeline.predict(X_test)):.4f}")Warnung: Polynome hohen Grades overfitten schnell. Nutze Cross-Validation, um den richtigen Grad auszuwählen, und bevorzuge Regularisierung für polynomiale Modelle.
Regularisierung: Ridge, Lasso und ElasticNet
Wenn dein Modell viele Features oder polynomialen Terme hat, verhindert Regularisierung Overfitting, indem sie eine Strafe für große Koeffizienten hinzufügt.
Ridge Regression (L2-Strafe)
Ridge addiert die Summe der quadrierten Koeffizienten zur Kostenfunktion. Es schrumpft Koeffizienten in Richtung Null, setzt sie jedoch nie exakt auf Null.
from sklearn.linear_model import Ridge
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.datasets import fetch_california_housing
import numpy as np
housing = fetch_california_housing()
X_train, X_test, y_train, y_test = train_test_split(
housing.data, housing.target, test_size=0.2, random_state=42
)
# Find best alpha with cross-validation
pipeline = Pipeline([
('scaler', StandardScaler()),
('ridge', Ridge())
])
param_grid = {'ridge__alpha': [0.01, 0.1, 1.0, 10.0, 100.0]}
grid = GridSearchCV(pipeline, param_grid, cv=5, scoring='r2')
grid.fit(X_train, y_train)
print(f"Best alpha: {grid.best_params_['ridge__alpha']}")
print(f"Best CV R²: {grid.best_score_:.4f}")
print(f"Test R²: {grid.score(X_test, y_test):.4f}")Lasso Regression (L1-Strafe)
Lasso addiert die Summe der absoluten Koeffizienten. Es kann Koeffizienten exakt auf Null setzen und führt damit automatische Feature-Selektion durch:
from sklearn.linear_model import Lasso
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.datasets import fetch_california_housing
import numpy as np
housing = fetch_california_housing()
X_train, X_test, y_train, y_test = train_test_split(
housing.data, housing.target, test_size=0.2, random_state=42
)
pipeline = Pipeline([
('scaler', StandardScaler()),
('lasso', Lasso(max_iter=10000))
])
param_grid = {'lasso__alpha': [0.001, 0.01, 0.1, 1.0, 10.0]}
grid = GridSearchCV(pipeline, param_grid, cv=5, scoring='r2')
grid.fit(X_train, y_train)
print(f"Best alpha: {grid.best_params_['lasso__alpha']}")
print(f"Test R²: {grid.score(X_test, y_test):.4f}")
# Show which features were selected (non-zero coefficients)
lasso_model = grid.best_estimator_.named_steps['lasso']
feature_names = housing.feature_names
for name, coef in zip(feature_names, lasso_model.coef_):
status = "KEPT" if abs(coef) > 1e-6 else "DROPPED"
print(f" {name:12s}: {coef:+.6f} [{status}]")ElasticNet (L1 + L2-Strafe)
ElasticNet kombiniert Ridge- und Lasso-Strafen. Der Parameter l1_ratio steuert die Mischung: 0 = reines Ridge, 1 = reines Lasso.
from sklearn.linear_model import ElasticNet
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.datasets import fetch_california_housing
housing = fetch_california_housing()
X_train, X_test, y_train, y_test = train_test_split(
housing.data, housing.target, test_size=0.2, random_state=42
)
pipeline = Pipeline([
('scaler', StandardScaler()),
('elasticnet', ElasticNet(max_iter=10000))
])
param_grid = {
'elasticnet__alpha': [0.01, 0.1, 1.0],
'elasticnet__l1_ratio': [0.1, 0.3, 0.5, 0.7, 0.9]
}
grid = GridSearchCV(pipeline, param_grid, cv=5, scoring='r2')
grid.fit(X_train, y_train)
print(f"Best alpha: {grid.best_params_['elasticnet__alpha']}")
print(f"Best l1_ratio: {grid.best_params_['elasticnet__l1_ratio']}")
print(f"Test R²: {grid.score(X_test, y_test):.4f}")Vergleich: LinearRegression vs Ridge vs Lasso vs ElasticNet
| Modell | Strafe | Feature-Selektion | Wann verwenden | Skalierung erforderlich |
|---|---|---|---|---|
| LinearRegression | Keine | Nein | Wenige Features, keine Multikollinearität, gutes Signal-Rausch-Verhältnis | Nein |
| Ridge | L2 (quadratisch) | Nein (schrumpft Richtung Null) | Viele korrelierte Features, du willst alle Features behalten | Ja |
| Lasso | L1 (absolut) | Ja (setzt Koeffizienten auf Null) | Viele Features, du willst automatische Feature-Selektion | Ja |
| ElasticNet | L1 + L2 | Ja (teilweise) | Viele korrelierte Features, du willst etwas Selektion | Ja |
Das richtige Modell auswählen
Nutze LinearRegression als Baseline. Wenn das Modell overfittet (große Lücke zwischen Train- und Test-R-squared), probiere zuerst Ridge. Wenn du viele irrelevante Features vermutest, probiere Lasso. Wenn Features korreliert sind und du Selektion willst, probiere ElasticNet. Vergleiche immer per Cross-Validation.
Annahmen der linearen Regression
Lineare Regression liefert zuverlässige Ergebnisse, wenn diese Annahmen erfüllt sind:
- Linearität – Die Beziehung zwischen Features und Target ist linear (oder durch Transformationen linearisierbar).
- Unabhängigkeit – Beobachtungen sind voneinander unabhängig. Wird bei Zeitreihen verletzt, wenn Autokorrelation nicht berücksichtigt wird.
- Homoskedastizität – Die Varianz der Residuen ist über alle Werte der Vorhersage konstant.
- Normalverteilung der Residuen – Residuen folgen einer Normalverteilung. Wichtig vor allem für Konfidenzintervalle und Hypothesentests, weniger für reine Vorhersagegenauigkeit.
- Keine Multikollinearität – Features sind nicht stark miteinander korreliert. Multikollinearität erhöht die Varianz der Koeffizienten und macht einzelne Koeffizienten unzuverlässig.
Annahmen im Code prüfen
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.datasets import fetch_california_housing
import numpy as np
housing = fetch_california_housing()
X_train, X_test, y_train, y_test = train_test_split(
housing.data, housing.target, test_size=0.2, random_state=42
)
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
residuals = y_test - y_pred
# Check residual statistics
print(f"Residual mean: {residuals.mean():.6f}") # Should be near 0
print(f"Residual std: {residuals.std():.4f}")
print(f"Residual skewness: {float(np.mean((residuals - residuals.mean())**3) / residuals.std()**3):.4f}")
# Check for multicollinearity (correlation matrix)
corr_matrix = np.corrcoef(X_train, rowvar=False)
print(f"\nMax feature correlation: {np.max(np.abs(corr_matrix - np.eye(corr_matrix.shape[0]))):.4f}")Vollständige Pipeline: Regression in der Praxis
Hier ist eine produktionsnahe Pipeline, die Preprocessing, Feature Engineering und Modellauswahl kombiniert:
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.preprocessing import StandardScaler, PolynomialFeatures
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.pipeline import Pipeline
from sklearn.datasets import fetch_california_housing
import numpy as np
# Load data
housing = fetch_california_housing()
X_train, X_test, y_train, y_test = train_test_split(
housing.data, housing.target, test_size=0.2, random_state=42
)
# Define models to compare
models = {
'LinearRegression': Pipeline([
('scaler', StandardScaler()),
('model', LinearRegression())
]),
'Ridge (alpha=1)': Pipeline([
('scaler', StandardScaler()),
('model', Ridge(alpha=1.0))
]),
'Lasso (alpha=0.01)': Pipeline([
('scaler', StandardScaler()),
('model', Lasso(alpha=0.01, max_iter=10000))
]),
'Poly(2) + Ridge': Pipeline([
('poly', PolynomialFeatures(degree=2, include_bias=False)),
('scaler', StandardScaler()),
('model', Ridge(alpha=10.0))
])
}
# Evaluate all models
print(f"{'Model':<25} {'CV R² (mean)':>12} {'CV R² (std)':>12} {'Test R²':>10}")
print("-" * 62)
for name, pipeline in models.items():
cv_scores = cross_val_score(pipeline, X_train, y_train, cv=5, scoring='r2')
pipeline.fit(X_train, y_train)
test_r2 = pipeline.score(X_test, y_test)
print(f"{name:<25} {cv_scores.mean():>12.4f} {cv_scores.std():>12.4f} {test_r2:>10.4f}")Regression-Ergebnisse mit PyGWalker erkunden
Nach dem Training deines Modells ist es entscheidend, Vorhersagemuster zu verstehen. PyGWalker (opens in a new tab) ermöglicht dir, Residuen, Feature Importances und Beziehungen zwischen „predicted vs actual“ visuell zu erkunden – über eine interaktive Drag-and-drop-Oberfläche in Jupyter:
import pandas as pd
import pygwalker as pyg
# Build a results DataFrame
results = pd.DataFrame(housing.data[len(X_train):], columns=housing.feature_names)
results['actual'] = y_test
results['predicted'] = y_pred
results['residual'] = y_test - y_pred
results['abs_error'] = np.abs(y_test - y_pred)
# Launch interactive exploration
walker = pyg.walk(results)Du kannst Features auf Achsen ziehen, nach Residualgröße einfärben und identifizieren, in welchen Segmenten deiner Daten das Modell Schwierigkeiten hat – ganz ohne Plotting-Code zu schreiben.
Für iteratives Experimentieren in Jupyter bietet RunCell (opens in a new tab) einen AI agent, der dir hilft, verschiedene Feature-Kombinationen, Hyperparameter und Preprocessing-Schritte zu testen, ohne Zellen manuell umzuschreiben.
FAQ
Was ist LinearRegression in sklearn?
sklearn.linear_model.LinearRegression ist ein Ordinary Least Squares (OLS)-Regressionsmodell. Es passt eine lineare Gleichung an die Daten an, indem es die Summe der quadrierten Unterschiede zwischen tatsächlichen und vorhergesagten Werten minimiert. Es ist das einfachste und am besten interpretierbare Regressionsmodell in scikit-learn.
Wie interpretiere ich den R-squared Score?
R-squared misst den Anteil der Varianz in der Zielvariable, den das Modell erklärt. Ein R-squared von 0.80 bedeutet, dass 80% der Varianz erklärt werden. Ein Wert von 1.0 ist ein perfekter Fit, 0.0 bedeutet, das Modell ist nicht besser als die Vorhersage des Mittelwerts, und negative Werte bedeuten, dass das Modell schlechter ist, als einfach den Mittelwert zu verwenden.
Wann sollte ich Ridge vs Lasso vs ElasticNet verwenden?
Nutze Ridge, wenn du alle Features behalten willst, aber Overfitting reduzieren möchtest (multikollineare Features). Nutze Lasso, wenn du automatische Feature-Selektion willst (es setzt irrelevante Feature-Koeffizienten auf Null). Nutze ElasticNet, wenn Features korreliert sind und du eine Balance zwischen der Stabilität von Ridge und der Sparsity von Lasso möchtest.
Braucht LinearRegression Feature-Skalierung?
Basis-LinearRegression erfordert keine Feature-Skalierung, weil die OLS-Lösung skaleninvariant ist. Ridge, Lasso und ElasticNet benötigen jedoch Skalierung, da ihre Strafterme alle Koeffizientengrößen gleich behandeln. Skaliere Features vor regularisierter Regression immer.
Wie gehe ich mit kategorialen Features in linearer Regression um?
Wandle kategoriale Features vor dem Fitten mit OneHotEncoder oder pd.get_dummies() in numerische Features um. Sklearns LinearRegression akzeptiert nur numerische Inputs. In Pipelines nutze ColumnTransformer, um unterschiedliche Transformationen auf numerische und kategoriale Spalten anzuwenden.
Was ist der Unterschied zwischen MSE und RMSE?
MSE (Mean Squared Error) ist der Durchschnitt der quadrierten Unterschiede zwischen tatsächlichen und vorhergesagten Werten. RMSE (Root Mean Squared Error) ist die Quadratwurzel aus MSE. RMSE hat die gleiche Einheit wie die Zielvariable und ist daher leichter zu interpretieren. Wenn du z. B. Hauspreise in Dollar vorhersagst, bedeutet ein RMSE von 50.000 einen durchschnittlichen Vorhersagefehler von etwa 50.000$.
Fazit
Sklearns LinearRegression ist der Einstiegspunkt für jede Regression-Aufgabe in Python. Es ist schnell, gut interpretierbar und effektiv, wenn die zugrunde liegende Beziehung ungefähr linear ist. Für Real-World-Datensätze mit Rauschen, Multikollinearität oder vielen Features liefern Ridge, Lasso und ElasticNet Regularisierung, die die Generalisierung verbessert. Evaluiere immer mit mehreren Metriken (R-squared, RMSE, MAE), nutze Train-Test-Splits, um Overfitting zu vermeiden, und prüfe Residuenmuster, um sicherzustellen, dass die Modellannahmen erfüllt sind. Baue Pipelines mit StandardScaler und PolynomialFeatures, um deinen Workflow sauber und reproduzierbar zu halten.