sklearn 的 PCA.fit_transform 结果与产品 PCA.components_ 和输入数据不匹配

Sel*_*lah 1 numpy linear-algebra pca scikit-learn

我正在尝试使用 sklearn 的 PCA 功能将我的数据减少到二维。但是,我注意到当我使用 fit_transform() 函数执行此操作时,结果与 elements_ 属性与输入数据相乘的结果不匹配。

为什么这些不匹配?哪个结果是正确的?

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!!!
Run Code Online (Sandbox Code Playgroud)

Ima*_*ngo 5

您缺少的唯一步骤(sklearn在内部处理)是数据居中。为了执行 PCA,您的数据需要居中,如果不是,sklearn 的 PCA 拟合方法的第一行之一是:

X -= X.mean(axis=0) 
Run Code Online (Sandbox Code Playgroud)

它将您的数据沿第一个轴居中。

为了获得与 sklearn 相同的结果(这是正确的结果),您只需在 fit 之前或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
Run Code Online (Sandbox Code Playgroud)

请注意,我.dot在标准 numpy 数组上使用而不是*在 numpy 矩阵中使用,因为我更愿意尽可能避免使用matrix,但结果是相同的。