在Python中理解scikitlearn PCA.transform函数

JSo*_*ulp 3 python pca scikit-learn

所以我目前正在开发一个涉及使用主成分分析(PCA)的项目,我试图在运行中学习它.幸运的是,Python有一个非常方便的scikitlearn.decomposition模块,它似乎可以为你完成大部分工作.在我真正开始使用它之前,我正试图弄清楚它正在做什么.

我一直在测试的数据框如下所示:

   0  1
0  1  2
1  3  1
2  4  6
3  5  3
Run Code Online (Sandbox Code Playgroud)

当我调用PCA.fit()然后查看我得到的组件时:

array([[ 0.5172843 ,  0.85581362],
   [ 0.85581362, -0.5172843 ]])
Run Code Online (Sandbox Code Playgroud)

从我对PCA的相当有限的了解,我有点了解这是如何计算的,但是我迷失的地方就是当我打电话给PCA.transform时.这是它给我的输出:

array([[-2.0197033 , -1.40829634],
       [-1.84094831,  0.8206152 ],
       [ 2.95540408, -0.9099927 ],
       [ 0.90524753,  1.49767383]])
Run Code Online (Sandbox Code Playgroud)

有人可能会引导我了解原始数据框和组件的转换方式并将其转换为这个新数组吗?我希望能够理解它所做的确切计算,这样当我扩大规模时,我会更好地了解正在发生的事情.谢谢!

Oli*_*ain 15

调用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 PCA(n_components = 10),然后调用,fit您会发现它components_有10行,一行代表您所请求的每个组件,500列代表输入维度.如果您随后调用了transform所有100行数据,则会将其投影到此10维空间中,因此输出将有100行(输入中每行1个),但只有10行,从而减少了数据的维度.

如何做到的简短答案是PCA计算奇异值分解,然后只保留其中一个矩阵的一些列.维基百科有关于此背后的实际线性代数的更多信息 - 对于StackOverflow答案来说,它有点长.