在非常大的稀疏矩阵上应用PCA

19
我正在使用R进行文本分类任务,并获得了一个大小为22490 x 120,000的文档-词条矩阵(只有400万个非零条目,不到1%的条目)。现在我想通过利用PCA(主成分分析)来降低维度。不幸的是,R无法处理这个巨大的矩阵,因此我把这个稀疏矩阵存储在“Matrix Market Format”文件中,希望使用一些其他技术来进行PCA。
所以,有谁能给我一些有用的库(任何编程语言),能够轻松地处理这个大规模的矩阵进行PCA,或者自己进行长手计算PCA,换句话说,首先计算协方差矩阵,然后计算协方差矩阵的特征值和特征向量。
我想要的是计算所有PC(120,000),并选择仅占总方差90%的前N个PC。显然,在这种情况下,我必须预先设定一个阈值,将某些非常小的方差值设置为0(在协方差矩阵中),否则,协方差矩阵将不会是稀疏的,其大小将是120,000 x 120,000,这是一个单个机器无法处理的。此外,载荷(特征向量)将非常大,并且应以稀疏格式存储。
感谢任何帮助!
注意:我正在使用具有24GB RAM和8个CPU核心的机器。

我不确定是否百分之百正确,但我认为MatLab可以完成这项工作。 - Anton
如果你在这里得不到任何帮助,可以考虑在http://stats.stackexchange.com/上提问。 - NPE
@aix 感谢您的建议,我已将其转移到计算科学测试版,并获得了一些有用的提示。您也可以在此URL关注它。 - Ensom Hodder
@EnsomHodder:我不知道那个新网站。看起来很有趣,谢谢你指出 :) - NPE
5个回答

15
Python工具包scikit-learn有几个PCA变体,其中RandomizedPCA可以处理由scipy.sparse支持的任何格式的稀疏矩阵。scipy.io.mmread应该能够解析Matrix Market格式(虽然我从未尝试过)。
免责声明:我是scikit-learn开发团队的成员。 编辑:在scikit-learn 0.14中,RandomizedPCA的稀疏矩阵支持已被弃用。应使用TruncatedSVD。有关详细信息,请参见文档。

非常感谢@larmans,你提出的方法在某种程度上可以使用稀疏矩阵进行PCA,但由于内存消耗较大,它只能计算一些少量的主成分 :-( - Ensom Hodder
2
请注意,RandomizedPCA已被弃用,建议使用带有关键字参数svd_solver ='randomized'PCA - BallpointBen

7
不必运行PCA,您可以尝试使用潜在狄利克雷分配(LDA),将文档-词矩阵分解为文档-主题和主题-词矩阵。这是一个R实现的链接:http://cran.r-project.org/web/packages/lda/ - 尽管如果您搜索一下,会发现有相当多的实现方式。
使用LDA需要预先指定固定数量的主题(类似于主成分)。一个可能更好的替代方案是HDP-LDA (http://www.gatsby.ucl.ac.uk/~ywteh/research/npbayes/npbayes-r21.tgz),它学习形成语料库良好表示所需的主题数量。
如果您的数据集可以放入内存中(看起来可以),那么运行LDA代码也不应该有问题。
正如scicomp论坛上的许多人指出的那样,没有必要计算所有120k个主成分。像http://en.wikipedia.org/wiki/Power_iteration这样的算法可以计算矩阵的最大特征值,而LDA算法将收敛到给定主题数量的数据的最小描述长度表示。

1

0

我想你可能无法计算所有的主成分,但仍然可以获得降维后的数据集矩阵版本。我在 MATLAB 中实现了一个简单的例程,这个例程在 Python 中很容易复制。

计算输入数据集的协方差矩阵,并将其转换为密集矩阵。假设 S 是您的输入 120,000 * 22490 稀疏矩阵,则可以这样操作:

Smul=full(S.'*S);
Sm=full(mean(S));
Sm2=120000*Sm.'*Sm;
Scov=Smul-Sm2; 

应用eigs函数于协方差矩阵,以获取前N个主要特征向量。
[V,D] = eigs(Scov,N);

通过将以零为中心的矩阵投影在特征向量上获得pcs,

Sr=(S-Sm)*V; 

Sr 是 S 的降维版本。


0

文本分类任务

我使用了一种针对稀疏矩阵的PCA技术,解决了几乎相同的问题。 这种技术可以处理非常大的稀疏矩阵。 结果显示,这种简单的PCA表现优于word2vec。 这意味着简单的PCA优于LDA。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接