概述
PageRank(网页排名)最初是在万维网(WWW)的背景下提出的,它利用WWW的链接结构来产生全局、客观的网页“重要性”排名供搜索引擎使用。该算法由Google联合创始人Larry Page和Sergey Brin于1997-1998年提出:
- L. Page, S Brin, R. Motwani, T. Winograd, The PageRank Citation Ranking: Bringing Order to The Web (1998)
随着技术的发展与大量关联性数据的产生,PageRank也被许多其他领域采用。
基本概念
链接结构与PageRank
在WWW中,网页中包含的超文本在网页之间创建链接。每个网页(节点)都可以有一些前链(通过出边连接)和后链(通过入边连接)。在下图中,A和B是C的后链,D是C的前链。
![](https://img.ultipa.cn/draw/draw_d6f0d10ef4474654a770555b6336ae8f.jpg?v='1678960967643')
不同网页在后链数量方面差异很大。在自然状态下,那些重要、权威或高质量的网页会获得更多或更重要的后链。
PageRank的核心思想是:一个网页的后链的排名总和越高,则该网页的排名就越高。这同时涵盖了两种情况,一是网页有大量的后链,二是网页的后链尽管数量不多但排名很高。
排名传递
所有网页的排名(分值)是以递归的方式计算的,所有网页的初始排名分值可以是任意的,然后进行迭代计算直至收敛。在每次迭代中,每个网页均匀地将其自身的排名分值传递给其所有的前链;同时,每个网页都从其所有后链获得排名分值。因此,网页u在一次迭代后的排名分值为:
![](https://img.ultipa.cn/img/2023-03-16-17-56-34-PR.jpg)
其中Bu是网页u的后链集合。
以下是一组网页间的排名传递达到稳定的状态:
![](https://img.ultipa.cn/draw/draw_e63020fcb3904d3b9c87b348c49df620.jpg?v='1678961307271')
阻尼系数
考虑以下几种类型的网页:
- 没有后链的网页。它们获得的排名是0,但它们仍需被浏览到。
- 没有前链的网页。它们的排名分值会从系统中消失。
- 对于一组网页,它们只指向组内的网页,而不指向任何组外的网页。
为了克服这些问题,我们引入阻尼系数(Damping Factor),其值介于0和1之间。它为每个网页提供一个保底排名分值,同时削弱从后链传递过来的排名分值。一次迭代后网页u的排名变为:
![](https://img.ultipa.cn/img/2023-03-23-11-39-14-pr2.jpg)
其中d是阻尼系数。例如,当d=0.7时,如果一个网页从后链接收到的排名总和为8,则该网页在本轮的排名为0.7*8 + (1-0.7) = 5.9
。
阻尼系数也可以理解为浏览者随机跳转到不是当前网页的前链之一的其他网页的概率。
特殊说明
- 孤点的排名将为(1-d)。
- 自环边被视为一条入边和一条出边,网页会通过自环边会将一部分排名传递给自身。有大量自环边的图通常需要较多次的迭代才能趋于稳定。
语法
- 命令:
algo(page_rank)
- 参数:
名称 |
类型 |
规范 |
默认 |
可选 |
描述 |
---|---|---|---|---|---|
init_value | float | >0 | 0.2 |
是 | 所有点的初始排名 |
loop_num | int | >=1 | 5 |
是 | 迭代轮数 |
damping | float | (0,1) | 0.8 |
是 | 阻尼系数 |
weaken | int | 1 , 2 |
1 |
是 | 计算PageRank时,保持此项为1 ;2 代表计算ArticleRank |
limit | int | ≥-1 | -1 |
是 | 返回的结果条数,-1 返回所有结果 |
order | string | asc , desc |
/ | 是 | 按排名分值大小对结果进行排序 |
示例
示例图如下:
![](https://img.ultipa.cn/draw/draw_0d0220f4b4e144b99050857de4ca2577.jpg?v='1680581529282')
文件回写
配置项 | 回写内容 |
---|---|
filename | _id ,rank |
algo(page_rank).params({
init_value: 1,
loop_num: 50,
damping: 0.8,
weaken: 1,
order: 'desc'
}).write({
file: {filename: 'rank'}
})
结果:文件rank
E,3.96235
F,1.61052
N,1.48175
G,1.25663
I,1.25663
B,0.844209
L,0.844209
K,0.702651
M,0.48106
J,0.36
H,0.333333
A,0.333333
C,0.333333
D,0.2
属性回写
配置项 | 回写内容 | 回写至 | 数据类型 |
---|---|---|---|
property | rank |
点属性 | / |
algo(page_rank).params({
loop_num: 50,
weaken: 1
}).write({
db:{property: 'PR'}
})
结果:每个节点的排名回写至名为PR的点属性下
直接返回
别名序号 | 类型 | 描述 | 列名 |
---|---|---|---|
0 | []perNode | 点及其排名 | _uuid , rank |
algo(page_rank).params({
init_value: 1,
loop_num: 50,
damping: 0.8,
weaken: 1,
order: 'desc',
limit: 5
}) as PR
return PR
结果:PR
_uuid | rank |
---|---|
5 | 3.9623489 |
6 | 1.6105210 |
14 | 1.4817491 |
7 | 1.2566270 |
9 | 1.2566270 |
流式返回
别名序号 | 类型 | 描述 | 列名 |
---|---|---|---|
0 | []perNode | 点及其排名 | _uuid , rank |
algo(page_rank).params({
loop_num: 50,
damping: 0.8,
weaken: 1,
order: 'desc',
limit: 5
}).stream() as PR
find().nodes({_uuid == PR._uuid}) as nodes
return table(nodes._id, PR.rank)
结果:table(nodes._id, PR.rank)
nodes._id | PR.rank |
---|---|
E | 3.9623020 |
F | 1.6104970 |
N | 1.4817290 |
G | 1.2566110 |
I | 1.2566110 |