了解 Python 中的 scikitlearn PCA.transform 函数
Understanding scikitlearn PCA.transform function in Python
所以我目前正在从事一个涉及使用主成分分析 (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]])
有人能告诉我它是如何获取原始数据框和组件并将其转换为这个新数组的吗?我希望能够理解它所做的确切计算,这样当我扩大规模时,我就能更好地了解正在发生的事情。谢谢!
当您调用 fit 时,PCA 将计算一些向量,您可以将数据投影到这些向量上,以减少数据的维度。由于数据的每一行都是二维的,因此最多可以将数据投影到 2 个向量上,并且这些向量中的每一个都是二维的。 PCA.components_
的每一行都是一个单一的向量,事物被投影到它上面,它的大小与训练数据中的列数相同。因为你做了一个完整的主成分分析,你得到了 2 个这样的向量,所以你得到了一个 2x2 矩阵。这些向量中的第一个将最大化投影数据的方差。第二个将最大化第一个投影后剩下的方差。通常,一个传递的 n_components
值小于输入数据的维度,这样您返回的行数就会减少,并且您的 components_
数组会变宽但不会变高。
当您调用 transform
时,您是在要求 sklearn 实际进行投影。也就是说,您要求它将每一行数据投影到调用 fit
时学习的向量 space 中。对于您传递给 transform
的每一行数据,您将在输出中有 1 行,并且该行中的列数将是在 fit
阶段学习的向量数。换句话说,列数将等于您传递给构造函数的 n_components
的值。
当源数据有很多列并且您希望减少列数同时保留尽可能多的信息时,通常会使用 PCA。假设您有一个包含 100 行的数据集,每行有 500 列。如果你构造了一个像 PCA(n_components = 10)
这样的 PCA,然后调用 fit
你会发现 components_
有 10 行,每行对应你请求的每个组件,还有 500 列,因为那是输入维度.如果您随后调用 transform
,则所有 100 行数据都将投影到这个 10 维 space 中,因此输出将有 100 行(输入中每行 1 行)但只有 10 列,从而减少数据的维度。
对此如何完成的简短回答是 PCA 计算奇异值分解,然后仅保留其中一个矩阵的某些列。 Wikipedia 有更多关于这背后的实际线性代数的信息 - Whosebug 的答案有点长。
所以我目前正在从事一个涉及使用主成分分析 (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]])
有人能告诉我它是如何获取原始数据框和组件并将其转换为这个新数组的吗?我希望能够理解它所做的确切计算,这样当我扩大规模时,我就能更好地了解正在发生的事情。谢谢!
当您调用 fit 时,PCA 将计算一些向量,您可以将数据投影到这些向量上,以减少数据的维度。由于数据的每一行都是二维的,因此最多可以将数据投影到 2 个向量上,并且这些向量中的每一个都是二维的。 PCA.components_
的每一行都是一个单一的向量,事物被投影到它上面,它的大小与训练数据中的列数相同。因为你做了一个完整的主成分分析,你得到了 2 个这样的向量,所以你得到了一个 2x2 矩阵。这些向量中的第一个将最大化投影数据的方差。第二个将最大化第一个投影后剩下的方差。通常,一个传递的 n_components
值小于输入数据的维度,这样您返回的行数就会减少,并且您的 components_
数组会变宽但不会变高。
当您调用 transform
时,您是在要求 sklearn 实际进行投影。也就是说,您要求它将每一行数据投影到调用 fit
时学习的向量 space 中。对于您传递给 transform
的每一行数据,您将在输出中有 1 行,并且该行中的列数将是在 fit
阶段学习的向量数。换句话说,列数将等于您传递给构造函数的 n_components
的值。
当源数据有很多列并且您希望减少列数同时保留尽可能多的信息时,通常会使用 PCA。假设您有一个包含 100 行的数据集,每行有 500 列。如果你构造了一个像 PCA(n_components = 10)
这样的 PCA,然后调用 fit
你会发现 components_
有 10 行,每行对应你请求的每个组件,还有 500 列,因为那是输入维度.如果您随后调用 transform
,则所有 100 行数据都将投影到这个 10 维 space 中,因此输出将有 100 行(输入中每行 1 行)但只有 10 列,从而减少数据的维度。
对此如何完成的简短回答是 PCA 计算奇异值分解,然后仅保留其中一个矩阵的某些列。 Wikipedia 有更多关于这背后的实际线性代数的信息 - Whosebug 的答案有点长。