単純な最小二乗係数を見つけるために「正規方程式」を使用しないのはなぜですか?


17

私はここでこのリストを見ましたが、最小二乗法を解く方法がたくさんあるとは信じられませんでした。ウィキペディアの「正規方程式」は、かなり単純な方法のように思われました:

α^=y¯β^x¯,β^=i=1n(xix¯)(yiy¯)i=1n(xix¯)2

では、なぜそれらを使用しないのですか?マーク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) 

答えはかなり誇張されています。逆数を明示的に計算することを避ければ、それほどひどいことではありません。
mathreadler

3
速度に関するいくつかの注意事項:単一の共変量のみを表示しているため、マトリックス反転のコストは本質的に0です。数千の共変量を見ると、変化します。第二に、共変量は1つしかないため、パッケージ化された競合他社では実際に多くの時間を費やすのはデータ変更です(ただし、これは直線的にしかスケールしないため、大したことではありません)。正規方程式の解法はデータの改ざんを行わないため、高速ですが、結果に付加機能はありません。
クリフAB

回答:


22

問題場合、正規方程式を形成すると、形成によりの条件数を二乗します。大まかに言うと、は、すべてがうまくいった場合に計算で失う桁数です。そして、これは実際には逆行列の形成とは何の関係もありません。がどのように解決されても、桁の精度をすでに失いました。すなわち、正規方程式を形成することで、命中した精度の桁数が2倍になりました。AxbAATAlog10(cond)ATAATAx=ATblog10(cond(ATA))=2log10(cond(A))

条件数が小さい場合(1つが最良の場合)、それほど重要ではありません。条件数=、QRやSVDなどの安定した方法を使用する場合、倍精度で約8桁の精度が得られます。正規方程式を作成する場合、条件数をに2乗しているため、本質的に正確な答えが得られません。1081016

場合によっては、正規方程式を回避できますが、そうでない場合もあります。


2
それを見る簡単な方法(条件数を知らない/気にしない場合)は、あなたが(本質的に)それ自身で何かを掛ける(それを二乗する)ことです。つまり、精度。(Aがスカラーの場合、これはより明白であるはずであり、Aを行列化しても根本的な問題は実際には変わらないことが容易にわかるはずです。)
Mehrdad

精度の違いに加えて、QRと正規方程式の間に大きな速度差もありますか?後者の場合、(X'X)-1 * X'Yを解く可能性がありますが、これは逆であるため低速です。私は、QRがどのように機能するかわからないので、質問します。または、唯一の考慮事項は精度の低下ですか?
サイモン

4
@Simonさて、正規方程式を解くとき、実際には逆行列を形成することはありません。これは遅すぎます。ただし、マトリックスとベクトルを形成し、システムを解く必要があります。A T bATAATb
アント

8

この1つの変数の問題のみを解決する必要がある場合は、先に進み、式を使用します。何も問題はありません。たとえば、組み込みデバイス用にASMで数行のコードを書いているのを見ることができました。実際、状況によってはこの種のソリューションを使用しました。もちろん、この小さな問題を解決するためだけに大きな統計ライブラリをドラッグする必要はありません。

数値の不安定性とパフォーマンスは、より大きな問題と一般的な設定の問題です。多変量最小二乗法などを解く場合、一般的な問題についてはもちろんこれを使用しません。


0

正規方程式で線形回帰を解決する最新の統計パッケージはありません。正規方程式は、統計書にのみ存在します。

行列の逆行列の計算は非常に問題があるため、正規方程式は使用しないでください。

閉形式の数学ソリューションが利用可能な場合、線形回帰に勾配降下を使用する理由は何ですか?

...ただし、直接正規方程式が利用可能です。正規方程式では、行列を反転する必要があることに注意してください。ここで、行列を反転すると、計算にO(N3)がかかります。ここで、NはX行列の行数、つまり観測値です。さらに、Xが悪条件の場合、推定で計算エラーが発生します...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.