2016-08-05 35 views
0

我正在訓練做python的MNIST的PCA重建,並將它們與我在maltab中的(舊)重建進行比較,我偶然發現我的重建不同意。經過一番調試,我決定打印每個主要組件的獨特特徵,以顯示它們是否相同,並且我發現我的驚訝發現它們是而不是相同。我打印所有組件的總和,並得到不同的數字。我做了MATLAB中的以下內容:爲什麼Scipy和MATLAB的主成分值不一致?

[coeff, ~, ~, ~, ~, mu] = pca(X_train); 
U = coeff(:,1:K) 
U_fingerprint = sum(U(:)) 
%print 31.0244 

和在Python/SciPy的:

pca = pca.fit(X_train) 
U = pca.components_ 
print 'U_fingerprint', np.sum(U) 
# prints 12.814 

爲什麼在TWI PCA不是計算相同的值?


我所有的嘗試和解決這個問題:

我發現,這是因爲當我重建我的MNIST圖像的方式,蟒蛇重建那裏受到了很多非常非常接近他們的原始圖像。我在Python中遇到了0.0221556788645的錯誤,而在MATLAB中我得到了尺寸爲29.07578的錯誤。爲了找出差異來自哪裏,我決定手指打印數據集(也許它們是以不同方式歸一化的)。所以,我有兩個獨立的副本MNIST數據集(即是通過把我的255標準化),並得到了指紋(彙總數據集中的所有號碼):

print np.sum(x_train) # from keras 
print np.sum(X_train)+np.sum(X_cv) # from TensorFlow 
6.14628e+06 
6146269.1585420668 

這是(基本上)相同的(一個來自副本張量流MNIST,另一個來自Keras MNIST,注意MNIST訓練數據集有大約1000個訓練集,所以你需要追加缺少的訓練集)。令我驚訝的是,我的MATLAB數據有相同指紋:

data_fingerprint = sum(X_train(:)) 
% prints data_fingerprint = 6.1463e+06 

意味着數據集正是相同。好,所以規範化數據不是問題。

在我的MATLAB腳本其實我手工計算重建如下:

U = coeff(:,1:K) 
X_tilde_train = (U * U' * X_train); 
train_error_PCA = (1/N_train)*norm(X_tilde_train - X_train ,'fro')^2 
%train_error_PCA = 29.0759 

,所以我想是因爲我用的是接口蟒蛇可能是問題了用於計算重建爲:

pca = PCA(n_components=k) 
pca = pca.fit(X_train) 
X_pca = pca.transform(X_train) # M_train x K 
#print 'X_pca' , X_pca.shape 
X_reconstruct = pca.inverse_transform(X_pca) 
print 'tensorflow error: ',(1.0/X_train.shape[0])*LA.norm(X_reconstruct_tf - X_train) 
print 'keras error: ',(1.0/x_train.shape[0])*LA.norm(X_reconstruct_keras - x_train) 
#tensorflow error: 0.0221556788645 
#keras error: 0.0212030354818 

這導致不同的誤差值0.022 vs 29.07,令人震驚的差異!

因此,我決定在我的Python腳本代碼,精確重建式:

pca = PCA(n_components=k) 
pca = pca.fit(X_train) 
U = pca.components_ 
print 'U_fingerprint', np.sum(U) 
X_my_reconstruct = np.dot( U.T , np.dot(U, X_train.T)) 
print 'U error: ',(1.0/X_train.shape[0])*LA.norm(X_reconstruct_tf - X_train) 
# U error: 0.0221556788645 

想不到,它通過使用該接口具有相同的錯誤作爲我MNIST誤差計算。因此,得出結論我不認爲我有我的PCA的誤解。

所有這些都導致我檢查主要組件的實際位置以及令我驚訝的scipy和MATLAB的PCA值有不同的指紋。

有誰知道爲什麼或什麼事情發生?


沃倫建議,在PCA分量(特徵向量)可能有不同的標誌。在幅度將所有組件做一個指紋後只有我發現它們具有相同的指紋:

[coeff, ~, ~, ~, ~, mu] = pca(X_train); 
K=12; 
U = coeff(:,1:K) 
U_fingerprint = sumabs(U(:)) 
% U_fingerprint = 190.8430 

和蟒蛇:

k=12 
pca = PCA(n_components=k) 
pca = pca.fit(X_train) 
print 'U_fingerprint', np.sum(np.absolute(U)) 
# U_fingerprint 190.843 

這意味着差必須因(pca)U矢量的不同符號。我覺得這很令人驚訝,我認爲這應該會有很大的變化,我甚至沒有考慮到它會產生很大的變化。我猜我錯了?

+0

兩個版本有多少個組件會返回?比較文件,這可能是一個可能解釋觀察到的行爲的差異點。 – rubenvb

+0

@rubenvb他們都是12(顯然是相同的,否則這將是愚蠢的錯誤,我將在明天早上提供github代碼以供人們判斷腳本)。 –

+0

在MATLAB變量是列市長和在python行市長。確保你沒有計算轉置矩陣中的PCA。 –

回答

2

我不知道這是否是問題,但肯定可以。主分量向量就像特徵向量:如果將向量乘以-1,它仍然是一個有效的PCA向量。由matlab計算的一些矢量可能與python中計算的矢量的符號不同。這將導致非常不同的總和。

例如,MATLAB文檔有這個例子:

coeff = pca(ingredients) 

coeff = 

    -0.0678 -0.6460 0.5673 0.5062 
    -0.6785 -0.0200 -0.5440 0.4933 
    0.0290 0.7553 0.4036 0.5156 
    0.7309 -0.1085 -0.4684 0.4844 

我有自己的python PCA代碼,並用相同的輸入作爲在MATLAB中,它產生此係數數組:

[[ 0.0678 0.646 -0.5673 0.5062] 
[ 0.6785 0.02 0.544 0.4933] 
[-0.029 -0.7553 -0.4036 0.5156] 
[-0.7309 0.1085 0.4684 0.4844]] 

因此,不要簡單地對係數數組進行求和,而應該對係數的絕對值求和。或者,在求和之前確保所有矢量具有相同的符號約定。例如,可以通過將每列乘以該列中第一個元素的符號(假設它們都不爲零)來實現。

+0

好像兩個主要組件矩陣(特徵向量)具有相同的指紋,現在我按照您的建議計算了絕對值的新指紋。這是否意味着重建計算錯誤,因爲特徵向量的符號不一致? –

+0

這個標誌不應該有所作爲,因爲重建是通過X_reconstruct = U * U.T * X來完成的,它可以消除符號。 –

+1

如果仔細查看我的代碼,可以注意到我計算的是規範2的損失,但是然後將它平方根(或者我猜測更精確地不是平方),另一個計算平方誤差,但是我平方誤差。其中考慮到了差異。感謝您的幫助! :d –

相關問題