私はここでこのリストを見ましたが、最小二乗法を解く方法がたくさんあるとは信じられませんでした。ウィキペディアの「正規方程式」は、かなり単純な方法のように思われました:
では、なぜそれらを使用しないのですか?マークLの上の最初のリンクで、SVDまたはQRは統計ソフトウェアで一般的な方法であり、正規方程式は「信頼性と数値精度の観点からは劣っています」と述べていることから、計算または精度の問題があるに違いないと思いました。ただし、次のコードでは、3つの一般的なpython関数と比較すると、正規方程式により小数点以下12桁までの精度が得られます。numpy's polyfit ; scipy's linregress ; およびscikit-learnのLinearRegression。
さらに興味深いのは、n = 100000000の場合に正規方程式法が最速であることです。私にとっての計算時間は次のとおりです。polyfitの場合は12.9秒。LinearRegressionの4.2秒。正規方程式の場合は1.8秒。
コード:
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)