手动 PCA 逆变换

Posted

技术标签:

【中文标题】手动 PCA 逆变换【英文标题】:PCA inverse transform manually 【发布时间】:2015-12-21 10:34:34 【问题描述】:

我正在使用 scikit-learn。我的应用程序的性质是,我离线进行拟合,然后只能在线(即时)使用得到的系数来手动计算各种目标。

变换很简单,就是data * pca.components_,即简单的点积。但是,我不知道如何执行逆变换。 pca 对象的哪个字段包含逆变换的相关系数?如何计算逆变换?

具体来说,我指的是sklearn.decomposition.PCA package 中提供的 PCA.inverse_transform() 方法调用:如何使用 PCA 计算的各种系数手动重现其功能?

【问题讨论】:

scikit-learn 的 pca 模块中存在逆变换,我只是希望能够手动运行它。它所做的是,它从缩小的空间中获取一个数据点,然后将其带回(当然会丢失信息)到原始空间。 我不这么认为。首先,矩阵维度不成立。 【参考方案1】:

1) transform 不是 data * pca.components_

首先,* 不是 numpy 数组的点积。它是逐元素乘法。要进行点积,您需要使用np.dot

其次,PCA.components_的形状是(n_components, n_features),而要转换的数据的形状是(n_samples, n_features),所以需要转置PCA.components_进行点积。

而且,变换的第一步是减去均值,因此如果手动进行,还需要先减去均值。

正确的变换方式是

data_reduced = np.dot(data - pca.mean_, pca.components_.T)

2)inverse_transform只是transform的逆过程

data_original = np.dot(data_reduced, pca.components_) + pca.mean_

如果您的数据在每列中的均值已经为零,则可以忽略上面的pca.mean_,例如

import numpy as np
from sklearn.decomposition import PCA

pca = PCA(n_components=3)
pca.fit(data)

data_reduced = np.dot(data, pca.components_.T) # transform
data_original = np.dot(data_reduced, pca.components_) # inverse_transform

【讨论】:

在上面写*的时候,我写的不是代码,而是psueodocde,也就是非正式的写idea。至于减去均值,可以理解,对,输入矩阵 X 应该已经具有均值 0 和标准差 1 的每一列,也就是说,它已经标准化了,对吧?因此,没有必要进一步调整平均值。但是,如果你想表达如何转换原始数据,在标准化之前,你能不能把它写成一个更干净、更一步一步的过程?那我准​​备好接受你的回答了。 是的,如果你的数据已经有每一列的平均值为 0,你不需要调整平均值。步骤其实很简单,我提供了一个比较完整的例子,如果有不清楚的地方请指出。 还有一个问题:您解决了均值问题,但方差如何?你没有提到任何关于确保 st.dev=1 的事情。 不必保证std=1。 scikit-learn 实现的 PCA 仅集中数据但不扩展数据。您可以通过查看源代码github.com/scikit-learn/scikit-learn/blob/a95203b/sklearn/… 来检查 手动操作,截断尺寸,data_reduced = np.dot(data, pca.components_.T[:,:dim]),返回data_original = np.dot(data_reduced, pca.components_[:dim, :])

以上是关于手动 PCA 逆变换的主要内容,如果未能解决你的问题,请参考以下文章

K-L变换和 主成分分析PCA

KL变换+PCA+关系

谁知道利用逆变换法(反变换法),用matlab编程正态分布随机变量随机数?

逆变换采样

模式识别(Pattern Recognition)学习笔记(三十五)-- K-L变换与PCA

PCA主成分分析