有没有办法防止numpy.linalg.svd内存不足?

时间:2013-11-02 15:32:07

标签: python numpy matrix linear-algebra svd

我有100万3d积分我要传递给numpy.linalg.svd,但内存耗尽很快。有没有办法将此操作分解为更小的块?

我不知道它在做什么但我只能传递代表3x3,4x4矩阵的数组?因为我已经看到它在线使用它们传递具有任意数量元素的数组。

2 个答案:

答案 0 :(得分:1)

如果你的情况是MxN 1000000x3矩阵numpy.linalg.svd不需要M == N.实际上,这正是SVD可以用来计算秩和伪逆等事物的地方。诸如linalg.inv之类的方法需要一个square(和满秩)矩阵来获得定义的结果。

@Saullo Castro是对的。 full_matrices = False可以变得难以处理,因为Ux矩阵不是1Mx1M元素,而是1Mx3,这是一个巨大的节省。我不确定哪个减少了SVD算法numpy使用(我认为它可能是Compact SVD,或者很薄):3个广泛使用的简短描述在维基百科上:http://en.wikipedia.org/wiki/Singular_value_decomposition在Reduced SVDs部分。它们都围绕着减少完整U矩阵的计算,减少形式,这对于一些甚至许多问题是足够的。当numberObservations>> numberFeatures

时,节省最多

关于你是否得到相同的结果。简短的回答可能是肯定的,具体取决于您将对SVD结果做些什么。例如,您将获得与原始格式相同的矩阵(缩放容差级别)和缩小格式,如下面的代码所示。请注意,在大写的情况下,U的大小是numberObservations x numberObservations,而在full_matrices = False中,U的大小是numberObservations x numberFeatures

此代码改编自numpy.linalg.svd doc,允许用户试验任意行/列,选择奇异值。

总是可以将U矩阵的大小减小到M x min(M,N)。根据您的数据结构和存在的噪音,可能会进一步减少。仅仅因为numpy.isclose为false并不意味着计算出的SV对所有上下文都不好。您可以使用mostSignificantSingularValues变量对此进行试验,该变量取自完整SVD的顶级SV。

numberObservations = 900
numberFeatures = 600
mostSignificantSingularValues = 600

a = np.random.randn( numberObservations, numberFeatures) + 1j*np.random.randn(numberObservations, numberFeatures)

#Reconstruction based on full SVD:

U, s, V = np.linalg.svd(a, full_matrices=True)
print(U.shape, V.shape, s.shape)
S = np.zeros((numberObservations, numberFeatures), dtype=complex)
S[:mostSignificantSingularValues, :mostSignificantSingularValues] = np.diag(s[:mostSignificantSingularValues])
print(np.allclose(a, np.dot(U, np.dot(S, V))))
d1 = a - np.dot(U, np.dot(S, V))#
#True

#Reconstruction based on reduced SVD:

U, s, V = np.linalg.svd(a, full_matrices=False)
print(U.shape, V.shape, s.shape)
S = np.diag(s)
print(np.allclose(a, np.dot(U, np.dot(S, V))))

d2 = a - np.dot(U, np.dot(S, V))#

答案 1 :(得分:0)

尝试使用scipy.linalg.svd代替numpy的功能。