2015-01-05 25 views
15

特異値分解M = USV *を考慮してください。そして、M * Mの固有値分解は、M * M = V(S * S)V * = VS * U * USV *を与える。numpyのeighとsvdで計算された固有ベクトルは一致しません

import numpy as np 
np.random.seed(42) 
# create mean centered data 
A=np.random.randn(50,20) 
M= A-np.array(A.mean(0),ndmin=2) 

# svd 
U1,S1,V1=np.linalg.svd(M) 
S1=np.square(S1) 
V1=V1.T 

# eig 
S2,V2=np.linalg.eigh(np.dot(M.T,M)) 
indx=np.argsort(S2)[::-1] 
S2=S2[indx] 
V2=V2[:,indx] 

# both Vs are in orthonormal form 
assert np.all(np.isclose(np.linalg.norm(V1,axis=1), np.ones(V1.shape[0]))) 
assert np.all(np.isclose(np.linalg.norm(V1,axis=0), np.ones(V1.shape[1]))) 
assert np.all(np.isclose(np.linalg.norm(V2,axis=1), np.ones(V2.shape[0]))) 
assert np.all(np.isclose(np.linalg.norm(V2,axis=0), np.ones(V2.shape[1]))) 

assert np.all(np.isclose(S1,S2)) 
assert np.all(np.isclose(V1,V2)) 

は、最後のアサーションは失敗します。私はeigh関数によって返された固有ベクトルはsvd関数によって返されたものと同じであることを示すことによってnumpyのこの平等性を検証したいです。どうして?

+0

を回転させることがあります全ての対角要素に対して正の数、すなわち、M2 = M + a * Iとする。ここで、aはM2正のセミフィーデイトを作るのに十分大きい。その後、SVDとEighは良く一致するはずです。 –

答えて

14

問題をデバッグするには、小さな番号で試してみてください。

代わりに、私のランダムな場合にはサイズ(50,20)

であなたもはるかに大きい行列のA=np.random.randn(3,2)とのスタートは、私が

v1 = array([[-0.33872745, 0.94088454], 
    [-0.94088454, -0.33872745]]) 

v2のためのことを見つける:

v2 = array([[ 0.33872745, -0.94088454], 
    [ 0.94088454, 0.33872745]]) 

彼らだけのために異なります記号であり、明らかに単位モジュールを持つように正規化されていても、ベクトルは記号のために異なっていてもよい。あなたは、元の大行列のため

assert np.all(np.isclose(V1,-1*V2)) 

トリックをしようとした場合

は今、それが失敗した...再び、これはOKです。何が起きるかは、いくつかのベクトルに-1が掛け合わされたものと、他のものが掛け合わされていないものがあります。

ベクトル間の等価性をチェックする正しい方法は次のとおりです。

assert allclose(abs((V1*V2).sum(0)),1.) 

と確かに、これはあなたがこの量を印刷することができますどのように動作するかの感覚を得るために:

(V1*V2).sum(0) 

確かにベクターに依存+1-1次のいずれか

array([ 1., -1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 
    1., -1., 1., 1., 1., -1., -1.]) 

EDIT:これは、ほとんどの場合、特にランダムな行列から開始する場合に発生します。一つ以上の固有値が1よりも大きな寸法の固有空間を持っている場合は、以下の彼のコメントに@Sven Marnachで指摘したように、このテストはおそらく、失敗することただし注意してください:

だけを乗じたベクターよりも他の違いがあるかもしれません-1。 固有値のいずれかが多次元の固有空間を持っている場合は、あなた は、その固有空間の任意の正規直交基底を得るかもしれない、と に、このような塩基はarbitraty ユニテリアン行列によって互いにあなたが追加することができます

+0

@matus大丈夫、私は失われています:)しかし、私はあなたの判断を信じているので、私は将来の読者を混乱させないように私のコメントを削除します。乾杯! – BartoszKP

+0

ベクトルに-1を掛けたもの以外の違いがあるかもしれません。固有値のいずれかが多次元固有空間を持つ場合、その固有空間の任意の正規直交基底を得ることができ、そのような基底に対しては、仲裁ユニタリアン行列によって互いに回転させることができる。 –

+0

@SvenMarnach、これは非常に有効なポイントです。この警告を指摘するために投稿を編集します – gg349

関連する問題