5

我有一个非常大的矩阵(大约 500000 * 20000),其中包含我将使用 pca 分析的数据。为此,我使用 ParallelColt 库,但都使用奇异值分解和特征值分解来获得协方差矩阵的特征向量和特征值。但是这些方法浪费了堆,我得到“OutOfMemory”错误......

同样使用 SparseDoubleMatrix2D (数据非常稀疏)错误仍然存​​在,所以我问你:我该如何解决这个问题?

换图书馆?

4

3 回答 3

2

您可以使用 Oja 规则计算 PCA:它是一种迭代算法,改进了 PCA 的估计,一次一个向量。它比通常的 PCA 慢,但只需要在内存中存储一​​个向量。它在数值上也非常稳定

http://en.wikipedia.org/wiki/Oja%27s_rule

于 2011-12-05T23:50:14.937 回答
0

我为这类问题构建了一些稀疏的增量算法。方便的是,它建立在 Colt 之上。

请参阅下面的trickl-cluster 库中的 HallMarshalMartin 类。你可以一次喂它大块的行,所以它应该可以解决你的内存问题。

该代码在 GPL 下可用。恐怕我才刚刚发布它,所以它的文档很短,希望它是相当不言自明的。有 JUnit 测试应该有助于使用。

http://open.trickl.com/trickl-pca/index.html

于 2011-12-07T17:09:18.283 回答
0

我不确定更改库是否会有所帮助。您将需要双打(每个 8 个字节)。我不知道在这种情况下协方差矩阵的维度是多少,但是切换库不会对基础计算产生太大影响。

运行时的 -Xmx 设置是什么?perm gen 的大小呢?也许你可以增加它们。

算法是立即停止还是运行一段时间?如果是后者,您可以使用 Visual VM 1.3.3 附加到该进程(下载并安装所有插件)。它会让你看到堆、线程等上发生了什么。可以帮助你找出根本原因。

谷歌搜索“大型矩阵的 Java 特征值”从谷歌找到了这个。如果您在评论中向下滚动,我想知道块 Lanczos 特征值分析可能会有所帮助。如果您可以获得特征值的一个子集,这可能就足够了。

这些 SVM 实现声称对大型数据集很有用:

http://www.support-vector-machines.org/SVM_soft.html

我认为您不能为 JVM 要求超过 2GB 的空间:

http://www.theserverside.com/discussions/thread.tss?thread_id=26347

根据 Oracle 的说法,您需要一个在 64 位操作系统上运行的 64 位 JVM:

http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit

于 2011-12-05T23:51:27.267 回答