Warum nicht die „normalen Gleichungen“ verwenden, um einfache Koeffizienten kleinster Quadrate zu finden?

17

Ich habe diese Liste hier gesehen und konnte nicht glauben, dass es so viele Möglichkeiten gibt, die kleinsten Quadrate zu lösen. Die "normalen Gleichungen" in Wikipedia schienen ein recht einfacher Weg zu sein:

α^=y¯-β^x¯,β^=ich=1n(xich-x¯)(yich-y¯)ich=1n(xich-x¯)2

Warum also nicht einfach benutzen? Ich ging davon aus, dass es ein Rechenproblem oder ein Präzisionsproblem geben muss, da Mark L. Stone im ersten Link oben erwähnt, dass SVD oder QR beliebte Methoden in statistischer Software sind und die normalen Gleichungen unter dem Gesichtspunkt der Zuverlässigkeit und numerischen Genauigkeit "SCHRECKLICH" sind. Im folgenden Code geben mir die normalen Gleichungen jedoch eine Genauigkeit von ~ 12 Dezimalstellen im Vergleich zu drei gängigen Python-Funktionen: numpy's polyfit ; scipys linregress ; und Scikit-Learn die Lineare Regression .

Interessanter ist, dass die normale Gleichungsmethode am schnellsten ist, wenn n = 100000000. Die Rechenzeiten für mich sind: 2.5s für linregress; 12,9s für polyfit; 4.2s für LinearRegression; und 1,8s für die normale Gleichung.

Code:

import numpy as np
from sklearn.linear_model import LinearRegression
from scipy.stats import linregress
import timeit

b0 = 0
b1 = 1
n = 100000000
x = np.linspace(-5, 5, n)
np.random.seed(42)
e = np.random.randn(n)
y = b0 + b1*x + e

# scipy                                                                                                                                     
start = timeit.default_timer()
print(str.format('{0:.30f}', linregress(x, y)[0]))
stop = timeit.default_timer()
print(stop - start)

# numpy                                                                                                                                      
start = timeit.default_timer()
print(str.format('{0:.30f}', np.polyfit(x, y, 1)[0]))
stop = timeit.default_timer()
print(stop - start)

# sklearn                                                                                                                                    
clf = LinearRegression()
start = timeit.default_timer()
clf.fit(x.reshape(-1, 1), y.reshape(-1, 1))
stop = timeit.default_timer()
print(str.format('{0:.30f}', clf.coef_[0, 0]))
print(stop - start)

# normal equation                                                                                                                            
start = timeit.default_timer()
slope = np.sum((x-x.mean())*(y-y.mean()))/np.sum((x-x.mean())**2)
stop = timeit.default_timer()
print(str.format('{0:.30f}', slope))
print(stop - start) 
Oliver Angelil
quelle
Die Antworten sind ziemlich übertrieben. Es ist nicht so schlimm, wenn Sie es einfach vermeiden, die Inverse explizit zu berechnen.
Kathreadler
3
Ein paar Anmerkungen zur Geschwindigkeit: Sie betrachten nur eine einzige Kovariate, die Kosten für die Matrixinversion betragen also im Wesentlichen 0. Wenn Sie sich ein paar tausend Kovariaten ansehen, ändert sich dies. Zweitens, da Sie nur eine einzige Kovariate haben, nimmt das Daten-Munging bei den Konkurrenten im Paket viel Zeit in Anspruch (dies sollte jedoch nur linear skaliert werden, also keine große Sache sein). Die normale Gleichungslösung führt kein Mungo durch, ist also schneller, hat aber keine Schnickschnack mit den Ergebnissen.
Cliff AB

Antworten:

22

EINxbEINEINTEINlÖG10(cÖnd)EINTEINEINTEINx=EINTblÖG10(cÖnd(EINTEIN))=2lÖG10(cÖnd(EIN))

1081016

Manchmal kommt man mit den Normalgleichungen durch und manchmal nicht.

Mark L. Stone
quelle
2
Eine einfachere Möglichkeit, dies zu sehen (wenn Sie sich nicht mit Bedingungsnummern auskennen / auskennen), besteht darin, dass Sie (im Wesentlichen) etwas mit sich selbst multiplizieren (es "quadrieren"), was bedeutet, dass Sie damit rechnen können, dass Sie ungefähr die Hälfte Ihrer Teile verlieren Präzision. (Dies sollte offensichtlicher sein, wenn A ein Skalar ist, und es sollte leicht zu erkennen sein, dass die Erstellung einer Matrix das zugrunde liegende Problem nicht wirklich ändert.)
Mehrdad,
Gibt es neben den Genauigkeitsunterschieden auch einen großen Geschwindigkeitsunterschied zwischen QR- und normalen Gleichungen? weil im letzteren Fall möglicherweise (X'X) -1 * X'Y aufgelöst wird, was aufgrund der Umkehrung langsam ist? Ich frage, weil ich nicht sicher bin, wie QR funktioniert. Vielleicht gibt es dort etwas, das genauso langsam ist wie das Invertieren einer Matrix. Oder ist der einzige Gesichtspunkt der Genauigkeitsverlust?
Simon
4
EINTEINEINTb
8

Wenn Sie nur dieses eine variable Problem lösen müssen, verwenden Sie die Formel. Daran ist nichts auszusetzen. Ich könnte sehen, dass Sie in ASM einige Codezeilen für ein eingebettetes Gerät schreiben. Tatsächlich habe ich diese Art von Lösung in einigen Situationen verwendet. Sie müssen natürlich keine großen statistischen Bibliotheken ziehen, um dieses eine kleine Problem zu lösen.

Die numerische Instabilität und Leistung sind Probleme größerer Probleme und allgemeiner Einstellungen. Wenn Sie multivariate kleinste Quadrate usw. lösen, würden Sie dies für ein allgemeines Problem natürlich nicht verwenden.

Aksakal
quelle
0

Kein modernes statistisches Paket würde eine lineare Regression mit den normalen Gleichungen lösen. Die normalen Gleichungen existieren nur in den statistischen Büchern.

Die normalen Gleichungen sollten nicht verwendet werden, da die Berechnung der Inverse der Matrix sehr problematisch ist.

Warum Gradientenabstieg für lineare Regression verwenden, wenn eine geschlossene mathematische Lösung verfügbar ist?

... obwohl die direkte Normalgleichung verfügbar ist. Beachten Sie, dass man in einer normalen Gleichung eine Matrix invertieren muss. Jetzt kostet das Invertieren einer Matrix O (N3) für die Berechnung, wobei N die Anzahl der Zeilen in der X-Matrix ist, dh die Beobachtungen. Wenn das X schlecht konditioniert ist, führt es außerdem zu Rechenfehlern bei der Schätzung ...

Kleinschach
quelle