应用SVD瞬间抛出内存错误?
我正在尝试对一个矩阵(3241行 x 12596列)应用奇异值分解(SVD),这个矩阵是经过一些文本处理得到的,最终目的是进行潜在语义分析。但是我不明白为什么会出现错误,因为我的64位机器有16GB的内存。当我调用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处理不了?在不改变方法的情况下,我能做些什么呢?
2 个回答
13
是的,scipy.linalg.svd
中的full_matrices
参数很重要:你的输入矩阵的秩非常低(最大秩为3,241),所以你不想为V
分配一个12,596 x 12,596的完整矩阵!
更重要的是,来自文本处理的矩阵通常是非常稀疏的。scipy.linalg.svd
是针对密集矩阵的,并且不支持截断奇异值分解,这会导致a) 性能非常糟糕,b) 大量内存浪费。
可以看看来自PyPI的sparseSVD包,它可以处理稀疏输入,并且你可以只请求前K
个因子。或者试试scipy.sparse.linalg.svd
,不过它的效率不如前者,并且只在较新版本的scipy中可用。
或者,为了完全避免复杂的细节,可以使用一个透明地为你执行高效LSA的包,比如gensim。
2
看来,感谢@Ferdinand Beyer,我没有注意到我在64位的电脑上使用的是32位的Python。
换成64位的Python并重新安装所有的库后,问题就解决了。