如何对非常高维的数据执行 PCA?

机器算法验证 主成分分析 Python
2022-02-14 13:51:44

要执行主成分分析 (PCA),您必须从数据中减去每列的均值,计算相关系数矩阵,然后找到特征向量和特征值。好吧,这就是我在 Python 中实现它所做的,除了它只适用于小矩阵,因为查找相关系数矩阵 (corrcoef) 的方法不允许我使用高维数组。由于我必须将它用于图像,因此我当前的实现并没有真正帮助我。

我已经读过可以只取你的数据矩阵并计算而不是,但这对我不起作用。好吧,我不确定我是否理解它的含义,除了它应该是一个矩阵而不是(在我的情况下为)的事实。我在 eigenfaces 教程中阅读了这些内容,但似乎没有一个以我能真正理解的方式解释它。DDD/nDD/nn×np×ppn

简而言之,是否有这种方法的简单算法描述,以便我可以遵循它?

4个回答

您现在所做的很接近,但您需要确保将(data . data.T) / lines左侧的特征向量乘以data.T,以获得 的特征向量(data.T . data) / lines这有时被称为“转置技巧”。

这里有更多细节。假设您有一个要对其执行 PCA为简单起见,假设的列已经归一化为零均值,因此我们只需要计算协方差矩阵的特征向量。AAATA

现在如果是一个矩阵,其中,那么是一个非常大的矩阵。因此的特征向量,而是计算小得多的矩阵的特征向量——假设我们可以找出两者之间的关系。那么的特征向量与的特征向量有什么关系呢?Am×nn>>mATAn×nATAm×mAATATAAAT

v为特征向量AAT有特征值λ. 然后

  • AATv=λv
  • AT(AATv)=AT(λv)
  • (ATA)(ATv)=λ(ATv)

换句话说,如果v是一个特征向量AAT, 然后ATv是一个特征向量ATA,具有相同的特征值。所以在执行 PCA 时A,而不是直接找到的特征向量ATA(这可能非常昂贵),更容易找到特征向量vAAT然后将这些在左边乘以AT得到特征向量ATvATA.

执行标准 PCA 的最简单方法是通过减去列均值来使数据矩阵的列居中(假设列对应于不同的变量),然后执行 SVD。左奇异向量乘以相应的奇异值,对应于(估计的)主成分。右奇异向量对应于(估计的)主成分方向——这些与 PCA 给出的特征向量相同。奇异值对应于主成分的标准偏差(乘以根 n 的因子,其中 n 是数据矩阵中的行数)——与 PCA 给出的特征值的平方根相同。

如果要对相关矩阵进行 PCA,则需要在应用 SVD 之前标准化数据矩阵的列。这相当于减去平均值(居中),然后除以标准偏差(缩放)。

如果您想要完整的 PCA,这将是最有效的方法。您可以使用一些代数验证这给您的答案与对样本协方差矩阵进行谱分解相同。

当您只需要几台 PC 时,还有一些计算部分 SVD 的有效方法。其中一些是幂迭代的变体。Lanczos 算法也是与偏最小二乘法相关的一个示例如果您的矩阵很大,则使用近似方法可能会更好。在这种情况下,规范 PCA 也有统计上的原因。

听起来您想要的是用于执行 PCA 的 NIPALS 算法。这是统计学家中非常流行的算法。它有很多优点:

  • 如果只需要前几个组件,则计算成本低于 SVD 或特征值分解方法。
  • 通常具有更适中的存储要求,因为从未形成协方差矩阵。对于非常大的数据集,这是一个非常重要的属性。
  • 可以处理数据集中丢失的数据(尽管这不是您的问题,因为您正在处理图像)。

说明
http://en.wikipedia.org/wiki/Non-linear_iterative_partial_least_squares

算法
这里是算法的简单而出色的描述(在第 1.2 节中)
http://stats4.eng.mcmaster.ca/w/mediafiles/mediawiki/f/f7/Section-Extra-Class-1.pdf

记住在进行 PCA 之前首先要平均中心尺度,因为它对尺度敏感。

为了补充 Gilead 的答案,它们是用于截断 PCA 的计算成本较低的算法。NIPALS 确实非常流行,但我在对部分数据执行一系列拟合的近似方法(通常称为随机投影的 PCA)方面取得了很大成功。这在元优化线程中进行了讨论。

正如您提到 Python 时,让我指出该算法是在scikit-learn中实现的:PCA类。特别是,它用于演示eigenfaces的示例中。