计算 PCA 中的误差



我有一个关于我在做 PCA 时没有预料到的结果的问题。

我已经使用参考数据成功地计算了主成分,然后作为检查以确保正在发生的事情是我认为正在发生的事情,我将参考数据投影到其特征的整个基础上(保留所有组件),然后转换回来,(这是在python中,所以它是pca.fit(ref_data)后跟ref_data_transform =pca.transform.(ref_data)后跟pca.inverse_transform(ref_data_transform)我得到完全相同的数据。这并不奇怪。

同样不足为奇的是,随着我选择的主成分越来越少,原始数据与预测到较小基础上然后预测回来的数据之间的点对点差异增加。也就是说,如果您绘制原始数据和"过滤"的数据,它看起来会有所不同,随着您减小要投影的子空间的大小,差异会增加。我可以捕获称为difference_vec的向量中每个数据点之间的差异。

令人惊讶的是(至少对我来说)当我对任何difference_vec列求和时,它总是等于零。也就是说,当我投影到越来越小的子空间上时,任何原始数据点与由一定数量的主成分过滤的相应数据点之间的实际差异会越来越大,但 TOTAL 误差始终为零。

如果我在这里犯了一些错误,我非常感谢我的任何见解,如果没有,为什么这个以前的"投影诱导错误"指标不起作用。

谢谢。

发生这种情况是因为ref_data和我称之为inv_data = pca.inverse_transform(pca.transform(ref_data))的都具有相同的平均值(沿第二维取,即对样本求平均值)。

要看到这一点,请查看transform的代码:

transform = lambda X: dot(X - mu, V.T)

inverse_transform可以定义为:

inverse_transform = lambda X: dot(X, V) + mu

其中muref_data的平均值,Vcovariance(ref_data)的第一个N特征向量。

因此,如果您遵循数据链及其平均值:

  1. ref_data与平均mu;
  2. transform(ref_data)的平均值为 0(请参阅上面的等效定义:X-mu平均值为零,然后将结果线性投影到某个坐标参考上只会旋转/剪切/翻转这些零平均值点,不会改变它们的平均值;
  3. 最后,inv_data = inverse_transform(transform(ref_data))mu加回来,所以它mu-mean;

你看ref_datainv_data都有卑鄙mu.

最后,sum(ref_data - inv_data)可以看作是sum(mean(ref_data - inv_data) * num_samples),通过线性简化为sum(mu - mu),即0。

对不起,这是很多话,但是现在我看到它的想法真的很简单。正如我在评论中提到的,在这种情况下,您希望使用矩阵范数(如弗罗贝尼乌斯范数)来测量两个矩阵之间的距离,而不仅仅是sum(A - B)😅!


示例代码:

import numpy as np
from sklearn.decomposition import PCA
ref_data = np.random.randn(20, 3)
pca = PCA(n_components=1)
pca.fit(ref_data)
trans_data = pca.transform(ref_data)
inv_data = pca.inverse_transform(trans_data)
np.mean(inv_data, 0)   # array([ 0.03664149,  0.51348007,  0.0360179 ])
np.mean(ref_data, 0)   # array([ 0.03664149,  0.51348007,  0.0360179 ])
np.mean(trans_data, 0) # array([ -2.49800181e-17]) meanwhile ...
np.sum(inv_data - ref_data) # -1.3877787807814457e-15 !

相关内容

  • 没有找到相关文章

最新更新