Lineare Regression

Hast du einen linearen Zusammenhang zwischen zwei Variablen festgestellt, kannst du im Streudiagramm eine Gerade einzeichnen, die möglichst nah durch deine Messpunkte verläuft.

Wir wollen nun für diese Gerade eine Geradengleichung in der Form mj[ \begin{equation}y=b x+a\end{equation} ]mj angeben.

  • mj[ \begin{equation}b\end{equation} ]mj ist die Steigung (engl. slope) der Geraden.
  • mj[ \begin{equation}a\end{equation} ]mj ist der y-Achsenabschnitt (engl. intercept) der Geraden.

Die beiden Werte mj[ \begin{equation}a\end{equation} ]mj und mj[ \begin{equation}b\end{equation} ]mj sollen aus den Messwerten so bestimmt werden, dass mj[ \begin{equation}\varepsilon_1^2+\varepsilon_2^2+\varepsilon_3^2\end{equation} ]mj minimal wird.

Berechnung mit SciPy

Für die lineare Regression benutzen wir aus SciPy die Funktion results = stats.linregress(). Der Rückgabewert results ist ein Datenobjekt, das folgende Werte enthält:

  • results.slope: Steigung mj[ \begin{equation}b\end{equation} ]mj der Regressionsgeraden
  • results.intercept: Achsenabschnitt mj[ \begin{equation}a\end{equation} ]mj der Regressionsgeraden
  • results.rvalue: Pearson’scher Korrelationskoeffizient mj[ \begin{equation}r\end{equation} ]mj
  • results.pvalue: mj[ \begin{equation}p\end{equation} ]mj-Wert des Signifikanztests
  • results.stderr: Standardfehler der Steigung (geschätzte Ungenauigkeit von mj[ \begin{equation}b\end{equation} ]mj)
  • results.intercept_stderr: geschätzte Ungenauigkeit von mj[ \begin{equation}a\end{equation} ]mj

 

Hast du mit der Korrelationsanalyse einen linearen Zusammenhang zwischen zwei Variablen festgestellt, kannst du im Streudiagramm eine Gerade einzeichnen, die möglichst nah durch deine Messpunkte verläuft, wie wir es in der vorigen Einheit schon als optische Hilfestellung getan haben.

Voraussetzungen

Um das Modell der linearen Regression benutzen zu können, muss auf folgendes geachtet werden:

  • Die Werte müssen metrisches Skalennviveau haben (hier erklärt).
  • Es muss ein linearer Zusammenhang zwischen beiden Variablen bestehen (hier erklärt).
  • Ausreißer entfernen: Ausreißer können Lage der Regressionsgeraden ändern. Identifizierst du solche bei der Überprüfung des Streudiagramms hinter der linearen Regression, musst du sie ggf. von der Regressionsrechnung entfernen.
  • Die Streuung der Fehlerterme sollte entlang der Regressionsgeraden konstant sein.

Vorgehen

Wir wollen nun für diese Gerade eine Geradengleichung in der Form mj[ \begin{equation}y=b x+a\end{equation} ]mj angeben.

  • mj[ \begin{equation}b\end{equation} ]mj ist die Steigung (engl. slope) der Geraden.
  • mj[ \begin{equation}a\end{equation} ]mj ist der y-Achsenabschnitt (engl. intercept) der Geraden.

Die beiden Werte mj[ \begin{equation}a\end{equation} ]mj und mj[ \begin{equation}b\end{equation} ]mj sollen aus den Messwerten so bestimmt werden, dass die Summe aller quadrierten Abweichungen (die sogenannten Fehlerquadrate) in y-Richtung so klein wie möglich ist.

Es handelt sich hierbei um eine Linie durch 3 Punkte

Kurz: Finde mj[ \begin{equation}a\end{equation} ]mj und mj[ \begin{equation}b\end{equation} ]mj so, dass mj[ \begin{equation}\varepsilon_1^2+\varepsilon_2^2+\varepsilon_3^2\end{equation} ]mj minimal wird.

Das Ergebnis ist ein einfache lineare Funktion, die sogenannte Regressionsgerade, mit der du zu jedem vorgegebenen mj[ \begin{equation}x\end{equation} ]mj-Wert den zu erwartenden mj[ \begin{equation}y\end{equation} ]mj-Wert vorhersagen kannst.

Dieses Verfahren nennt man lineare Regression. Sie ist eine der wichtigsten Verfahren des Maschinellen Lernens. Du kannst hiermit nicht nur lineare Abhängigkeiten zwischen zwei Variablen beschreiben, sondern aus einem bekannten mj[ \begin{equation}x\end{equation} ]mj-Wert auch Prognosen für einen zu erwartenden mj[ \begin{equation}y\end{equation} ]mj-Wert erstellen.

Berechnung mit SciPy

Du musst diese Rechnung nicht selbst durchführen. Python liefert uns auch hierfür wieder fertige Funktionen. Für die lineare Regression benutzen wir aus dem Paket SciPy die Funktion results = stats.linregress(), die wir oben schon zur Konstruktion der Hilfsgeraden benutzt haben. Der Rückgabewert results ist ein Datenobjekt, das folgende Werte enthält:

  • results.slope: Steigung mj[ \begin{equation}b\end{equation} ]mj der Regressionsgeraden
  • results.intercept: Achsenabschnitt mj[ \begin{equation}a\end{equation} ]mj der Regressionsgeraden
  • results.rvalue: Pearson’scher Korrelationskoeffizient mj[ \begin{equation}r\end{equation} ]mj
  • results.pvalue: mj[ \begin{equation}p\end{equation} ]mj-Wert-Wert des Signifikanztests
  • results.stderr: Standardfehler der Steigung (geschätzte Ungenauigkeit von mj[ \begin{equation}b\end{equation} ]mj)
  • results.intercept_stderr: geschätzte Ungenauigkeit von mj[ \begin{equation}a\end{equation} ]mj

Da wir bei einer linearen Regression ohnehin eine Korrelationsanalyse und einen Signifikanztest durchführen müssen, liefert die Funktion linregress() die entsprechenden Werte mj[ \begin{equation}r\end{equation} ]mj und mj[ \begin{equation}p\end{equation} ]mj also praktischerweise gleich mit.

In einem vorangegangenen Video haben wir einen Immobilienpreisrechner gezeigt. In diesem Berechnungsmodell ergibt sich der Immobilienpreis mj[ \begin{equation}P\end{equation} ]mj aus einem Anteil, der proportional zur Wohnfläche mj[ \begin{equation}W\end{equation} ]mj ist plus weiteren Anteilen, so dass der Preis in der Form mj[ \begin{equation}\mathrm{P}=\mathrm{a}+\mathrm{b}^* \mathrm{~W}\end{equation} ]mj geschrieben werden kann. Dabei haben wir die Faktoren mj[ \begin{equation}a\end{equation} ]mj und mj[ \begin{equation}b\end{equation} ]mj als bekannt angenommen. Aber woher bekommen wir die Werte von mj[ \begin{equation}a\end{equation} ]mj und mj[ \begin{equation}b\end{equation} ]mj? Wir erhalten sie, indem wir anhand einer Testdatenbank eine lineare Regression durchführen und so Durchschnittswerte für mj[ \begin{equation}a\end{equation} ]mj und mj[ \begin{equation}b\end{equation} ]mj ermitteln. Die Testdatenbank sollte eine große Liste von Wohnungen enthalten, die sich möglichst nur durch die Wohnfläche mj[ \begin{equation}W\end{equation} ]mj und die zugehörigen Preise mj[ \begin{equation}P\end{equation} ]mj unterscheiden.

Führen wir nun an folgenden Testdaten für Immobilienpreise eine lineare Regression durch. Die Testdaten geben die Wohnfläche in m² und die Preise in tausend Euro an.

import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats

df = pd.DataFrame([(120,238),(150,288),(180,406),(200,465),
(210,399),(140,359),(130,285)], columns=["Wohnfläche","Preis"])
df.dropna(inplace=True)

# Linie berechnen
def linie(x):
return b * x + a
results = stats.linregress(df["Wohnfläche"],df["Preis"])
r = results.rvalue
p = results.pvalue
b = results.slope
a = results.intercept
y = list(map(linie, [100,250]))

# Scatterplot zeichnen
plt.scatter(df["Wohnfläche"],df["Preis"]) # Punkte zeichnen
plt.axis([100,250,200,500]) # Achsenskalierung
plt.xlabel("Wohnfläche in m²") # Achsenbeschriftungen
plt.ylabel("Preis in T€")
plt.plot([100,250], y, linewidth=1, linestyle=":") # Linie
plt.text(150,255,"r = "+str(r.round(4))) # r anzeigen
plt.text(150,245,"p = "+str(p.round(4))) # p anzeigen
plt.text(150,225,"P = "+str(b.round(3))+" W + "+str(a.round(2))) plt.show()

Wir erhalten aus unseren Testdaten einen Schätzwert für den Parameter mj[ \begin{equation}b\end{equation} ]mj, der mit 2011 Euro pro m² Wohnfläche schon sehr nah an dem Wert liegt, den wir für unseren Immobilienpreisrechner verwendet haben.

Der Achsenabschnittswert, den man für eine Wohnfläche von 0 m² erhält, von 23.930 Euro und die relativ starke Streuung der Messpunkte lassen jedoch vermuten, dass es neben der Wohnfläche noch weitere Einflussgrößen auf den Preis gibt. Tatsächlich haben wir gesehen, dass u.a. die Grundstücksfläche und das Alter der Immobilie einen Einfluss auf den Preis haben. Wenn wir diese Größen in unsere Testdaten mit aufnehmen, können wir jeweils eine weitere lineare Regression des Gesamtpreises mj[ \begin{equation}P\end{equation} ]mj bezüglich der Grundstücksfläche mj[ \begin{equation}G\end{equation} ]mj beziehungsweise des Alters mj[ \begin{equation}A\end{equation} ]mj durchführen und so die jeweiligen Parameterwerte mj[ \begin{equation}c\end{equation} ]mj, mj[ \begin{equation}d\end{equation} ]mj usw. bestimmen.

Der Gesamtpreis setzt sich dann aus der Summe der einzelnen Beiträge zusammen:
mj[ \begin{equation}\mathrm{P}=\mathrm{a}+\mathrm{bW}+\mathrm{cG}+\mathrm{dA}+\ldots\end{equation} ]mj