应用SVD会立即引发内存错误?

7

我正在尝试对我的矩阵(3241 x 12596)应用SVD,该矩阵是在进行一些文本处理后得到的(最终目标是执行潜在语义分析),但我无法理解为什么会出现这种情况,因为我的64位计算机有16GB RAM。一旦调用svd(self.A),它就会抛出一个错误。具体的错误如下:

Traceback (most recent call last):
  File ".\SVD.py", line 985, in <module>
    _svd.calc()
  File ".\SVD.py", line 534, in calc
    self.U, self.S, self.Vt = svd(self.A)
  File "C:\Python26\lib\site-packages\scipy\linalg\decomp_svd.py", line 81, in svd
    overwrite_a = overwrite_a)
MemoryError

所以我尝试使用

self.U, self.S, self.Vt = svd(self.A, full_matrices= False)

这次出现了以下错误:

Traceback (most recent call last):
  File ".\SVD.py", line 985, in <module>
    _svd.calc()
  File ".\SVD.py", line 534, in calc
    self.U, self.S, self.Vt = svd(self.A, full_matrices= False)
  File "C:\Python26\lib\site-packages\scipy\linalg\decomp_svd.py", line 71, in svd
    return numpy.linalg.svd(a, full_matrices=0, compute_uv=compute_uv)
  File "C:\Python26\lib\site-packages\numpy\linalg\linalg.py", line 1317, in svd
    work = zeros((lwork,), t)
MemoryError

这个矩阵是否太大,以至于Numpy无法处理?在不改变方法本身的情况下,有什么我可以做的吗?


Python在尝试计算SVD时使用了多少内存?您正在运行32位还是64位的Python? - Ferdinand Beyer
@Ferdinand Beyer:它在崩溃时使用了380 MB。啊!:( 我正在使用32位的Python。我将继续安装64位版本。 - Legend
@Ferdinand Beyer:你真是个救星!不知怎么的,我竟然忘了这一点。现在它完美地运行了!非常感谢你。 - Legend
2个回答

13

是的,scipy.linalg.svdfull_matrices 参数非常重要:您的输入非常秩亏损(秩最大为 3,241),因此您不希望为 V 分配整个 12,596 x 12,596 矩阵的空间!

更重要的是,从文本处理中得到的矩阵通常是非常稀疏的。而 scipy.linalg.svd 是密集型的,并且不提供截断 SVD,这会导致 a)性能差劲和 b)浪费大量内存。

可以看看 PyPI 上的 sparseSVD 包,它可以处理稀疏输入,并且你可以仅要求前 K 个因子。或者尝试 scipy.sparse.linalg.svd,虽然它不太高效,并且只在较新版本的 scipy 中可用。

或者,为了完全避免这些琐碎的细节,使用一个可以透明地为您执行有效的 LSA 的包,例如 gensim


2

显然,感谢@Ferdinand Beyer的提醒,我没有注意到我在64位机器上使用了32位版本的Python。

使用64位版本的Python并重新安装所有库解决了问题。


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