Zum Hauptinhalt springen

4.3 Multiple lineare Regression & Normalengleichung

Mehrere Eingabegrößen​

Meist hängt die Zielgröße von mehreren Merkmalen ab. Beispiel auf 📄 04_linear_methods_ws26.pdf, Folie 16: Der Advertising-Datensatz mit 200 Zeilen, Werbeausgaben für TV, Radio und Zeitung (Newspaper) sowie die erzielten Verkäufe (Sales). Das Modell:

sales^=1⋅w0+w1 TV+w2 Radio+w3 Newspaper\widehat{\text{sales}} = 1\cdot w_0 + w_1\,\text{TV} + w_2\,\text{Radio} + w_3\,\text{Newspaper}

Das ist multiple (auch multivariate) lineare Regression (multiple linear regression).

Matrixschreibweise und Designmatrix​

📄 04_linear_methods_ws26.pdf, Folie 17 Man schreibt die Daten in eine Matrix, eine Zeile pro Beobachtung, eine Spalte pro Merkmal, und ergänzt vorne eine Spalte aus Einsen (Intercept). Diese Matrix heißt Designmatrix (design matrix) XX:

(1230,137,869,2144,539,345,1117,245,969,3⋮⋮⋮⋮)⏟X  (200×4)(w0w1w2w3)⏟w=(20,2412,4312,31⋮)⏟y^vgl. y=(22,110,49,3⋮)\underbrace{\begin{pmatrix} 1 & 230{,}1 & 37{,}8 & 69{,}2\\ 1 & 44{,}5 & 39{,}3 & 45{,}1\\ 1 & 17{,}2 & 45{,}9 & 69{,}3\\ \vdots & \vdots & \vdots & \vdots \end{pmatrix}}_{X \;(200\times 4)} \underbrace{\begin{pmatrix} w_0\\ w_1\\ w_2\\ w_3\end{pmatrix}}_{\boldsymbol w} = \underbrace{\begin{pmatrix} 20{,}24\\ 12{,}43\\ 12{,}31\\ \vdots\end{pmatrix}}_{\hat{\boldsymbol y}} \qquad \text{vgl. } \boldsymbol y = \begin{pmatrix} 22{,}1\\ 10{,}4\\ 9{,}3\\ \vdots\end{pmatrix}

Kompakt: X⋅w=y^X\cdot\boldsymbol w = \hat{\boldsymbol y}. Eine einzige Matrix-Vektor-Multiplikation liefert alle 200 Vorhersagen.

Warum die Einserspalte? Für Zeile ii ergibt die Multiplikation 1⋅w0+xi1w1+…1\cdot w_0 + x_{i1}w_1 + \dots, der Achsenabschnitt wird also automatisch addiert. So muss man bb nicht gesondert behandeln.

Das Modell allgemein​

📄 04_linear_methods_ws26.pdf, Folie 18 Mit dd Merkmalen:

y^=fθ(x)=1⋅w0+w1x1+w2x2+⋯+wdxd=∑j=1dwjxj+w0=wTx+w0=⟨w,x⟩+w0\hat y = f_\theta(x) = 1\cdot w_0 + w_1x_1 + w_2x_2 + \dots + w_dx_d = \sum_{j=1}^d w_jx_j + w_0 = \boldsymbol w^T\boldsymbol x + w_0 = \langle\boldsymbol w, \boldsymbol x\rangle + w_0
  • Als neuronales Netz: ein Neuron mit Eingängen 1,x1,…,xd1, x_1, \dots, x_d, Gewichten w0,…,wdw_0, \dots, w_d und Summe Σ\Sigma, keine Aktivierung.
  • Geometrisch: Bei einem Merkmal ist fθf_\theta eine Gerade, bei zwei Merkmalen eine Ebene im 3D-Raum, bei dd Merkmalen eine Hyperebene im (d+1)(d+1)-dimensionalen Raum. Die Residuen sind die senkrechten (in yy-Richtung gemessenen) Abstände der Punkte zur Ebene.

Notation​

Die Literatur ist hier uneinheitlich 📄 04_linear_methods_ws26.pdf, Folie 19:

  • w0w_0 heißt oft bb (Bias).
  • Oft steckt der Bias mit im Gewichtsvektor, wT=(w0,w1,…,wd)\boldsymbol w^T = (w_0, w_1, \dots, w_d), und x\boldsymbol x bekommt eine führende 1 („erweiterte Datenmatrix“). Dann gilt einfach y^=w⋅x\hat y = \boldsymbol w\cdot\boldsymbol x.
  • In der Statistikliteratur (Tibshirani u. a.) heißt der Gewichtsvektor β\boldsymbol\beta.
  • Häufig werden die Vektorpfeile/Fettdruck weggelassen.

Einsteinsche Summenkonvention​

Eine Kurzschrift, die auf den nächsten Folien verwendet wird: Über doppelt auftretende Indizes wird summiert, das Summenzeichen lässt man weg.

y^i=∑j=0pXijwj=Xijwj\hat y_i = \sum_{j=0}^p X_{ij}w_j = X_{ij}w_j

In NumPy entspricht das np.einsum('ij,j->i', X, w), also schlicht X @ w.

Laut Feedback-Folie 36 ist die Summenkonvention „nicht soo wichtig“. Wichtig ist nur, die Herleitung unten nachvollziehen zu können. Im Folgenden werden die Summen deshalb ausgeschrieben.

Herleitung der Normalengleichung​

📄 04_linear_methods_ws26.pdf, Folie 20 und 📄 04_linear_methods_ws26.pdf, Folie 21 leiten die geschlossene Lösung in vier Schritten her.

Schritt 1: Verlustfunktion​

Summe der quadrierten Fehler (der Faktor 1n\frac1n ändert die Lage des Minimums nicht und wird weggelassen):

L=∑i(y^i−yi)2=∑i(∑jXijwj−yi)2L = \sum_i (\hat y_i - y_i)^2 = \sum_i\Big(\sum_j X_{ij}w_j - y_i\Big)^2

Schritt 2: Ableiten nach einem Gewicht wkw_k​

Kettenregel: äußere Ableitung von (⋅)2(\cdot)^2 ist 2(⋅)2(\cdot), dann mal innere Ableitung.

∂L∂wk=2∑i(∑jXijwj−yi)⋅∂∂wk(∑jXijwj−yi)\frac{\partial L}{\partial w_k} = 2\sum_i\Big(\sum_j X_{ij}w_j - y_i\Big)\cdot\frac{\partial}{\partial w_k}\Big(\sum_j X_{ij}w_j - y_i\Big)

Die innere Ableitung: In ∑jXijwj=Xi0w0+Xi1w1+…\sum_j X_{ij}w_j = X_{i0}w_0 + X_{i1}w_1 + \dots hängt nur ein Summand von wkw_k ab, nämlich XikwkX_{ik}w_k. Alle anderen fallen weg, yiy_i auch:

∂∂wk(∑jXijwj−yi)=∑jXij δjk=Xik\frac{\partial}{\partial w_k}\Big(\sum_j X_{ij}w_j - y_i\Big) = \sum_j X_{ij}\,\delta_{jk} = X_{ik}

(δjk\delta_{jk} ist das Kronecker-Delta: 1 für j=kj = k, sonst 0. Die Folie schreibt δkjXij\delta_{kj}X_{ij} unter die Klammer.) Also:

∂L∂wk=2∑i(∑jXijwj−yi)Xik\frac{\partial L}{\partial w_k} = 2\sum_i\Big(\sum_j X_{ij}w_j - y_i\Big)X_{ik}

Ergänzung: In Matrixform ist das die kk-te Komponente von

∇wL=2XT(Xw−y).\nabla_{\boldsymbol w}L = 2X^T(X\boldsymbol w - \boldsymbol y).

Das ist auch der Gradient, den man für Gradientenabstieg braucht. Intuition: Xw−yX\boldsymbol w - \boldsymbol y ist der Vektor der Residuen, XTX^T gewichtet jedes Residuum mit dem zugehörigen Merkmalswert.

Die Folie bemerkt, dass die direkte Vektorschreibweise „scary and error-prone“ ist. Deshalb die Herleitung über Indizes.

Schritt 3: Gradient gleich null setzen​

∂L∂wk=0  ⟹  ∑i∑jXikXijwj=∑iXikyifu¨r alle k\frac{\partial L}{\partial w_k} = 0 \;\Longrightarrow\; \sum_i\sum_j X_{ik}X_{ij}w_j = \sum_i X_{ik}y_i \quad\text{für alle } k

Links steht ∑j(XTX)kjwj\sum_j (X^TX)_{kj}w_j, denn (XTX)kj=∑iXikXij(X^TX)_{kj} = \sum_i X_{ik}X_{ij}. Rechts steht (XTy)k(X^T\boldsymbol y)_k. Für alle kk gleichzeitig:

XTX w=XTy\boxed{X^TX\,\boldsymbol w = X^T\boldsymbol y}

Das ist die Normalengleichung (normal equation), ein lineares Gleichungssystem mit so vielen Gleichungen wie Gewichten.

Schritt 4: Auflösen​

Falls XTXX^TX invertierbar ist:

w=(XTX)−1XTy\boxed{\boldsymbol w = (X^TX)^{-1}X^T\boldsymbol y}
Warum „Normalen“gleichung?

Ergänzung, nicht auf den Folien: Umgestellt lautet sie XT(y−Xw)=0X^T(\boldsymbol y - X\boldsymbol w) = \boldsymbol 0. Der Residuenvektor steht also senkrecht (normal) auf allen Spalten von XX. Geometrisch ist y^=Xw\hat{\boldsymbol y} = X\boldsymbol w die Orthogonalprojektion von y\boldsymbol y auf den Raum, den die Spalten von XX aufspannen. Der kürzeste Abstand zu einem Unterraum ist immer der senkrechte.

Durchgerechnetes Beispiel​

Ergänzung, nicht auf den Folien: Die drei Punkte (1,2)(1,2), (2,3)(2,3), (3,5)(3,5) aus 4.1:

X=(111213),y=(235),XTX=(36614),XTy=(1023)X = \begin{pmatrix} 1 & 1\\ 1 & 2\\ 1 & 3\end{pmatrix},\quad \boldsymbol y = \begin{pmatrix}2\\3\\5\end{pmatrix},\quad X^TX = \begin{pmatrix} 3 & 6\\ 6 & 14\end{pmatrix},\quad X^T\boldsymbol y = \begin{pmatrix} 10\\ 23\end{pmatrix}

(XTXX^TX enthält nn, ∑xi\sum x_i und ∑xi2\sum x_i^2; XTyX^T\boldsymbol y enthält ∑yi\sum y_i und ∑xiyi\sum x_iy_i.) Mit det⁡(XTX)=42−36=6\det(X^TX) = 42 - 36 = 6:

(XTX)−1=16(14−6−63),w=16(140−138−60+69)=(1/33/2)(X^TX)^{-1} = \frac16\begin{pmatrix} 14 & -6\\ -6 & 3\end{pmatrix},\qquad \boldsymbol w = \frac16\begin{pmatrix} 140 - 138\\ -60 + 69\end{pmatrix} = \begin{pmatrix} 1/3\\ 3/2\end{pmatrix}

Also w0=b=1/3w_0 = b = 1/3 und w1=a=1,5w_1 = a = 1{,}5, wie in 4.1 und mit Gradientenabstieg in 4.2.

Wann ist XTXX^TX nicht invertierbar?​

Ergänzung, nicht auf den Folien (wichtig zum Verständnis von Ridge in 4.4):

  • Mehr Parameter als Datenpunkte (p>np > n): XTXX^TX ist p×pp\times p, hat aber höchstens Rang nn. Es gibt dann unendlich viele Lösungen, die die Daten perfekt treffen.
  • Linear abhängige Spalten (perfekte Kollinearität), z. B. ein Merkmal doppelt, einmal in Metern und einmal in Zentimetern.
  • Fast abhängige Spalten machen XTXX^TX schlecht konditioniert: Kleine Änderungen in den Daten verändern w\boldsymbol w stark.

In Python​

Die Folien verweisen auf das Notebook linear_methods/LinearRegression.ipynb 📄 04_linear_methods_ws26.pdf, Folie 23.

Ergänzung: Typische Varianten:

import numpy as np
from sklearn.linear_model import LinearRegression

X1 = np.column_stack([np.ones(len(X)), X]) # Einserspalte anhängen

w = np.linalg.inv(X1.T @ X1) @ X1.T @ y # wörtlich die Formel
w = np.linalg.solve(X1.T @ X1, X1.T @ y) # besser: LGS lösen
w, *_ = np.linalg.lstsq(X1, y, rcond=None) # am stabilsten

model = LinearRegression().fit(X, y) # fügt den Intercept selbst hinzu
model.intercept_, model.coef_
Fallstrick: Inverse explizit berechnen

Die Formel (XTX)−1XTy(X^TX)^{-1}X^T\boldsymbol y ist zum Herleiten gedacht. Numerisch ist es besser, das Gleichungssystem zu lösen (solve) oder direkt ein Kleinste-Quadrate-Verfahren (lstsq, QR-Zerlegung) zu verwenden, weil das Bilden von XTXX^TX die Kondition quadriert. Und bei LinearRegression aus scikit-learn keine eigene Einserspalte anhängen, der Intercept wird automatisch geschätzt.