Page Rank 是谷歌搜索的网页排名算法。PageRank是以谷歌创始人Larry Page命名的。(只能说是个巧合,敢不敢叫Larry Rank)
PageRank算法假设,一个用户在互联网上随机跳转到别的page。他要求用户最终到达某个page的概率。
我找到的最好的例子就是下面这个:
PageRank Algorithm - Example(YouTube)
如果你的网络有问题,访问不了,没关系,我会详细讲解。
我们有以下的有向图,每个节点代表一个页面,每条有向边代表从一个page到另一个page的链接。
第0次遍历,在一开始,用户随机访问这4个page的概率,当然是1/4。
在遍历1, 用户在遍历0的基础上,跳转到另一个page。
Page A
对于Page A,唯一访问它的就是Page C。但是Page C同时也指向B和D,所以从C出发,到达A的概率是1/3。而之前我们算过了,只有1/4的用户访问了C,两者结合,就是1/4*1/3=1/12 = 0.08333333333333333。
B
对于B来说,情况稍微复杂了一点。因为有A和C都指向B。
我们先只考虑A->B,因为A同时指向B和C,所以从A出发,到达B的概率是1/2。考虑Iteration 1 的 A的概率是1/4。则用户先访问A,再访问B的概率是1/2 * 1/4 = 1/8
同理,用户先访问C,再访问B的概率是
1/3 * 1/4 = 1/12
结合以上,用户在Iteration 1时,到达B的概率是
1/2 * 1/4 + 1/3 * 1/4 = 1/8 + 1/12 = 0.20833333333333334。
C
P(C|I1) = P(C|A) * P(A) + P(C|D) * P(D) = 1/2 * 1/4 + 1 * 1/4 = 1/8+1/4=4.5/12=0.375
D
P(D|I1) = P(D|B) * P(B) + P(D|C) * P© = 1 * 1/4 + 1/3 * 1/4 = 1/4+1/12=4/12=0.3333333333333333
最终结果为
[0.08333333333333333, 0.20833333333333334, 0.375, 0.3333333333333333]
我们在遍历1的基础上,计算遍历2。
A
I1表示Iteration 1, I2表示Iteration 2。
P(A|I2) = P(C|A) * P(C|I1) = 1/3 * 4.5/12 = 1.5/12
B
P(B|I2) = P(B|A) * P(A|I1) + P(B|C) * P(C|I1) = 1/2 * 1/12 + 1/3 * 4.5/12= 2/12
C
P(C|I2) = P(C|A) * P(A|I1) + P(C|D) * P(D|I1) = 1/2 * 1/12 = 4.5/12
D
P(D|I2) = P(D|B) * P(B|I1) + P(D|C) * P(C|I1) = 1 * 2.5/12 + 1/3 * 4.5/12= 4/12
遍历2的最终结果 :
[0.125, 0.16666666666666666, 0.375, 0.3333333333333333]
最终的PageRank是[1, 2, 4, 3]
import numpy as np
n_iterations=3
n_nodes=4
#graph
graph = np.zeros((n_nodes, n_nodes))
#direction[start_node,end_node]=1
graph[0,1]=1
graph[0,2]=1
graph[1,3]=1
graph[2,0]=1
graph[2,1]=1
graph[2,3]=1
graph[3,2]=1
graph
#page rank matrix
pr_matrix = np.zeros((n_iterations, n_nodes))
#iteration 0
pr_matrix[0] = [1/n_nodes] * n_nodes
print('Page rank in Iteration 0')
print(pr_matrix[0])
#iteration 1,2
for i_iteration in [1,2]:
print(f'Page rank in Iteration {i_iteration}')
for node in range(n_nodes):
pr=0
for previous_node in range(n_nodes):
if graph[previous_node, node]==1:
pr+=pr_matrix[i_iteration-1,previous_node]/graph[previous_node, :].sum()
pr_matrix[i_iteration, node] = pr
print(pr_matrix[i_iteration])
源代码Github地址
欢迎阅读本系列其他文章:
《python机器学习手写算法系列——PageRank算法》
《python机器学习手写算法系列——线性回归》
《python机器学习手写算法系列——逻辑回归》
《python机器学习手写算法系列——决策树》
《python机器学习手写算法系列——kmeans聚类》
《python机器学习手写算法系列——梯度提升GBDT回归》
《python机器学习手写算法系列——梯度提升GBDT分类》