Python中的页面排名
作者:互联网
我是Python的新手,我正在尝试根据Python中的这个等式计算页面排名向量:
其中Pi(k)是k-Th迭代后的Page-rank向量,G是Google矩阵,H是超链接矩阵,a是悬空节点向量,α= 0.85,e是1的向量.
使用G进行计算需要花费大量时间,而使用超链接矩阵H(稀疏矩阵)应该花费更少的时间.
这是我的代码:
for i in range(1, k_steps+1):
for j in range(0, len(dictionary_urls)):
for k in range(0, len(dictionary_urls)):
if matrix_H[k][j] != 0:
matrix_pi_k[i][j] += matrix_pi_k[i-1][k] * float(matrix_H[k][j])
alpha_pi_k_a += matrix_pi_k[i-1][k]*float(vector_a[k])
alpha_pi_k_a = alpha_pi_k_a * float(alpha)
alpha_pi_k_a = alpha_pi_k_a + float((1- alpha))
alpha_pi_k_a = alpha_pi_k_a / float(len(dictionary_urls))
matrix_pi_k[i][j] = matrix_pi_k[i][j] * float(alpha)
matrix_pi_k[i][j] = matrix_pi_k[i][j] + float(alpha_pi_k_a)
alpha_pi_k_a = 0
k_steps是所需的迭代次数.
dictionary_links包含所有URL.
代码执行后,matrix_pi_k应该具有所有Pi向量
我计算了所需的所有变量.我得到一个使用H矩阵的运行时间几乎等于使用G矩阵的运行时间,但理论上它应该是不同的.
为什么?我应该改变什么来减少运行时间?
谢谢.
解决方法:
问题是你使用相同的密集矩阵向量乘法算法将稀疏矩阵乘以密集向量.你不会以这种方式看到任何加速.
假设你有一个nxn矩阵A(密集或稀疏)和一个n向量x.要计算y = Ax,我们可以写:
y = [0]*n
for i in range(n):
for j in range(n):
y[i] += A[i,j]*x[j]
无论矩阵A是密集的还是稀疏的,这都有效.但是假设A很稀疏.我们仍然循环遍历A的所有列以计算y的单个条目,即使大多数条目将为零.因此外部循环经历n次迭代,内部循环也经历n次迭代.
如果我们知道A的哪些条目非零,我们可以做得更好.假设我们有一个第i行的所有非零项的列表,称之为非零[i].然后我们可以用这个列表上的迭代替换内部循环:
y = [0]*n
for i in range(n):
for j in nonzero[i]:
y[i] += A[i,j]*x[j]
因此,虽然我们的外部循环执行n次迭代,但内部循环仅执行与非零条目一样多的迭代.
这是加速带稀疏矩阵向量乘法的地方.
使用numpy!
但是你还有另外一个问题:你正在尝试用纯Python做矩阵乘法,它(由于类型检查,非连续数据结构等)很慢.解决方案是使用numpy
,它提供快速的算法和数据结构.然后你可以使用scipy
‘s sparse matrices,因为它们为你实现了快速稀疏矩阵向量乘法.
实验
我们可以通过快速实验展示所有这些.首先,我们将生成10,000 x 10,000密集矩阵A:
>>> import numpy as np
>>> n = 10000
>>> A = np.random.sample((n,n))
然后我们将通过阈值A来制作稀疏矩阵B.B与A的大小相同,但只有10%的条目是非零的:
>>> B = np.where(A < .1, A, 0).astype(float)
现在我们将制作一个密集向量,将A和B乘以:
>>> x = np.random.sample(n)
>>> %timeit A.dot(x)
10 loops, best of 3: 46.7 ms per loop
>>> %timeit B.dot(x)
10 loops, best of 3: 43.7 ms per loop
计算Ax的时间与计算Bx的时间相同,即使B是“稀疏的”.当然,它实际上并不稀疏:它被存储为具有大量零条目的密集矩阵.让我们稀疏:
>>> sparse_B = scipy.sparse.csr_matrix(B)
>>> 100 loops, best of 3: 12 ms per loop
我们的加速!现在,只是为了好玩,如果我们将A存储为稀疏矩阵,即使它真的很密集呢?
>>> sparse_A = scipy.sparse.csr_matrix(A)
>>> %timeit sparse_A.dot(x)
10 loops, best of 3: 112 ms per loop
哎哟!但这是可以预料的,因为将A作为稀疏矩阵存储将在乘法期间产生一些开销.
标签:python,algorithm,pagerank 来源: https://codeday.me/bug/20190519/1138476.html