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:
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)