Python 如何在数百万个节点上计算个性化的PageRank?

Python 如何在数百万个节点上计算个性化的PageRank?,python,numpy,scipy,pagerank,Python,Numpy,Scipy,Pagerank,我有一个稀疏图,包含大约100万个节点和1000万条边。我想计算每个节点的个性化PageRank,其中节点n的个性化PageRank指: # x_0 is a column vector of all zeros, except a 1 in the position corresponding to node n # adjacency_matrix is a matrix with a 1 in position (i, j) if there is an edge from node i

我有一个稀疏图,包含大约100万个节点和1000万条边。我想计算每个节点的个性化PageRank,其中节点n的个性化PageRank指:

# x_0 is a column vector of all zeros, except a 1 in the position corresponding to node n
# adjacency_matrix is a matrix with a 1 in position (i, j) if there is an edge from node i to node j

x_1 = 0.5 * x_0 + 0.5 * adjacency_matrix * x_0
x_2 = 0.5 * x_0 + 0.5 * adjacency_matrix * x_1
x_3 = 0.5 * x_0 + 0.5 * adjacency_matrix * x_2

# x_3 now holds the personalized PageRank scores

# i'm basically approximating the personalized PageRank by running this for only 3 iterations
我试着用NumPy编码,但运行起来太长了。(大约1秒以计算每个节点的个性化PageRank)

我还尝试将x_0更改为矩阵(通过组合多个不同节点的列向量),但这也没有多大帮助,实际上使计算花费的时间更长。(可能是因为矩阵很快变得密集,所以它不再适合RAM?我不确定)

有没有其他建议的计算方法,最好是用Python?我还考虑采用非矩阵方法进行PageRank计算,通过三次迭代进行一种模拟随机游走(即,我以1的分数开始每个节点,然后将该分数传播到其邻居,等等),但我不确定这是否会更快。是吗?如果是的话,原因是什么?

我认为“PageRank”算法最好被视为一个有向图(可能有适当的权重)

我喜欢位于的
networkx


您会发现,在您可以调整的算法下,它还有一个“PageRank”示例。

在您的情况下,如果数据存储方式正确,使用模拟随机游走迭代方法应该可以很好地工作。当与节点数量相比,边很少时(如您的情况),我认为矩阵方法不是一个好的选择,因为它是一个非常稀疏的矩阵,但实际上,这种方法意味着您正在检查从I到j的任何I和j的节点的存在性。(顺便说一句,我不确定这些乘零运算需要多少运行时间。)

如果数据的存储方式使每个节点对象都有其传出链接的目的地列表,那么随机行走模拟方法将相当快。忽略阻尼因子,这就是在随机行走模拟的每次迭代中实际要做的:

for node in nodes:
    for destination in node.destinations:
        destination.pageRank += node.pageRank/len(destinations)

每个迭代的时间复杂度为O(n*k),在您的情况下,n=1m,k=10。如果我没有遗漏任何东西,这听起来不错。

是的,我有一个有向图。嗯,我没有尝试networkx,但我尝试了igraph的个性化PageRank算法。不过,我也有同样的问题——速度相当慢。(据我所知——我可能错了——igraph通常更快。)@grautur应该很容易证明——我相信
networkx
将从numpy数组中获取数据来构建图形。。。不得不承认,我从来没有过一百万个节点。。。(所以不能担保——只是把期权扔到了拳击场上)