So nutzt du die Seite

Arbeite von oben nach unten. Jede Sektion hat eine kurze Erklärung, direkt ausführbaren Code und einen Mini-Selbstcheck. Das Ziel ist nicht nur "es läuft", sondern dass du die Parameter fachlich erklären kannst.

Codepfad
Dauer: 45-90 Minuten
Python: 3.11.3
Libraries: pandas, scikit-learn, statsmodels

1) Setup und Notation (Theorie in 5 Minuten)

Univariat: ein Einflussfaktor `x` (z. B. Temperatur). Multivariat: mehrere Faktoren `x1, x2, ...`. In Matrixform gilt: `y = X*beta + epsilon`.

Interpretation:
`b0`/Intercept ist das Basisniveau. `b1` (bzw. Gewichte in `beta`) sind die Änderungsraten je Feature. `epsilon` steht für den nicht erklärten Rest.
Code
python3.11 -m venv .venv
source .venv/bin/activate
pip install pandas scikit-learn statsmodels matplotlib

# optional: jupyter lab
# pip install jupyterlab
Mini-Check: Warum braucht man oft einen Intercept?

Ohne Intercept wird das Modell durch den Ursprung gezwungen. Das ist in vielen realen Problemen fachlich unplausibel und verschlechtert die Anpassung.

2) Univariat mit `scikit-learn`

Start mit dem bekannten Fall: Heizkosten nur aus Temperatur erklären. So siehst du Steigung und Intercept direkt im Code wieder.

Code
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, r2_score

# kleines Beispiel-Dataset
df = pd.DataFrame({
    "temp_c": [-2, 0, 3, 6, 10, 14, 16],
    "heating_cost_eur": [152, 144, 129, 116, 96, 79, 72]
})

X = df[["temp_c"]]      # 2D, weil sklearn Features als Matrix erwartet
y = df["heating_cost_eur"]

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42
)

model_uni = LinearRegression()
model_uni.fit(X_train, y_train)

y_pred = model_uni.predict(X_test)

print("Steigung b1:", round(model_uni.coef_[0], 3))
print("Intercept b0:", round(model_uni.intercept_, 3))
print("MAE:", round(mean_absolute_error(y_test, y_pred), 3))
print("R2:", round(r2_score(y_test, y_pred), 3))

# konkrete Prognose
print("Prognose bei 5°C:", round(model_uni.predict(pd.DataFrame({"temp_c": [5]}))[0], 2))
Berufslogik: Wenn `b1` negativ ist, sinken die Heizkosten pro zusätzlichem Grad. Genau diese fachliche Aussage musst du später kommunizieren können.
Mini-Check: Was sagt dir `coef_ = -4.6` konkret?

Erhöht sich die Temperatur um 1°C, sinkt die Modellprognose im Mittel um ca. 4.6 Euro, solange der Zusammenhang im betrachteten Bereich ungefähr linear bleibt.

3) Multivariat mit `scikit-learn`

Jetzt erweitern wir auf zwei Features. Das ist die direkte Fortsetzung deiner Matrix-/Matrizenmultiplikations-Seiten.

Code
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error

# Gebäudefaktor als zweites Merkmal (z. B. Dämm-/Gebäudezustand)
df = pd.DataFrame({
    "temp_c": [-2, 1, 4, 7, 11, 15],
    "building_factor": [1.18, 1.10, 1.04, 0.98, 0.92, 0.88],
    "heating_cost_eur": [170, 159, 144, 130, 112, 98]
})

X_multi = df[["temp_c", "building_factor"]]
y = df["heating_cost_eur"]

model_multi = LinearRegression()
model_multi.fit(X_multi, y)

pred_multi = model_multi.predict(X_multi)
mae_multi = mean_absolute_error(y, pred_multi)

print("Gewichte:")
print("temp_c:", round(model_multi.coef_[0], 3))
print("building_factor:", round(model_multi.coef_[1], 3))
print("Intercept:", round(model_multi.intercept_, 3))
print("MAE (train, nur Demo):", round(mae_multi, 3))

new_case = pd.DataFrame({"temp_c": [6], "building_factor": [1.00]})
print("Prognose für neuen Fall:", round(model_multi.predict(new_case)[0], 2))
Wichtig: Feature-Skalen beeinflussen die Größe der Koeffizienten. Vergleiche Gewichte nicht blind ohne Kontext oder Standardisierung.
Mini-Check: Wann bringt ein zweites Feature echten Mehrwert?

Wenn es zusätzlichen erklärenden Informationsgehalt hat und die Fehler im Mittel sinken, ohne dass das Modell instabil oder unnötig komplex wird.

4) OLS mit `statsmodels` (Interpretation)

Mit `statsmodels` bekommst du ein statistisches Summary (p-Werte, Konfidenzintervalle, F-Test, R²). Das ist relevant für Reporting und Stakeholder-Kommunikation.

Code
import pandas as pd
import statsmodels.formula.api as smf

cars = pd.DataFrame({
    "temp_c": [-2, 1, 4, 7, 11, 15],
    "building_factor": [1.18, 1.10, 1.04, 0.98, 0.92, 0.88],
    "heating_cost_eur": [170, 159, 144, 130, 112, 98]
})

result = smf.ols(
    formula="heating_cost_eur ~ temp_c + building_factor",
    data=cars
).fit()

print(result.summary())

# Vorhersage mit Formula-API
print(result.predict(exog={"temp_c": [6], "building_factor": [1.00]}))
Was im Summary zuerst lesen?
1) R-squared / Adj. R-squared (Güte), 2) Koeffizienten-Vorzeichen und Größenordnung (Fachlogik), 3) p-Werte und Konfidenzintervalle (Unsicherheit), 4) F-statistic (Gesamtmodell).
Mini-Check: Was bedeutet ein hoher p-Wert für ein Feature?

Unter den Modellannahmen ist der Beitrag dieses Features statistisch unsicher. Das heißt nicht automatisch "immer entfernen", aber es ist ein Signal zur Prüfung.

5) Modellgüte prüfen und Grenzen benennen

Ein gutes Ergebnis ist nicht nur ein niedriger Fehler. Du prüfst auch, ob Annahmen und Einsatzkontext zusammenpassen. Der Code läuft auch separat, falls vorherige Zellen nicht ausgeführt wurden.

Code
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression

# Standalone-Block: lauffähig ohne vorherige Schritte
df_uni = pd.DataFrame({
    "temp_c": [-2, 0, 3, 6, 10, 14, 16],
    "heating_cost_eur": [152, 144, 129, 116, 96, 79, 72]
})
X = df_uni[["temp_c"]]
y = df_uni["heating_cost_eur"]

model_uni = LinearRegression()
model_uni.fit(X, y)

# Wichtig: komplette Zelle ausführen, nicht nur die letzten 2 Zeilen.
y_hat_all = model_uni.predict(X)
residuals = y - y_hat_all

print("Durchschnittsfehler (MAE):", round(np.mean(np.abs(residuals)), 3))

plt.axhline(0, color="black", linewidth=1)
plt.scatter(X["temp_c"], residuals)
plt.xlabel("Temperatur (°C)")
plt.ylabel("Residuum (Ist - Vorhersage)")
plt.title("Residualplot")
plt.show()
Typische Grenzen:
Nichtlineare Zusammenhänge, fehlende wichtige Features, Ausreißer, kleine Datensätze, Drift im Zeitverlauf. In solchen Fällen reicht lineare Regression allein oft nicht.
Mini-Check: Wie prüfst du, ob das Modell die Daten "gut beschreibt"?

MAE/R² auf Testdaten, Residuenmuster prüfen, fachliche Plausibilität der Koeffizienten validieren und mit einem einfachen Baseline-Modell vergleichen.

Nächste Schritte für den Kurs

  1. Das Beispiel in ein Notebook übertragen und pro Schritt kurze Textinterpretationen ergänzen.
  2. Univariat vs. multivariat mit denselben Testdaten vergleichen und Ergebnis begründen.
  3. `statsmodels`-Summary in 4 Sätzen für ein Management-Update zusammenfassen.