PageRank算法实现
- 迭代法实现大规模PageRank,网页数量不低于10000。解答在1.1 迭代法计算PageRank
 - 代数法求小规模PageRank的稳态解,网页数量为5。解答在2.2 修正后PageRank的代数法计算
 - 附加分,构造不存在稳态的情况,设计方法变为有稳态的情况。解答在2 修正的PageRank 的定义与计算
 
问题背景
值得一提的是,虽然 PageRank 算法经常被用于搜索引擎中,但是网络节点重要性分析的重要性对于很多领域都是非常重要的。
基本概念
- 马尔可夫性质(Markov property):当一个随机过程在给定现在状态及所有过去状态情况下,其未来状态的条件概率分布仅依赖于当前状态;换句话说,在给定现在状态时,它与过去状态(即该过程的历史路径)是条件独立的。也就是说,系统的状态只与最邻近的上一个状态有关。
 
P ( x n = x n ∣ x n − 1 = x n − 1 , x n − 2 = x n − 2 , . . . x 0 = x 0 ) = P ( x n = x n ∣ x n − 1 = x n − 1 ) P(x_n=x_n\mid x_{n-1}=x_{n-1}, x_{n-2}=x_{n-2},...x_0=x_0)=P(x_n=x_n\mid x_{n-1}=x_{n-1}) P(xn=xn∣xn−1=xn−1,xn−2=xn−2,...x0=x0)=P(xn=xn∣xn−1=xn−1)
-  
马尔可夫链:具有马尔可夫性质的离散时间的链。
 -  
周期性: p i i ( n ) p_{ii}^{(n)} pii(n)表示在有向图中,经过 n n n个边之后从节点 i i i到节点 i i i的概率。记 d i d_i di是数集 { n ∣ p i i ( n ) > 0 } \{n\mid p_{ii}^{(n)}>0\} {n∣pii(n)>0}的最大公约数,如果 d i = 1 d_i=1 di=1则是非周期,如果 d i > 1 d_i>1 di>1则为周期的,且周期为 d i d_i di。
 -  
随机游走模型:给定一个含有 n n n 个结点的有向图,在有向图上定义随机游走模型,即一阶马尔可夫链,其中结点表示状态,有向边表示状态之间的转移,假设从一个结点到通过有向边相连的所有结点的转移概率相等。
转移矩阵 M M M :是一个 n n n 阶矩阵 M = [ m i j ] n × n M=[m_{ij}]_{n\times n} M=[mij]n×n。其中 m i j m_{ij} mij 的意义是从节点 j j j到节点 i i i的概率。
**状态分布矩阵 R t R_t Rt **:某个时刻 t t t 访问各个节点的概率分布,其中在$ t+1 $时刻的状态分布矩阵 R t + 1 R_{t+1} Rt+1 是
R t + 1 = M R t R_{t+1}=MR_t Rt+1=MRt 
1 PageRank的基本定义
令
    
     
      
       
        u
       
      
      
       u
      
     
    u为一个网页,
    
     
      
       
        N
       
       
        (
       
       
        v
       
       
        )
       
      
      
       N(v)
      
     
    N(v)表示网页
    
     
      
       
        v
       
      
      
       v
      
     
    v向外链接数目,
    
     
      
       
        B
       
       
        (
       
       
        u
       
       
        )
       
      
      
       B(u)
      
     
    B(u)表示连接到网页
    
     
      
       
        u
       
      
      
       u
      
     
    u的网页集合,
    
     
      
       
        R
       
       
        (
       
       
        u
       
       
        )
       
      
      
       R(u)
      
     
    R(u)表示网页
    
     
      
       
        u
       
      
      
       u
      
     
    u的PageRank值,
    
     
      
       
        C
       
      
      
       C
      
     
    C为规范因子,作用是保证所有网页的PageRank总和为常数。
 
     
      
       
        
         R
        
        
         (
        
        
         u
        
        
         )
        
        
         =
        
        
         c
        
        
         
          ∑
         
         
          
           v
          
          
           ∈
          
          
           B
          
          
           (
          
          
           u
          
          
           )
          
         
        
        
         
          R
         
         
          (
         
         
          v
         
         
          )
         
         
          /
         
         
          N
         
         
          (
         
         
          v
         
         
          )
         
        
       
       
         R(u)=c\sum_{v\in B(u)}{R(v)/N(v)} 
       
      
     R(u)=cv∈B(u)∑R(v)/N(v)
 值的一提的是, PageRank 的基本定义是理想化的情况,即要求马尔可夫链不可约且非周期,只有满足这个条件根据马尔可夫平稳分布定理,才会有当时间趋于无穷时状态分布收敛于唯一的平稳分布。
至于不符合上述的限制条件的马尔可夫链求解 PageRank 见本文 2 修正的PageRank 的定义与计算。
1.1 迭代法计算PageRank
1.1.1 基本思路
假设 S S S为整个网页的总和,因为所有网页的 PageRank 值开始都是未知的,所以我们进行平均分配,给每个网页的 PageRank 都赋值 1 / S 1/S 1/S,再根据上式反复迭代计算,直到计算得到的 PageRank 值收敛于一个相对固定的数。也就是说,计算出的所有网页的重要程度趋于稳定,此时停止运算。
即极限
 
     
      
       
        
         
          
           lim
          
          
           
          
         
         
          
           t
          
          
           →
          
          
           +
          
          
           ∞
          
         
        
        
         
          
           M
          
          
           t
          
         
         
          
           R
          
          
           0
          
         
        
        
         =
        
        
         R
        
       
       
         \lim_{t \to +\infty}{M^tR_0}=R 
       
      
     t→+∞limMtR0=R
 存在。$ R $就是我们求取的 PageRank 值。
1.1.2 代码实现
# 运行环境:
# macOS 12.3.1
# PyCharm 2021.3.3 (Community Edition)
# Python 3.7
import numpy as np
import random
M = np.zeros((10000, 10000)) # 随机生成10000*10000的数据(可能含有自回路)
for i in range(len(M[0])):
    for j in range(len(M[0])):
        if i > 100:
            if random.random()>0.5:
                M[i, j] = 1
            else:
                M[i, j] = 0
        else:
            if random.random()>0.2:
                M[i, j] = 1
            else:
                M[i, j] = 0
for i in range(len(M[0])): # 将邻接矩阵转化为转移矩阵
    sum_i = np.sum(M[:, i])
    for j in range(len(M[0])):
        M[j, i] = M[j, i] / sum_i
R = np.ones((len(M[0]), 1)) * (1/len(M[0]))
alpha = 0.85 # 
R_1 = np.zeros((len(M[0]), len(M[0])))
e = 100000 # 初始化误差为100000
count = 0 # 记录迭代次数
while e > 0.00000000000001 or count < 1000: # 限制两个迭代条件,即迭代次数和误差大小
    # R_1 = np.dot(M, R)*alpha + (1-alpha)/len(M[0]) # 修正的pageRank
    R_1 = np.dot(M, R) # 基本的pageRank
    e = R - R_1
    e = np.max(np.abs(e))
    R = R_1
    count += 1
    print(f'iteration {count}: {e}')
print(f'final :{R}')
 
2 修正的PageRank 的定义与计算
在之前的定义中就已经提及,先前定义的 PageRank 具有一定的局限性(对于不存在稳态情况无法计算),主要体现在PageRank 值沉淀现象。
2.1 修正的PageRank 的定义
所以引入衰减系数(damping factor) $ \alpha (0<\alpha<1)$,修正后的PageRank定义为:
 
     
      
       
        
         R
        
        
         (
        
        
         u
        
        
         )
        
        
         =
        
        
         α
        
        
         
          ∑
         
         
          
           v
          
          
           ∈
          
          
           B
          
          
           (
          
          
           u
          
          
           )
          
         
        
        
         
          R
         
         
          (
         
         
          v
         
         
          )
         
         
          /
         
         
          N
         
         
          (
         
         
          v
         
         
          )
         
        
        
         +
        
        
         (
        
        
         1
        
        
         −
        
        
         α
        
        
         )
        
       
       
         R(u)=\alpha \sum_{v\in B(u)}{R(v)/N(v)} + (1-\alpha) 
       
      
     R(u)=αv∈B(u)∑R(v)/N(v)+(1−α)
2.2 修正后PageRank的代数法计算
修正后,PageRank 的平稳分布满足:
 
     
      
       
        
         R
        
        
         =
        
        
         α
        
        
         M
        
        
         R
        
        
         +
        
        
         
          
           1
          
          
           −
          
          
           α
          
         
         
          n
         
        
        
         E
        
       
       
         R=\alpha MR + \frac {1-\alpha}{n}E 
       
      
     R=αMR+n1−αE
 因此有:
 
     
      
       
        
         R
        
        
         =
        
        
         (
        
        
         E
        
        
         −
        
        
         α
        
        
         M
        
        
         
          )
         
         
          
           −
          
          
           1
          
         
        
        
         
          
           1
          
          
           −
          
          
           α
          
         
         
          n
         
        
        
         E
        
       
       
         R=(E-\alpha M)^{-1}\frac{1-\alpha}{n}E 
       
      
     R=(E−αM)−1n1−αE
2.2.1 代码实现
# 运行环境:
# macOS 12.3.1
# PyCharm 2021.3.3 (Community Edition)
# Python 3.7
import numpy as np
import random
M = np.zeros((5, 5))
for i in range(len(M[0])):
    for j in range(len(M[0])):
        if i > 2:
            if random.random()>0.5:
                M[i, j] = 1
            else:
                M[i, j] = 0
        else:
            if random.random()>0.2:
                M[i, j] = 1
            else:
                M[i, j] = 0
for i in range(len(M[0])): # 将邻接矩阵转化为转移矩阵
    sum_i = np.sum(M[:, i])
    for j in range(len(M[0])):
        M[j, i] = M[j, i] / sum_i
alpha = 0.85
A = alpha*M + (1-alpha)/len(M[0])*np.ones((len(M[0]), len(M[0])))
E = np.identity(len(M[0]))
B = np.ones(len(M[0]))
res = (1-alpha)/len(M[0])*np.linalg.inv(E-alpha*M)
res = np.dot(res, np.transpose(B))
print(f'final :{res}')
 
2.3 修正后的PageRank的迭代法计算
只需要将 1.1.2 代码实现 中的
R_1 = np.dot(M, R)*alpha + (1-alpha)/len(M[0]) # 修正的pageRank取消注释R_1 = np.dot(M, R) # 基本的pageRank注释即可
在此不再赘述。
参考文献
[1]曹军.Google的PageRank技术剖析[J].情报杂志,2002(10):15-18.
[2]黄德才,戚华春.PageRank算法研究[J].计算机工程,2006(04):145-146+162.










