了解用于 PCA 时 SVD 的输出

机器算法验证 主成分分析 Python svd
2022-04-03 04:53:19

我正在对相当多的数据(3000 个变量,100079 个数据点)进行主成分分析(PCA)。我这样做主要是为了好玩;数据分析不是我的日常工作。

通常,要进行 PCA,我会计算协方差矩阵,然后找到它的特征向量和相应的特征值。我非常了解如何解释这两者,并发现它是最初掌握数据集的有用方法。

但是,我已经读到,对于如此大的数据集,最好(更快,更准确)通过对数据矩阵进行奇异值分解(SVD)来进行主成分分析。

我已经使用SciPy 的svd函数完成了这项工作。我不太了解 SVD,所以我可能做得不对(见下文),但假设我有,我最终得到的是 (1) a matrix U,它的大小3000×3000; s长度向量3000V, 和一个大小矩阵3000×100079. (我使用了这个full_matrices=False选项,否则它会是100079×100079,这很愚蠢。)

我的问题如下:

  • s向量中的奇异值可能与相关矩阵的特征值相同,这似乎是合理的。这个对吗?

  • 如果是这样,我如何找到相关矩阵的特征向量?它们是 的行U,还是它的列,还是别的什么?

  • 似乎合理的是, 的列V可能是转换为由主成分定义的基础的数据。这个对吗?如果没有,我怎么能得到它?

为了进行分析,我只是把我的数据放在一个大3000×100079numpy 数组并将其传递给svd函数。(我知道通常应该首先将数据居中,但我的直觉表明我可能不想为我的数据执行此操作,至少最初是这样。)这是正确的方法吗?或者我应该在将数据传递给这个函数之前对我的数据做一些特别的事情吗?

3个回答

我认为首先要记住的是给定一个矩阵AA=UΣVT(奇异值分解)分解同理A=SΛS1(特征值分解)如果A是一个正(半)定对称矩阵,即。A=QΛQT. 话虽如此,回到你的第一个问题:是的,奇异值在数值上与特征值相同是合理的。一般来说,如下所示并由@amoeba 指出,奇异值是非零特征值的平方根ATA.

来到你的第二个问题:假设Am×n=UΣVT,你要找的特征向量在V然而UV是酉矩阵:VTV=InUTU=Im. 我想这点也回答了你的第三个问题。为了更清楚地说明这一点:A=UΣVTATA=VΣTUTUΣVTVΣ2VT因为ΣT=ΣUTU=I. 所以Σ2=Λ. (小心你很可能需要使用归一化因子1n1实现这种平等。)

关于你的最后一点:我通常在m>n域,因此协方差函数的特征分解更有效;这样就可以立即进行居中。话虽如此:是的,你的直觉是正确的;不,如果您想使用SVD要计算主成分,您无需先将数据居中。以下主题对此主题进行了很好的讨论:何时应将数据居中以及何时应标准化?

我的第一个参考资料SVD及其与特征分解的联系是 G.Strang 的线性代数导论,第 1 章。6 节。7 和 IT Jolliffe 的主成分分析,章节。3 节。5. 两者通常作为旧图书馆副本很容易获得,如果您希望稍后访问更高级的文本,应该作为一个很好的介绍。

您的问题的答案如下:

  1. 不,这是不正确的:数据矩阵的奇异值(您的s) 等于协方差矩阵的特征值的平方根,直到一个比例因子N1在哪里N是数据点的数量。

  2. 协方差(NB:协方差!不是相关)矩阵的特征向量由U.

  3. 几乎正确:列V是主要成分,即主轴上的投影,但按单位范数缩放!主成分本身由以下列给出V,每个乘以各自的奇异值。

下面链接的两个函数使用np.linalg.eig或计算 PCA np.linalg.svd它应该可以帮助您在两者之间进行转换。该模块中有一个更大的 PCA 类,您可能会感兴趣。如果您最终使用它,我想听听有关 PCA 类的一些反馈。在我们将其合并之前,我仍在添加功能。

你可以在这里看到 PR 由于某种原因,它不会让我发布深层链接,因此请查找def _pca_svdand def _pca_eig