如何解决计算大型稀疏矩阵的幂和
给定一个查询向量(one-hot-vector)q
,大小为50000x1
和一个大的稀疏矩阵A
,大小为50000 x 50000
,nnz为{{ 1}} 是 A
亿,我想计算 0.3
(通常是 r=(A + A^2 + ... + A^S)q
)。
我可以使用循环迭代上述方程
4 <= S <=6
首先想到的是 r = np.zeros((50000,1))
for i in range(S):
q = A.dot(q)
r += q
可以是对称的,所以 eigen decomposition would help for compute power of A
。但由于 A
是大型稀疏矩阵,分解后会生成与 A
相同大小的稠密矩阵,从而导致性能下降(在内存和速度方面)。
还考虑了低秩近似。但是 A
又大又稀疏,所以不确定哪个排名 A
合适。
预先计算一些东西是完全没问题的,比如 r
。但我希望最后一次计算会很快:计算 A + A^2 + ... + A^S = B
小于 40 毫秒。
是否有任何参考或论文或技巧?
解决方法
即使矩阵不是稀疏的,迭代方法也是可行的方法。
乘以 A.dot(q) 的复杂度为 O(N^2),而计算 A.dot(A^i) 的复杂度为 O(N^3)。
q 是稀疏的(确实比 A 稀疏得多)这一事实可能会有所帮助。
对于第一次迭代,A*q
可以计算为 A[q_hot_index,:].T
。
对于第二次迭代,A @ q
的预期密度与 A 的预期密度相同(大约 10%),因此稀疏地进行仍然是好的。
对于之后的第三次迭代,A^i @ q
将是密集的。
由于您正在累积结果,因此您的 r
不是稀疏的,它可以防止索引操作。
有 several 种不同的方式来存储稀疏矩阵。我自己不能说我对所有这些都了解得深入,但我认为 csr_matrix、csc_matrix 是通用稀疏矩阵中最紧凑的。
当您需要计算 P(A)
时,特征分解是好的,为了计算 P(A)*q
,只有当 P(A)
具有 {{ 大小的数量级时,特征分解才变得有利1}}。特征分解的复杂度为A
,矩阵向量乘积的复杂度为O(N^3)
,使用特征分解对O(N^2)
次多项式P(A)
的求值可以在{ {1}}。
编辑:回答评论中的问题
- “它可以防止索引操作”
假设您有一个稀疏矩阵 D
。这可以描述为 O(N^3 + N*D)
。现在假设您将 1 分配给一个元素,它变为 [0,2,7,0]
,现在表示为 ((3,2),(5,7))
。赋值是通过插入数组来执行的,插入数组的复杂度为[0,1,0]
,其中nnz 是非零元素的个数。如果你有一个密集矩阵,你总是可以修改一个复杂度为 ((3,(4,1),7))
的元素。
- 复杂度中的 N 是多少?
它是矩阵O(nnz)
的行数或列数
- 关于特征分解,你想说值不值 可以在 O(N^3 +N*D) 而非 O(N^3 + N^2) 中实现计算 r
计算 O(1)
将具有复杂度 A
(具有不同的常数),对于大矩阵,使用特征分解计算 P(A)
可能是最有效的。但是 O(N^3 * D)
具有 P(A)
复杂性,因此除非您有很大的 P(A)x
O(N^2 * D)
,否则使用特征分解计算 P(A)x
可能不是一个好主意,当速度为担心。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。