PageRank算法实现

基本原理

在互联网上,如果一个网页被很多其他网页所链接,说明它受到普遍的承认和信赖,那么它的排名就高。这就是PageRank的核心思想。

引用来自《数学之美》的简单例子:

网页Y的排名应该来自于所有指向这个网页的其他网页的权重之和,在上图中Y的网页排名就是0.001 + 0.01 + 0.02 + 0.05 = 0.081。

如此,就可以把互联网简化成一个有向图,每个结点就代表一个网页,边就代表网页之间的链接关系。

 

接下来以具体的例子来介绍如何计算:

 令 $PR = \left (PR_{1}\ ,\ PR_{2} \ ,\cdots ,PR_{N}\right )^{T}$为各个网页的排名,上图的网络用邻接矩阵来表示就是:

$S = \begin{pmatrix}
0 & 0& 0& 0& 1\\
1/3 & 0& 0& 0 &0 \\
1/3 & 0& 0& 0& 0\\
1/3 & 1/2& 0& 0 &0 \\
0& 1/2& 1& 1& 0
\end{pmatrix}$

注意,每一列的元素和为1。

需要额外注意的是,该算法要实现的前提之一是图必须是强连通的,所以如果网络中存在没有出链的结点,那么就需要处理一下。处理方法是让该结点对所有其他结点都有出链(包括它自身)。

 

PageRank算法是通过迭代来实现的,假定$PR_{i}$是第$i$次迭代的结果,那么

$PR_{i} = S\cdot PR_{i-1}$

当经过多次迭代后,最后得到一个稳定的PR值。

现在因为我们一开始不知道网页的初始排名,所以令$PR_{i} = \left (\frac{1}{N}\ ,\ \frac{1}{N} \ ,\cdots ,\frac{1}{N}\right )^{T}$。

 

上文说到图必须是强连通的,除了存在没有出链的结点,还存在只对自己出链的结点,若是访问了此结点,那就一直在该结点处循环。当然了,我们可不会一直很傻的在该网页停留,在现实中,我们也会通过输入一个新的地址来访问别的网页,这个网页是随机的,和当前网页可以没有关系。

为此引入一个新的变量$\alpha $,表示用户以$\alpha $的概率访问该网页所链接的网页,以$1-\alpha $的概率随机访问图中任意网页。

新的迭代公式就是:

$PR_{i} = \frac{1-\alpha }{N}\cdot e^{T}\cdot e + \alpha *S\cdot PR_{i-1} $

其中$e^{T}$为全1的列向量。

 

Python算法实现

接下来就用python来计算上面的网页排名,代码如下:

 1 import numpy as np
 2 
 3 
 4 def page_rank(graph, alpha, eps, max_step):
 5     node = graph.shape[0]  # 网络中结点个数
 6 
 7     pr = []
 8     for i in range(node):  # 初始访问概率
 9         pr.append(1/node)
10 
11     pr = np.array(pr)
12     pr = pr.reshape(pr.shape[0], 1)
13 
14     y = []                 # 跳转至任意网页的概率
15     x = (1.0-alpha)/node
16     for i in range(node):
17         y.append(x)
18     y = np.array(y)
19     y = y.reshape(y.shape[0], 1)
20 
21     for i in range(max_step):
22         pre_pr = pr
23         pr = np.dot(alpha * graph, pr) + y
24 
25         if abs(np.min(pr - pre_pr)) < eps:
26             print("The algorithm converges to the %dth iteration!" % i)
27             print(pr)
28             return
29 
30     print("failed!")
31 
32 
33 if __name__ == '__main__':
34     graph = np.array([[0, 0, 0, 0, 1],
35                       [1/3, 0, 0, 0, 0],
36                       [1/3, 0, 0, 0, 0],
37                       [1/3, 1/2, 0, 0, 0],
38                       [0, 1/2, 1, 1, 0]])
39     page_rank(graph, 0.85, 1e-6, 100)

最后的运行结果:

 

 

MapReduce实现

这部分我也是用Python代码实现的,想看的可以转至我的另一篇随笔:传送文 

 

参考:

[1] 【机器学习】【PageRank算法-1】PageRank算法原理介绍

[2] PageRank算法--从原理到实现

[3] 吴军. 数学之美. PageRank——Google的民主表决式网页排名技术

转载于:https://www.cnblogs.com/zyb993963526/p/10572733.html

PageRank是一种用于网页排名的算法,由Google创始人拉里·佩奇(Larry Page)和谢尔盖·布林(Sergey Brin)在1998年发明,它基于链接分析的思想,通过计算网页之间的“重要性”得分,从而确定其在搜索引擎结果中的位置。 在Python实现PageRank算法,你可以使用网络流库如`networkx`和`scipy.sparse`。以下是一个简单的步骤概述: 1. **安装必要的库**: ```bash pip install networkx scipy ``` 2. **创建图(Graph)**: 使用`networkx`中的`DiGraph`或`MultiDiGraph`来表示网页及其间的链接。 ```python import networkx as nx # 创建一个空有向图 G = nx.DiGraph() ``` 3. **添加节点和边**: 将网页作为节点,边表示从源到目标的链接。 ```python # 添加节点和边的字典或列表形式 nodes = ['A', 'B', 'C', ...] edges = [('A', 'B'), ('B', 'C'), ('B', 'D'), ...] G.add_nodes_from(nodes) G.add_edges_from(edges) ``` 4. **初始化PageRank矩阵**: 网页总数为n,初始的PageRank通常是所有节点的均值,除以n。 ```python n = len(G.nodes) initial_PR = [1 / n] * n PR_matrix = nx.to_numpy_array(G) + nx.laplacian_matrix(G).todense() ``` 5. **迭代更新PageRank**: 这通常涉及到迭代地应用转移矩阵(PR_matrix),直到收敛。 ```python def iteration(PR, convergence_threshold): new_PR = PR @ PR_matrix delta = sum(abs(new_PR - PR)) if delta < convergence_threshold: return new_PR else: PR = new_PR # 调整阈值并继续迭代,例如减半 convergence_threshold /= 2 return iteration(PR, convergence_threshold) final_PR = iteration(initial_PR, 0.0001) ``` 6. **显示结果**: 打印每个节点的PageRank分数。 ```python for node, rank in zip(G.nodes, final_PR): print(f"Node {node}: Rank {rank}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值