Csr_matrix.dot与Numpy.dot

问题描述:

我有一个大(N = 50000)块对角线csr_matrix中号表示一组图形的邻接矩阵。我必须多次乘以M的致密numpy.arrayv。因此我使用M.dot(v)Csr_matrix.dot与Numpy.dot

令人惊讶的是,我发现首先将M转换为numpy.array,然后使用numpy.dot要快得多。

任何想法为什么这样呢?

+0

是'v' 1D矢量吗?或者它是另一个'nxm'矩阵?你的矩阵如何稀疏?稀疏矩阵只与稀疏因子一样有效。如果矩阵不够*稀疏*,算术运算可能会慢几个数量级。 –

+0

该矢量是1D。 – Christopher

我没有足够的内存在内存中容纳一个50000x50000密集矩阵,并将其乘以50000向量。但是在这里找到一些维度较低的测试。

设置:

import numpy as np 
from scipy.sparse import csr_matrix 

def make_csr(n, N): 
    rows = np.random.choice(N, n) 
    cols = np.random.choice(N, n) 
    data = np.ones(n) 
    return csr_matrix((data, (rows, cols)), shape=(N,N), dtype=np.float32) 

上面的代码生成与在NxN矩阵n非零元素的稀疏矩阵。

矩阵:

N = 5000 

# Sparse matrices 
A = make_csr(10*10, N)  # ~100 non-zero 
B = make_csr(100*100, N) # ~10000 non-zero 
C = make_csr(1000*1000, N) # ~1000000 non-zero 
D = make_csr(5000*5000, N) # ~25000000 non-zero 
E = csr_matrix(np.random.randn(N,N), dtype=np.float32) # non-sparse 

# Numpy dense arrays 
An = A.todense() 
Bn = B.todense() 
Cn = C.todense() 
Dn = D.todense() 
En = E.todense() 

b = np.random.randn(N) 

时序:

>>> %timeit A.dot(b)  # 9.63 µs per loop 
>>> %timeit An.dot(b)  # 41.6 ms per loop 

>>> %timeit B.dot(b)  # 41.3 µs per loop 
>>> %timeit Bn.dot(b)  # 41.2 ms per loop 

>>> %timeit C.dot(b)  # 3.2 ms per loop 
>>> %timeit Cn.dot(b)  # 41.2 ms per loop 

>>> %timeit D.dot(b)  # 35.4 ms per loop 
>>> %timeit Dn.dot(b)  # 43.2 ms per loop 

>>> %timeit E.dot(b)  # 55.5 ms per loop 
>>> %timeit En.dot(b)  # 43.4 ms per loop 
  • 对于高度稀疏矩阵(AB)它更快超过1000x倍。
  • 对于不是很稀疏矩阵(C),它仍然得到10x加速。
  • 对于几乎不稀疏矩阵D会有一些0由于指数的重复,但不是很多概率上讲),但仍然较快,虽然不大,但速度更快。
  • 对于真正的非稀疏矩阵(E),操作较慢,但速度并不慢。

结论:你得到的加速取决于你的矩阵的稀疏,但N = 5000稀疏矩阵是总是快(只要他们有一些项)。

由于内存问题,我无法尝试N = 50000。你可以试试上面的代码,看看N

+0

为什么'np。对于小矩阵来说,“点”要快得多,因为它通常会调用BLAS函数来进行实际的乘法运算。根据您的numpy版本链接到哪个BLAS库,这些通常是多线程的并且经过非常严格的优化。 'csr_dot'是单线程的,并且按照您的时序显示,仅在处理高度稀疏矩阵时才显示效率增益。顺便说一下,'sparse.rand'是创建密度可变的随机稀疏矩阵的一种更简单的方法。 –

+0

@ali_m非常感谢,不知道'sparse.rand'。顺便说一句,我有numpy链接到OpenBLAS。 –

+0

OpenBLAS的速度确实非常快 - 大多数基准测试与Intel MKL相当(或稍快)(例如[here](http://gcdart.blogspot.co.uk/2013/06/fast-matrix-multiply-和ml.html))。 –