Saya melihat daftar ini di sini dan tidak percaya ada begitu banyak cara untuk menyelesaikan kuadrat terkecil. "Persamaan normal" di Wikipedia tampaknya merupakan cara yang cukup lurus ke depan:
Jadi mengapa tidak menggunakannya saja? Saya berasumsi pasti ada masalah komputasi atau presisi mengingat bahwa dalam tautan pertama di atas Mark L. Stone menyebutkan bahwa SVD atau QR adalah metode populer dalam perangkat lunak statistik dan bahwa persamaan normal adalah "TERRIBLE dari keandalan dan sudut pandang akurasi numerik". Namun , dalam kode berikut, persamaan normal memberi saya akurasi hingga ~ 12 tempat desimal bila dibandingkan dengan tiga fungsi python populer: polyfit numpy ; linregress scipy ; dan LinearRegression scikit- learn .
Yang lebih menarik adalah bahwa metode persamaan normal adalah yang tercepat ketika n = 100000000. Waktu komputasi bagi saya adalah: 2,5 detik untuk linregress; 12.9 untuk polyfit; 4.2s untuk LinearRegression; dan 1,8 untuk persamaan normal.
Kode:
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)