我试图检查我的PCA实现,看看我是否理解它,并且我尝试在MNIST数据集上使用12个组件进行PCA(我使用的tensorflow接口为我标准化了它)。我获得了sklearn给出的主要成分,然后进行了如下重构:
pca = PCA(n_components=k)
pca = pca.fit(X_train)
X_pca = pca.transform(X_train)
# do manual PCA
U = pca.components_
my_reconstruct = np.dot( U.T , np.dot(U, X_train.T) ).T
然后我使用了sklearn给出的重建接口来尝试重建如下:
pca = PCA(n_components=k)
pca = pca.fit(X_train)
X_pca = pca.transform(X_train)
X_reconstruct = pca.inverse_transform(X_pca)
然后检查错误如下(因为行是数据点和列的功能):
print 'X_recon - X_my_reconstruct', (1.0/X_my_reconstruct.shape[0])*LA.norm(X_my_reconstruct - X_reconstruct)**2
#X_recon - X_my_reconstruct 1.47252586279
您可以看到的错误非零并且实际上非常明显。为什么?他们的重建与我的重建有何不同?
答案 0 :(得分:1)
我看到了几个问题:
点积应为X_pca.dot(pca.components_)
。 PCA
使用SVD对您的X_train
矩阵进行分解:
X train = U·S·Vᵀ。
此处,pca.components_
对应Vᵀ(一个(k, n_features)
矩阵),而不是 U (一个(n_datapoints, k)
矩阵)。< / p>
PCA的sklearn实现非常易读,可以找到here。我还在this previous answer中写了一个纯粹的numpy例子。
您是否通过在进行拟合之前减去每列的平均值来使X_train
居中?
PCA
类会自动将数据居中,并将原始均值向量存储在其.mean_
属性中。如果输入要素的平均向量非零,则需要将平均值添加到重建中,即my_reconstruct += pca.mean_
。