所以我目前正在开发一个涉及使用主成分分析(PCA)的项目,我试图在运行中学习它。幸运的是,Python有一个非常方便的scikitlearn.decomposition模块,似乎可以为你完成大部分工作。在我真正开始使用它之前,我正在试图弄清楚它正在做什么。
我一直在测试的数据框如下所示:
0 1
0 1 2
1 3 1
2 4 6
3 5 3
当我调用PCA.fit()然后查看我得到的组件时:
array([[ 0.5172843 , 0.85581362],
[ 0.85581362, -0.5172843 ]])
从我对PCA的相当有限的了解,我有点了解这是如何计算的,但是当我迷路的时候,我就打电话给PCA.transform。这是它给我的输出:
array([[-2.0197033 , -1.40829634],
[-1.84094831, 0.8206152 ],
[ 2.95540408, -0.9099927 ],
[ 0.90524753, 1.49767383]])
有人可能会告诉我原始数据框架和组件的转换方式并将其转换为这个新数组吗?我希望能够理解它所做的确切计算,这样当我扩大规模时,我会更好地了解正在发生的事情。谢谢!
答案 0 :(得分:8)
当您调用fit时,PCA将计算一些可以将数据投影到的向量,以减少数据的维数。由于数据的每一行都是2维,因此最多可以有2个向量投影数据,每个向量都是2维的。 PCA.components_
的每一行都是一个向量投影的向量,它将与训练数据中的列数相同。由于你做了一个完整的PCA,你得到2个这样的向量,所以你得到一个2x2矩阵。这些向量中的第一个将最大化投影数据的方差。第二个将最大化第一次投影后剩下的变化。通常情况下,传递的值n_components
小于输入数据的维度,这样您就可以获得更少的行,并且您拥有宽但不高的components_
数组。
当您致电transform
时,您要求sklearn实际进行投影。也就是说,您要求它将数据的每一行投影到调用fit
时学习的向量空间中。对于传递给transform
的数据的每一行,您在输出中将有1行,该行中的列数将是fit
阶段中学习的向量数。换句话说,列数将等于传递给构造函数的n_components
的值。
通常,当源数据包含大量列并且您希望减少列数同时保留尽可能多的信息时,会使用PCA。假设您有一个包含100行的数据集,每行有500列。如果您构建了一个类似PCA(n_components = 10)
的PCA,然后调用了fit
,那么您会发现components_
有10行,每行所请求的一行,以及500列#&# 39; s输入维度。如果你随后调用了transform
,那么所有100行数据都会被投射到这个10维空间中,因此输出将有100行(输入中每行1个)但只有10行,从而减少了数据的维数
如何做到的简短答案是PCA计算奇异值分解,然后只保留其中一个矩阵的某些列。 Wikipedia有更多关于此背后的实际线性代数的信息 - 对于StackOverflow答案,它有点长。