5

我有 100 万个 3d 点要传递,numpy.linalg.svd但它很快就会耗尽内存。有没有办法把这个操作分解成更小的块?

我不知道它在做什么,但我只应该传递代表 3x3、4x4 矩阵的数组吗?因为我在网上看到了它的用法,他们传递具有任意数量元素的数组。

4

2 回答 2

1

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

@Saullo Castro 是正确的。full_matrices=False 可以变得难以处理,因为 U 矩阵不是 1Mx1M 元素,而是 1Mx3,节省了大量资金。我不确定 numpy 使用哪种简化的 SVD 算法(我认为它可能是 Compact SVD 或瘦):维基百科上有 3 个广泛使用的算法的简要描述:http ://en.wikipedia.org/wiki/Singular_value_decomposition in简化的 SVD 部分。它们都围绕将整个 U 矩阵的计算简化为简化形式,这对于某些甚至许多问题来说已经足够了。节省最多的是 numberObservations>>numberFeatures

关于你是否得到相同的结果。简短的回答可能是肯定的,具体取决于您将使用 SVD 结果做什么。例如,您将获得与原始形式相同的矩阵(到浮点容差水平),其简化形式与原始形式相同,如下面的代码所示。请注意,在上例中,U 的大小是 numberObservations x numberObservations,而在 full_matrices=False 中,U 的大小是 numberObservations x numberFeatures

此代码改编自 numpy.linalg.svd 文档,以允许人们尝试任意行/列,选择奇异值。

人们总是可以将 U 矩阵的大小减小到 M x min(M,N)。根据您的数据结构和存在多少噪音,可能会进一步减少。仅仅因为 numpy.isclose 为假并不意味着计算出的 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))#
于 2013-11-04T16:01:25.147 回答
0

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

于 2016-08-03T12:00:12.517 回答