Tôi thấy danh sách này ở đây và không thể tin rằng có rất nhiều cách để giải các hình vuông nhỏ nhất. "Phương trình bình thường" trên Wikipedia dường như là một cách khá đơn giản:
Vậy tại sao không sử dụng chúng? Tôi giả định rằng phải có một vấn đề tính toán hoặc chính xác được đưa ra trong liên kết đầu tiên ở trên Mark L. Stone đề cập rằng SVD hoặc QR là các phương pháp phổ biến trong phần mềm thống kê và phương trình bình thường là "TERRIBLE từ độ tin cậy và quan điểm chính xác về số". Tuy nhiên , trong đoạn mã sau, các phương trình bình thường đang cho tôi độ chính xác tới ~ 12 chữ số thập phân khi so sánh với ba hàm python phổ biến: numpy's polyfit ; nữ tu sĩ của scipy ; và scikit-học của hồi quy tuyến tính .
Điều thú vị hơn là phương pháp phương trình bình thường là nhanh nhất khi n = 100000000. Thời gian tính toán đối với tôi là: 2,5 giây cho linregress; 12,9 giây cho polyfit; 4.2s cho linearRegression; và 1,8s cho phương trình bình thường.
Mã số:
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)