公号:码农充电站pro
主页:https://codeshellme.github.iohtml
在互联网早期,随着网络上的网页逐渐增多,如何从海量网页中检索出咱们想要的页面,变得很是的重要。python
当时著名的雅虎和其它互联网公司都试图解决这个问题,但都没能有一个很好的解决方案。git
直到1998 年先后,两位斯坦福大学的博士生,拉里·佩奇和谢尔盖·布林一块儿发明了著名的 PageRank 算法,才完美的解决了网页排名的问题。也正是由于这个算法,诞生了伟大的 Google 公司。github
(上图中:左为布林,右为佩奇。)算法
PageRank 算法的核心原理是:在互联网中,若是一个网页被不少其它网页所连接,说明该网页很是的重要,那么它的排名就高。shell
拉里·佩奇将整个互联网当作一张大的图,每一个网站就像一个节点,而每一个网页的连接就像一个弧。那么,互联网就能够用一个图或者矩阵来描述。数组
拉里·佩奇也因该算法在30 岁时当选为美国工程院院士。网络
假设目前有4 个网页,分别是 A,B,C,D,它们的连接关系以下:数据结构
咱们规定有两种链:工具
好比图中的C 网页,有两个入链,一个出链。
PageRank 的思想就是,一个网页的影响力就等于它的全部入链的影响力之和。
用数学公式表示为:
其中(分值表明页面影响力):
PR(u)
是网页u
的分值。Bu
是网页u
的入链集合。v
是网页u
的任意一个入链。PR(v)
是网面v
的分值。L(v)
是网页v
的出链数量。v
带给网页u
的分值就是 PR(v) / L(v)
。PR(u)
就等于全部的入链分值之和。在上面的公式中,咱们假设从一个页面v 到达它的全部的出链页面的几率是相等的。
好比上图来讲,页面A 有三个出链分别连接到了 B、C、D 上。那么当用户访问 A 的时候,就有跳转到 B、C 或者 D 的可能性,跳转几率均为 1/3。
下面来看下如何计算网页的分值。
咱们能够用一个表格,来表示上图中的网页的连接关系,及每一个页面到其它页面的几率:
A | B | C | D | |
---|---|---|---|---|
A | 0 A->A |
1/2 B->A |
1 C->A |
0 D->A |
B | 1/3 A->B |
0 B->B |
0 C->B |
1/2 D->B |
C | 1/3 A->C |
0 B->C |
0 C->C |
1/2 D->C |
D | 1/3 A->D |
1/2 B->D |
0 C->D |
0 D->D |
根据这个表格中的数字,能够将其转换成一个矩阵M:
假设 A、B、C、D 四个页面的初始影响力都是相同的,都为 1/4,即:
通过第一次分值转移以后,能够获得 W1,以下:
同理能够获得W2,W3 一直到 Wn:
那么何时计算终止呢?
佩奇和布林已经证实,无论网页的初识值选择多少(咱们这假设都是1/4),最终都能保证网页的分值可以收敛到一个真实肯定值。
也就是直到 Wn 再也不变化为止。
这就是网页分值的计算过程,仍是比较好理解的。
咱们上文中介绍到的是PageRank 的基本原理,是简化版本。在实际应用中会出现等级泄露(RankLeak)和等级沉没(Rank Sink)的问题。
若是一个网页没有出链,就会吸取其它网页的分值不释放,最终会致使其它网页的分值为0,这种现象叫作等级泄露。以下图中的网页C:
相反,若是一个网页没有入链,最终会致使该网页的分值为0,这种现象叫作等级沉没。以下图中的网页C:
为了解决上面的问题,拉里·佩奇提出了随机浏览模型,即用户并不都是依靠网页连接来访问网页,也有可能用其它方式访问网址,好比输入网址。
所以,提出了阻尼因子的概念,这个因子表明用户按照跳转连接来上网的几率,而 1-d 则表明用户经过其它方式访问网页的几率。
因此,将上文中的公式改进为:
其中:
如何用代码来计算网页的PR 分值呢?(为了方便查看,我把上图放在这里)
咱们能够看到,该图实际上就是数据结构中的有向图,所以咱们能够经过构建有向图来构建 PageRank 算法。
NetworkX 是一个Python 工具包,其中集成了经常使用的图结构和网络分析算法。
咱们能够用 NetworkX 来构建上图中的网络结构。
首先引入模块:
import networkx as nx
用 DiGraph 类建立有向图:
G = nx.DiGraph()
将4 个网页的连接关系,用数组表示:
edges = [ ("A", "B"), ("A", "C"), ("A", "D"), ("B", "A"), ("B", "D"), ("C", "A"), ("D", "B"), ("D", "C") ]
数组中的元素做为有向图的边,并添加到图中:
for edge in edges: G.add_edge(edge[0], edge[1])
使用pagerank
方法计算PR 分值:
# alpha 为阻尼因子 PRs = nx.pagerank(G, alpha=1) print PRs
输出每一个网页的PR 值:
{'A': 0.33333396911621094, 'B': 0.22222201029459634, 'C': 0.22222201029459634, 'D': 0.22222201029459634}
最终,咱们计算出了每一个网页的PR 值。
NetworkX 包中还提供了画出网络图的方法:
import matplotlib.pyplot as plt # 画网络图 nx.draw_networkx(G) plt.show()
以下:
咱们还能够设置图的形状,节点的大小,边的长度等属性,具体能够点击这里查看。
更多关于 NetworkX 的内容能够参考其官方文档。
PageRank 算法给了咱们一个很重要的启发,权重在不少时候是一个很是重要的指标。
本篇文章主要介绍了:
(本节完。)
推荐阅读:
欢迎关注做者公众号,获取更多技术干货。