2017-12-14 6 views
0

私は画像using this code by AlyssaのPCAをpythonで計算しようとしています。最初の2つの主成分が逆転します

# Read the image into palmFingers_mask: 
# we use PCA and otain 2 principal components 
y, x = np.nonzero(palmFingers_mask) 
# Subtract mean from each dimension 
x = x - np.mean(x) 
y = y - np.mean(y) 
coords = np.vstack([x, y]) 
# Covariance matrix and its eigenvectors and eigenvalues 
cov = np.cov(coords) 
evals[:,frm_cnt], evecs = np.linalg.eig(cov) 
# Sort eigenvalues in decreasing order 
sort_indices = np.argsort(evals[:,frm_cnt])[::-1] 
evec1[:,frm_cnt], evec2[:,frm_cnt] = evecs[:, sort_indices] 
x_v1, y_v1 = evec1[:,frm_cnt] # Eigenvector with largest eigenvalue 
x_v2, y_v2 = evec2[:,frm_cnt] 
# Plot the principal components 
scale = 20 
plt.figure(1) 
plt.plot(x, y, 'y.') 
plt.plot([x_v1*-scale*2, x_v1*scale*2], 
       [y_v1*-scale*2, y_v1*scale*2], color='red') 
plt.plot([x_v2*-scale, x_v2*scale], 
       [y_v2*-scale, y_v2*scale], color='blue') 
plt.axis('equal') 
plt.gca().invert_yaxis() # Match the image system with origin at top left 
plt.show() 

I(赤が大きい成分であり、線の長さは何も意味しない)赤と青の線を有する2つの軸をマークします。

そうすることが、私は以下の通り、1故障した場合に出くわした:

enter image description here

どのようにそれが可能になることができますか?これは、赤の固有ベクトルが大きいことを示していますが、直観的には、そうではありません。軸(青い線に沿って)は、より大きなものでなければなりません。私のデータベースの他のすべての画像については、軸が適切であるとわかります。このイメージの場合にのみ、それは交換されます。入力画像を添付しました(Img 209.png)

私の理解に間違いはありますか?

これは私が期待するものである:例えば

enter image description here

、私はそれが働くためBinImg_20.pngを添付しています。

Attached files are on Dropbox

答えて

2

私はこの問題はここだと思います。この時点で

evec1, evec2 = evecs[:, sort_indices] 

あなたは

evecs = [[ 0.70926191 0.70494507] 
     [-0.70494507 0.70926191]] 
evec1 = [ 0.70926191 0.70494507] 
evec2 = [-0.70494507 0.70926191] 

sort_indicesによってインデックスが正しくをソートしています。しかし、アンパックアサインをでアンパックすると、間違いが発生します。

述べ見るthe documentation for numpy.linalg.eig

vを:(...、M、M)アレイ - 正規化(単位「長さ」)カラムv[:,i]は対応する固有ベクトルであるように固有ベクトル固有値w[i]

そしてtutorial書込み:多次元配列上

を反復は、私は、Rの一部のクロスチェックを行った第一軸に対して


で行われますそのような計算が正常であり、固有ベクトルが期待どおりであることを確認してください。あなたが興味を持っている場合には、ここからの入力と出力があり、Rは1ベースのインデックス作成を行うので、中心が1つずれています。ここで

> install.packages("pixmap") 
> library(pixmap) 
> pix <- read.pnm("BinImg_209.pbm") 
> mask = which([email protected] != 0, arr.ind=T) 
> mask = data.frame(x=mask[,"col"], y=mask[,"row"]) 
> prcomp(mask)   # single step principal component analysis 
Standard deviations (1, .., p=2): 
[1] 117.84952 44.23114 

Rotation (n x k) = (2 x 2): 
     PC1  PC2 
x 0.7092619 0.7049451 
y -0.7049451 0.7092619 

> cov <- cov.wt(mask) # manual covariance computation 
> cov     # show computed data 
$cov 
      x   y 
x 7958.874 -5965.947 
y -5965.947 7886.030 

$center 
     x  y 
593.1907 519.1019 

$n.obs 
[1] 47909 

> eigen(cov$cov)  # manual computation of eigenvectors 
eigen() decomposition 
$values 
[1] 13888.510 1956.394 

$vectors 
      [,1]  [,2] 
[1,] -0.7092619 -0.7049451 
[2,] 0.7049451 -0.7092619 

、あまりにも、vectors行列のは固有ベクトルです。 prcompの回転行列は、より明確にラベル付けされています。列は主成分であり、行は元の座標です。

+0

ブログページの変更提案:https://github.com/alyssaq/alyssaq.github.io/pull/4 – MvG

関連する問題