Python PageRank计算中矩阵向量积的稀疏矩阵

Python PageRank计算中矩阵向量积的稀疏矩阵,python,numpy,scipy,sparse-matrix,Python,Numpy,Scipy,Sparse Matrix,我正在实现一些迭代算法来计算webgraph的PageRank,但我在寻找存储某些矩阵的最佳方法时遇到了一些困难 我有一个Bnxn矩阵,它表示网络图(B[I,j]=1/outdegree[j]如果有一个从j到I的弧,则0否则;outdegree[j]是从节点j传出的弧数)我将其存储为一个scipy.sparse.dok_矩阵,因为它大部分都是0条目。问题是,我必须计算许多Px类型的矩阵x向量积,其中 P = B + (1/n)*e*d^T 其中,e是全一向量,d是一个布尔向量,它在分量jifo

我正在实现一些迭代算法来计算webgraph的PageRank,但我在寻找存储某些矩阵的最佳方法时遇到了一些困难

我有一个
B
nxn
矩阵,它表示网络图(
B[I,j]=1/outdegree[j]
如果有一个从
j
I
的弧,则
0
否则;
outdegree[j]
是从节点
j
传出的弧数)我将其存储为一个
scipy.sparse.dok_矩阵
,因为它大部分都是
0
条目。问题是,我必须计算许多
Px
类型的矩阵x向量积,其中

P = B + (1/n)*e*d^T
其中,
e
是全一向量,
d
是一个布尔向量,它在分量
j
if
outdegree[j]>0
中具有
1
。基本上,
e*d^T
是一种线性代数“技巧”,它可以编写一个
nxn
矩阵,其列要么全部由
1
s,要么由
0
s组成,这取决于
d
中对应的条目是
1
还是
0

因此,我正在为两件事而挣扎,这两件事并非完全独立:

  • 如何在numpy中实现相同的“技巧”,因为
    e*d.T
    只计算标量积,而我需要一个矩阵。我想这是广播和切片的巧妙运用,但我对numpy还是新手,无法理解
  • 如果我只是像上面那样定义
    P
    (假设我找到了1的解决方案),我就失去了将
    B
    存储为稀疏矩阵所获得的内存优势,突然我需要存储
    n^2
    浮动。总之,我添加到
    B
    中的矩阵是非常冗余的(只有两种类型的列),因此肯定有比将整个矩阵存储在内存中更好的方法。有什么建议吗?请记住,对于任意向量,
    x
    ,它必须能够方便地计算
    P.dot(x)

  • 第1点的答案。是:

    它从
    v1
    (M)数组和
    v2
    (N)数组创建
    B
    (MxN)矩阵,从而
    B(i,j)=v1[i]*v2[j]

    答案是2。这个问题更复杂

  • 如果您不再需要
    B
    ,您可以简单地将其定义为
    numpy.empty((n,n))
    ,按照问题的开头填写,然后再填写
    B+=(1/n)*np.outer(e,d)
  • 如果
    n
    不是太大,那么使用稀疏矩阵或标准矩阵可能没有多大区别
  • 如果可能的话,考虑<代码> NP.Enter(E,D)< /代码>作为稀疏矩阵,然后尝试从中提出一些建议。
    为简单起见,由于带有
    np.dot
    的表达式将非常庞大,因此让
    表示矩阵乘法,
    e
    d
    x
    是向量,即具有形状(n,1),在方括号中的表达式
    *
    是python的列表乘法。然后,通过结合性

    (e∙d.T)∙x = e∙(d.T∙x) = [[d.T∙x] * n]
    
    其中
    d.T∙x
    是一个标量,并且

    P∙x = B∙x + 1/n * e∙d.T∙x = B∙x + 1/n * [[d.T∙x] * n]
    

    为了能够进行计算,你只能存储向量d。注意
    d.T∙x
    (或者相当于
    np.dot(d.T,x)
    (如果使用数组)是向量积,是相对于矩阵乘法的一种廉价运算。

    如果您可以添加一些代码,以适当的形状/类型生成示例输入变量(B,d,e等)。是的,我刚刚找到了基本相同的东西,我不需要在需要的时候写
    P.dot(x)
    ,而是简单地写
    B.dot(x)+(d.dot(x)*e)/n
    。这样我就解决了问题2。完全避免问题1。