2016-04-01 10 views
0

私は線形回帰のために私自身のコードを書こうとしました。普通の方程式beta = inv(X'X)X'Yに従いました。しかし、平方誤差はのlstsq関数よりもはるかに大きくなります。 SVDメソッド(lstsqが使用する)が正規方程式よりも正確である理由は誰にも分かりますか?ありがとうございました最小平方法:正規方程式対svd

+1

再現性の例を教えてください。考えられる理由はいくつかありますが、データがなければ、私はあなたの質問に対する答えを推測することしかできません。 –

答えて

2

あなたのデータはX'Xの行列が高いと思われますcondition number。このような行列の逆数を計算しようとすると、大きな誤差が生じる可能性があります。逆行列を明示的に計算することは、通常はお勧めできません(たとえば、http://www.johndcook.com/blog/2010/01/19/dont-invert-that-matrix/またはhttp://epubs.siam.org/doi/abs/10.1137/1.9780898718027.ch14を参照)。

numpy.linalg.condを使用して条件番号を確認できます。

例を示します。まずXYを作成します。このランダムXのために

In [186]: X = np.random.randn(500, 30) 

In [187]: Y = np.linspace(0, 1, len(X)) 

を、条件数が大きくない:

In [188]: np.linalg.cond(X.T.dot(X)) 
Out[188]: 2.4456380658308148 

正規方程式とlstsqは、同じ結果を与える(numpy.allcloseによると、その関数のデフォルトを使用した場合引数:

In [189]: betan = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y) 

In [190]: betal, res, rnk, s = np.linalg.lstsq(X, Y) 

In [191]: np.allclose(betan, betal) 
Out[191]: True 

今すぐ調整するつの列をほぼ同じにすることによって、を生成します。これはX'Xはほとんど単数形になり、それに大きな条件数を与える:

In [192]: X[:,0] = X[:,1] + 1e-8*np.random.randn(len(X)) 

In [193]: np.linalg.cond(X.T.dot(X)) 
Out[193]: 3954529794300611.5 

今、正規方程式はlstsqとは異なる結果が得られます。

In [194]: betan = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(Y) 

In [195]: betal, res, rnk, s = np.linalg.lstsq(X, Y) 

In [196]: np.allclose(betan, betal) 
Out[196]: False 
関連する問題