2015-10-06 414 views
0

我試圖使用sklearn的PCA功能將我的數據減少到2維。但是,我注意到當我使用fit_transform()函數執行此操作時,結果與將components_屬性與我的輸入數據相乘的結果不匹配。sklearn的PCA.fit_transform結果與產品PCA.components_和輸入數據不匹配

爲什麼這些不匹配?哪個結果是正確的?

def test_pca_fit_transform(self): 
    from sklearn.decomposition import PCA 
    input_data = np.matrix([[11,4,9,3,2,2], [7,2,8,2,0,2], [3,1,2,5,2,9]]) 
    #each column of input data is an observation, each row is a dimension 

    #method1 
    pca = PCA(n_components=2) 
    data2d = pca.fit_transform(input_data.T) 

    #method2 
    component_matrix = np.matrix(pca.components_) 
    data2d_mult = (component_matrix * input_data).T 

    np.testing.assert_almost_equal(data2d, data2d_mult) 
    #FAILS!!! 

回答

0

您唯一缺少的內容(其中sklearn內部處理)是數據集中。爲了執行PCA需要你的數據爲中心,如果它不是,sklearn的PCA的擬合方法的第一行之一是:

X -= X.mean(axis=0) 

沿第一軸中心的數據。

爲了達到與sklearn(這是正確的)相同的結果,您只需要在合適之前或在您的method2之前居中數據。

在這裏找到工作的例子:

X = np.array([[11,4,9,3,2,2], [7,2,8,2,0,2], [3,1,2,5,2,9]]) 
X = X.T.copy() 

# PCA 
pca = PCA(n_components=2) 
data = pca.fit_transform(X) 

# Your method 2 
data2 = X.dot(pca.components_.T) 

# Centering the data before method 2 
data3 = X - X.mean(axis=0) 
data3 = data3.dot(pca.components_.T) 

# Compare 
print np.allclose(data, data2) # prints False 
print np.allclose(data, data3) # prints True 

請注意,我在標準numpy的陣列,而不是*在numpy的矩陣使用.dot因爲我更喜歡避免使用matrix只要有可能,但結果是一樣的。

相關問題