使用sklearn提取PCA主成分

3

我正在使用sklearn的PCA对大量图像进行降维处理。一旦完成PCA拟合,我想查看组件的外观。

可以通过查看components_属性来实现这一点。由于不知道该属性的存在,我选择了其他方法:

each_component = np.eye(total_components)
component_im_array = pca.inverse_transform(each_component)

for i in range(num_components):
   component_im = component_im_array[i, :].reshape(height, width)
   # do something with component_im

换句话说,我在PCA空间中创建了一个图像,其中除1个特征外,所有特征均设为0。通过反向转换它们,然后应该得到原始空间中的图像,该图像一旦转换,就可以仅使用该PCA组件来表达。
下图显示了结果。左边是使用我的方法计算得出的分量。右边是直接使用pca.components_[i]。此外,使用我的方法,大多数图像非常相似(但它们确实是不同的),而通过访问components_,图像非常不同,正如我所预期的那样。
我的方法是否存在概念问题?显然,从pca.components_[i]获取的组件是正确的(或者至少更正确)。谢谢! left: calculated component, right: real component
2个回答

6

组件和反向变换是两个不同的概念。反向变换将这些组件映射回原始图像空间。

#Create a PCA model with two principal components
pca = PCA(2)
pca.fit(data)
#Get the components from transforming the original data.
scores = pca.transform(data)
# Reconstruct from the 2 dimensional scores 
reconstruct = pca.inverse_transform(scores )
#The residual is the amount not explained by the first two components
residual=data-reconstruct

因此,您是在反向转换原始数据而不是组件,因此它们完全不同。您几乎从不对原始数据进行 inverse_transform 。pca.components_ 是实际表示用于将数据投影到 pca 空间中的基础轴的向量。

谢谢您的回答。也许我们有一些误解:我不是在反向转换原始数据,而是一个除了一个位置以外都是零的向量。这样做,我期望我正在反向转换一个图像 [0,0,...,0,1,0,...,0],这个图像必须来自一个看起来像组件的原始图像。 - Miquel

5
抓取 components_ 和在单位矩阵上执行 inverse_transform 的区别在于后者加入了每个特征的经验平均值。即:
def inverse_transform(self, X):
    return np.dot(X, self.components_) + self.mean_

其中self.mean_是从训练集中估计得出的。


太好了。我不知道为什么我之前没有自己查看源代码。谢谢!然而,在PCA._fit(X)中,均值被计算为self.mean_ = np.mean(X, axis=0),其中X是一个具有n_samples行和n_features列的数组,因此均值是每个特征上的特征均值,对于每个特征,这当然可能会支配组件实际具有的任何贡献,这就是为什么所有图像看起来几乎相同的原因。一切都解释清楚了,谢谢! - Miquel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接