python机器学习手写算法系列——PageRank算法

Page Rank

Page Rank 是谷歌搜索的网页排名算法。PageRank是以谷歌创始人Larry Page命名的。(只能说是个巧合,敢不敢叫Larry Rank)

算法

PageRank算法假设,一个用户在互联网上随机跳转到别的page。他要求用户最终到达某个page的概率。

例子

我找到的最好的例子就是下面这个:

PageRank Algorithm - Example(YouTube)

如果你的网络有问题,访问不了,没关系,我会详细讲解。

探索

我们有以下的有向图,每个节点代表一个页面,每条有向边代表从一个page到另一个page的链接。
PageRank

Iteration 0

第0次遍历,在一开始,用户随机访问这4个page的概率,当然是1/4。

Iteration 1

在遍历1, 用户在遍历0的基础上,跳转到另一个page。

Page A

PageRank
对于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

PageRank
我们用符号表示以上运算,则有:

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]

Iteration 2

我们在遍历1的基础上,计算遍历2。

A
PageRank
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]

PageRank

代码

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分类》

发布了82 篇原创文章 · 获赞 1511 · 访问量 54万+

猜你喜欢

转载自blog.csdn.net/juwikuang/article/details/103536254