想象一座大型美食城,里面有几十家小吃店。每家店门口挂着一块推荐板,顾客吃完后可以写上自己喜欢的店名。怎么判断哪家店最受欢迎?一个简单办法是数谁被写到的次数最多。但你很快会发现,一位连续十年探店的老饕和一位只吃过一家店的路人,签名分量完全不同;更复杂的是,这位老饕自己也是被大家推荐的“名店”的常客。于是每家店的推荐权,取决于推荐者自己的“口碑”,而口碑又来自别人的推荐……这个互相决定的口碑系统,就是 PageRank 算法的核心模型。谷歌用它从海量网页中找出真正重要的页面,后来它成为图分析、网络科学与推荐系统的基石。这篇文章会带你从美食城口碑模型出发,理解原始 PageRank 的数学公式、常见缺陷,以及 Personalized PageRank 等优秀变体。

岗位关联

掌握 PageRank,等于拿到一套分析任意网络影响力的通用工具;无论是搜索引擎排序、社交网络挖掘还是推荐系统,都能用它解决现实问题。

目录
  1. 可视化演示
  2. 链接投票思想
  3. 随机游走模型
  4. 原始公式推导
  5. 阻尼因子作用
  6. 死胡同与修正
  7. 个性化变体
  8. 应用场景
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

本节配有交互动效(进入视口后自动加载,约 3KB)。

PageRank公式 d * \u03A3 PR(j)/L(j)PR(i) = (1-d)/N +N=节点数PageRank通过随机游走评估节点重要性:PR(i)=(1-d)/N + d*\u03A3PR(j)/L(j); 个性化版本修改随机跳跃目标分布

链接投票思想

美食城里的每家店都有一块推荐板,顾客吃完后可以把店名写在上面。如果只看谁被写到的次数最多,一家店可能雇人刷屏就冲上榜首。PageRank 想解决的,正是这种“只看票数、不看投票人”的问题。在 PageRank 的世界里,每个网页都是一家店,网页之间的超链接就是一张写出去的推荐票。指向某个网页的链接越多,说明它的口碑越广。

从直觉出发,最简单的排名就是统计入链数量:

其中 $B_u$ 是所有指向网页 $u$ 的页面集合。这相当于“谁收到的推荐最多,谁就最有人气”。

不过,仅数推荐笔迹很容易被垃圾链接刷出来。真正的口碑不是“谁写得多”,而是“谁写的更有分量”。所以 PageRank 用了更聪明的递归思想:你的价值,由推荐你的人的价值共同决定。

R(u)=∣Bu∣\displaystyle R(u) = |B_u|
这个公式说明,一个网页的重要性等于它的入链总数,但它还没有考虑“投票者”本身的重要程度。
  1. 得分符号公式左侧的 $R(u)$ 表示网页 $u$ 的排名得分,得分越高代表页面越重要。
    R(u)R(u)
  2. 入链集合$B_u$ 是所有通过超链接指向 $u$ 的页面构成的集合。
    Bu={v∣v→u}B_u = \{ v \mid v \to u \}
  3. 集合大小$|B_u|$ 表示集合中元素的数量,也就是指向 $u$ 的链接总数。
    ∣Bu∣|B_u|

随机游走模型

顾客在美食城并不会看完整张地图才决定去下一家,更多时候是顺着刚吃完饭的店家推荐,随机走向下一家。把这种“随机乱逛”重复无数次,哪家店被踏访的次数多,哪家店就人气高。PageRank 的发明人布林和佩奇正是这样想象用户在网页上的浏览行为——这就是随机游走模型。

如果当前在页面 $v$,它一共链接到 $N_v$ 个页面,那么用户点击其中某个页面 $u$ 的概率就是 $1/N_v$。这相当于把 $v$ 的推荐信均匀地抄送给了所有被链接的页面:

这里的 $P(v \to u)$ 是“从 $v$ 一步跳到 $u$”的转移概率。

随机游走者长期停留在各页面的比例,就是 PageRank 分数。这也是为什么 PageRank 可以被理解为图上的一种“稳态分布”:逛得越久,越常待的店,排名越高。

P(v→u)=1Nv\displaystyle P(v \to u) = \frac{1}{N_v}
出链越多,每一条链接分到的概率越小;这和店家只能把一份口碑平均分给很多介绍对象,道理完全一样。
  1. 转移概率$P(v \to u)$ 表示用户正停留在页面 $v$,并点击链接跳到页面 $u$ 的概率。
    P(v→u)P(v \to u)
  2. 出链均分$N_v$ 是页面 $v$ 的出链数量,每个出链被选中的机会相等。
    Nv=∣{w∣v→w}∣N_v = |\{ w \mid v \to w \}|
  3. 概率和为一从 $v$ 出发到所有出链的概率加起来必须等于 1,保证用户一定要选一条路离开。
    ∑u:v→uP(v→u)=1\sum_{u: v \to u} P(v \to u) = 1

原始公式推导

美食家的推荐信不能只看一次,因为推荐者本身也在被别人推荐;每家店的推荐价值都与其他店纠缠在一起。PageRank 用迭代的方法破解这种“鸡生蛋、蛋生鸡”:先给每家店一个相同初始分,然后不断按推荐关系重新分配,直到分数稳定。

当一个页面 $v$ 指向另一个页面 $u$ 时,$v$ 会把自己当前的得分平均分成 $N_v$ 份,其中一份送给 $u$。网页 $u$ 的总分就是所有送来的份额之和:

这里的 $B_u$ 是所有指向 $u$ 的页面集合。

需要提醒的是,这个原始版本还没有阻尼因子,后文会看到它在真实网络上很容易出现收敛问题。

R(u)=∑v∈BuR(v)Nv\displaystyle R(u) = \sum_{v \in B_u} \frac{R(v)}{N_v}
这个公式说明:一个页面得到的分数,等于所有“投票页面”分数的加权和;每个投票者能投出的总分就是它自己的 PageRank 值。
  1. 累加所有入链$\sum_{v \in B_u}$ 表示把所有指向 $u$ 的页面 $v$ 各自贡献的分数加起来。
    ∑v∈Bu\sum_{v \in B_u}
  2. 按出链分摊$\frac{R(v)}{N_v}$ 表示页面 $v$ 把自己的得分 $R(v)$ 平均分给它的 $N_v$ 个出链页面,每个出链得到其中一份。
    R(v)Nv\frac{R(v)}{N_v}
  3. 迭代逼近由于页面互相引用,公式实际是一个方程组,需要从初始值开始反复迭代求解。
    R(t+1)(u)=∑v∈BuR(t)(v)NvR^{(t+1)}(u) = \sum_{v \in B_u} \frac{R^{(t)}(v)}{N_v}

阻尼因子作用

真实顾客不会永远顺着推荐链走下去。他们可能突然想起想吃的麻辣烫,直接打开另一家店的页面。PageRank 把这种“跳出”建模为阻尼因子 $d$:以概率 $d$ 继续点链接,以概率 $1-d$ 随机跳到任意一家店。这样既保留了链接推荐的主线,又给整个系统注入外部流动性。

引入阻尼因子后的迭代公式是:

其中 $N$ 是全网页面总数,$d$ 通常取 0.85。

如果没有这种“跳出”,某些互相抬分的小圈子会不断累积分数,导致排名失衡。阻尼因子相当于给口碑系统安装了“通风口”,让流量不会被局部小团体垄断。

R(u)=1−dN+d∑v∈BuR(v)Nv\displaystyle R(u) = \frac{1-d}{N} + d \sum_{v \in B_u} \frac{R(v)}{N_v}
公式右边第一项是“随机跳到任意页面的均匀概率”,第二项是“顺着链接到达的概率”。即使一个页面没有任何入链,它也能获得一个基础分。
  1. 随机跳转项$\frac{1-d}{N}$ 表示用户以概率 $1-d$ 不再点链接,而是等概率随机打开全网的 $N$ 个页面之一。
    1−dN\frac{1-d}{N}
  2. 链接传播项$d \sum_{v \in B_u} \frac{R(v)}{N_v}$ 表示用户以概率 $d$ 继续点击链接,并按原始 PageRank 规则把分数传给 $u$。
    d∑v∈BuR(v)Nvd \sum_{v \in B_u} \frac{R(v)}{N_v}
  3. 系数选择$d=0.85$ 是实验中的常用值,它让算法在“保留链接推荐”和“保证全局可达”之间取得平衡。
    d=0.85d = 0.85

死胡同与修正

美食城里总有一些店从来不写推荐信,只默默收下别人的推荐。放在随机游走里,顾客一旦走进这种“没有出链”的页面,就像进了死胡同,再也没法继续点链接,排名分数会不断沉积在这里。这种页面叫做死胡同或悬挂节点,是每个 PageRank 初学者都会遇到的坑。

为了解决泄漏,Google 的做法是把死胡同收集到的分数统一拿出来,再平均分给所有页面。修正后的迭代式可以写成:

其中 $\text{leak}$ 是所有死胡同页面得分之和。

死胡同的修正让总分数始终守恒,迭代才能稳定收敛。没有这一步,排名分数会像漏水的水池一样越来越少。

R(u)=1−dN+d(∑v∈BuR(v)Nv+leakN)\displaystyle R(u) = \frac{1-d}{N} + d \left( \sum_{v \in B_u} \frac{R(v)}{N_v} + \frac{\text{leak}}{N} \right)
这个公式相当于把“黑洞”里积压的口碑分数重新撒回整个美食城,保证总分数不丢失。
  1. 死胡同泄漏$\text{leak}$ 是所有出链数为 0 的页面当前得分总和,它们会让随机游走无法离开。
    leak=∑v∈DR(v)\text{leak} = \sum_{v \in D} R(v)
  2. 泄漏再分配$\frac{\text{leak}}{N}$ 是把死胡同积攒的分数平均分给全网 $N$ 个页面。
    leakN\frac{\text{leak}}{N}
  3. 修正后的传播括号内同时包含“正常链接传入的分数”和“从死胡同逃逸后重新分配的分数”。
    d(∑v∈BuR(v)Nv+leakN)d\left( \sum_{v \in B_u} \frac{R(v)}{N_v} + \frac{\text{leak}}{N} \right)

个性化变体

如果你是素食主义者,走进美食城时并不会参考肉食老饕的推荐,而会从自己常去的素食店出发,沿着“气味相投”的推荐链探索。Personalized PageRank(个性化 PageRank)正是把全局排名里的“均匀随机跳转”,换成“按你的偏好跳转”。

设 $s(u)$ 表示你对页面 $u$ 的先验偏好,且所有 $s(u)$ 之和为 1。替代阻尼公式中的均匀项,就能得到个性化 PageRank 的迭代式:

其中 $\alpha$ 是重启概率,常用取值与 $1-d$ 类似,约 0.15。

当 $s$ 取均匀分布时,个性化 PageRank 退化为带阻尼的全局 PageRank;当 $s$ 按主题构造时就是主题敏感搜索;当 $s$ 来自可信种子网站时就是 TrustRank;在推荐系统里,这种方法也叫带重启的随机游走(RWR)。变体的核心是改变“按什么偏好进行随机跳转”,而传播逻辑本身不变。

R(u)=(1−α)∑v∈BuR(v)Nv+αs(u)\displaystyle R(u) = (1-\alpha)\sum_{v \in B_u} \frac{R(v)}{N_v} + \alpha s(u)
从美食城的视角看,$\alpha s(u)$ 相当于“我每隔一阵就回到自己最喜欢的素食店重新出发”,而不是随机跳到任意一家店。
  1. 个性化偏好项$\alpha s(u)$ 表示以概率 $\alpha$ 不继续点链接,而是直接跳回用户偏好的页面 $u$,偏好强度由 $s(u)$ 决定。
    αs(u)\alpha s(u)
  2. 链接传播项$(1-\alpha)\sum_{v \in B_u} \frac{R(v)}{N_v}$ 表示以概率 $1-\alpha$ 继续沿着链接网络传播分数。
    (1−α)∑v∈BuR(v)Nv(1-\alpha)\sum_{v \in B_u} \frac{R(v)}{N_v}
  3. 偏好向量约束$s(u)$ 必须满足 $\sum_u s(u)=1$,这样它才能被解释为“随机跳转的目标概率分布”。
    ∑us(u)=1\sum_u s(u)=1

应用场景

美食城口碑模型的适用范围远超餐厅:只要有一张“谁指向谁”的有向图,PageRank 就能回答“哪个节点更重要”。这也解释了为什么一个搜索引擎时代诞生的算法,今天依然活跃在各类图分析任务中。

在搜索引擎中,PageRank 曾经是谷歌排序的核心信号之一,帮助用户从内容农场中筛选出权威页面。在社交网络中,研究者用 Personalized PageRank 从少量可信种子出发计算影响力,找出真正的意见领袖。在推荐系统中,用户和商品可以构成一张二部图,带重启的随机游走能计算任意用户与商品之间的多跳相关性,为“猜你喜欢”提供召回候选。

这类应用共同点是:把具体业务关系抽象成图,再把 PageRank 或它的变体当作图上的相关性度量。只要某个场景能表示为“节点 + 边”,美食城的口碑传播逻辑就能迁移过去。

AI 应用场景

搜索引擎网页排序

阶段:信息检索与网页排序

解决的问题:传统关键词匹配无法区分垃圾站与权威站。就像美食城只看推荐条数会被刷单一样,PageRank 通过链接传递权威分数,让高质量页面浮出水面。

具体案例:Google 早期在搜索结果中融合 PageRank,用户可以更少看到内容农场;直到今天,链接分析仍是大型搜索引擎排序的重要信号之一。

社交网络意见领袖识别

阶段:图特征工程与网络分析

解决的问题:只看粉丝数很容易被僵尸粉欺骗,PageRank 或 TrustRank 从少量可信种子用户出发传播信任,评估真实影响力。

具体案例:Twitter 上分析话题传播网络,从可信媒体种子出发计算 TrustRank 分数,找出真正带动讨论的关键节点。

推荐系统召回

阶段:候选召回与图计算

解决的问题:用户与物品的交互矩阵非常稀疏,直接算相似度经常无解;用带重启的随机游走在用户-物品二部图上做相关性传播,可以找到多跳相关的物品。

具体案例:Pinterest 的 Pixie 推荐系统在超大规模图上用 Personalized PageRank 做毫秒级召回,大幅提升推荐点击率和转化率。

Python 演示

python45 行
# -*- coding: utf-8 -*-"""从零实现 PageRank 迭代计算"""  def page_rank(graph, damping=0.85, max_iter=100, tol=1e-6):    pages = list(graph.keys())    n = len(pages)    index = {p: i for i, p in enumerate(pages)}    rank = [1.0 / n for _ in pages]    out_degree = {p: len(graph[p]) for p in pages}     for _ in range(max_iter):        new_rank = [(1.0 - damping) / n for _ in pages]        leak = sum(rank[index[p]] for p in pages if out_degree[p] == 0)         for p in pages:            if out_degree[p] == 0:                continue            share = rank[index[p]] / out_degree[p]            for q in graph[p]:                new_rank[index[q]] += damping * share         # 把死胡同泄漏的分数平均分给所有页面        for i in range(n):            new_rank[i] += damping * leak / n         diff = sum(abs(new_rank[i] - rank[i]) for i in range(n))        rank = new_rank        if diff < tol:            break     return {p: rank[index[p]] for p in pages}  if __name__ == "__main__":    web = {        "A": ["B", "C"],        "B": ["C"],        "C": ["A"],        "D": ["C", "E"],        "E": ["D"],    }    result = page_rank(web)    for page, score in sorted(result.items(), key=lambda x: -x[1]):        print("{}: {:.4f}".format(page, score))
目的:在小型网页图上演示带阻尼因子和死胡同修正的 PageRank 迭代,最终输出每个页面的排名分数。
  1. rank = [1.0 / n for _ in pages]初始化每个网页得分相等,保证所有分数总和为 1。
  2. leak = sum(rank[index[p]] for p in pages if out_degree[p] == 0)计算死胡同页面攒下的分数,后面会分给全网。
  3. share = rank[index[p]] / out_degree[p]把页面 p 的得分按出链数均匀分给每个被链接页面。
  4. new_rank[index[q]] += damping * share只有 d 比例的分数通过链接传播,剩下的留给随机跳转。
  5. new_rank[i] += damping * leak / n把死胡同泄漏的分数重新平均分配到每个页面。
  6. if diff < tol: break当两轮之间的变化足够小,就认为 PageRank 已经收敛。
  7. result = page_rank(web)传入网页链接字典,返回每个页面的最终得分。

常见误区

误区我以为 PageRank 等于统计一个网页有多少反向链接,链接越多排名越高,和投票计数没什么区别。

正解简单入链数只是初始启发,PageRank 的关键是加权传递:投票者自身得分越高,它投出的票越值钱。否则垃圾网站互相刷链接就能冲上榜首。就像美食城推荐不能只看签名数量,还要看签名者自己的口碑。

为何常见:因为 PageRank 确实以入链为基础,教学简化时很容易丢掉权重传递这一步。

误区我会觉得 d 越接近 1,链接传播越充分,PageRank 效果应该越好,最好设成 0.99。

正解d 太大会让随机游走几乎不跳出,在强连通分量里反复循环,收敛变慢且对死胡同更敏感。d=0.85 是实验得到的平衡点,既保留链接推荐,又确保全局可达。

为何常见:很多人从“多传播信息”的直觉出发,忽略了跳出机制是为了保证收敛和全局排名质量。

误区我总觉得 PageRank 只是谷歌给网页排名的算法,离开搜索引擎就没有用武之地。

正解PageRank 本质是图上节点重要性的度量方法,任何能用有向图建模的系统都可以使用,比如社交网络影响力、论文引用、蛋白质网络、推荐系统。就像推荐信机制不仅能评价餐厅,也能评价任何被推荐的对象。

为何常见:算法起源于搜索引擎,名字也总是和 Google 绑定,容易让人忽略它的图算法本质。

误区我以为个性化版本就是把每个页面的初始分数按偏好调整,然后再跑一遍全局 PageRank。

正解PPR 的偏好向量 s 是每一次迭代中“随机跳转”的目标分布,而不是一次性初始值。它持续影响游走过程,相当于每隔一段时间就按你的口味回到起点。只改初始值,会在第一次迭代后就被链接结构淹没。

为何常见:因为 PageRank 初始化也是用均匀值,很容易把“初始值”和“随机跳转偏好”混为一谈。

误区我倾向于认为一个网页没有出链只是它自己无法继续得分,对其他网页没什么影响。

正解死胡同会让随机游走卡住,导致整个图的排名分数不断泄漏,所有节点的分数都被拉低。PageRank 必须把这些分数捞出来重新分配,否则总概率不守恒,迭代甚至不收敛。就像美食城一家不推荐别人的店,会让整条推荐链在它那里断掉。

为何常见:直觉上觉得无出链只影响该页面,忽略了 PageRank 是一个全局概率系统,分数需要在整个图上守恒。

面试题

Q1. PageRank 中,一个网页的排名得分主要由什么决定?

单选题 · easy

  • A.域名年龄和服务器速度
  • B.来自重要页面的入链加权← 正确答案
  • C.页面上的图片数量大小
  • D.提交搜索引擎的次数

答案:B。PageRank 看入链,但更看入链来源本身的重要性;域名年龄、图片数量、提交次数都不是核心。就像美食城口碑不是看推荐条数,而是看推荐人的口碑。

Q2. 一个网页有 4 个出链,在随机游走中它如何把得分分给每个出链?

单选题 · easy

  • A.全部分给第一个出链
  • B.按出链权重四六分配
  • C.平均分配四分之一得分← 正确答案
  • D.随机分配不确定份额

答案:C。随机游走假设点击每条链接的概率相等,所以每个出链得到四分之一的分数。相当于店家把推荐信平均抄送给四个被推荐对象。

Q3. PageRank 引入阻尼因子 d 的主要目的是?

单选题 · mid

  • A.提高网页的加载速度
  • B.模拟用户停链随机跳转← 正确答案
  • C.降低服务器并发压力
  • D.仅用于处理死胡同节点

答案:B。阻尼因子 d 模拟用户以概率 1-d 停止点链接、直接换一个网址。它保证随机游走不会困在小圈子里,也让迭代能够收敛。其余选项与算法设计动机无关。

Q4. 哪种页面被称为死胡同(Dead End)?

单选题 · mid

  • A.没有任何入链的页面
  • B.没有任何出链的页面← 正确答案
  • C.加载速度特别慢的页面
  • D.内容完全重复的页面

答案:B。死胡同是没有出链的页面,走进去的游走者无处可去,因此迭代时必须处理分数泄漏。没有入链只是不接收投票,并不是死胡同。

Q5. 以下哪些属于 PageRank 的个性化变体?

多选题 · mid

  • A.个性化 PageRank 算法← 正确答案
  • B.TrustRank 可信排名算法← 正确答案
  • C.TF-IDF 关键词加权法
  • D.主题敏感 PageRank 法← 正确答案

答案:ABD。个性化 PageRank、TrustRank、主题敏感 PageRank 都通过改变随机跳转偏好形成变体;TF-IDF 是文本检索中的词语权重方法,与链接传播无关。

Q6. TrustRank 的种子集合通常选择什么页面?

单选题 · easy

  • A.随机抽取的所有页面
  • B.人工筛选的高可信页面← 正确答案
  • C.页面数量最多的站点
  • D.出链数量最多的页面

答案:B。TrustRank 从人工筛选的可信页面出发传播信任分,避免垃圾网站靠互相链接刷排名。就像选一批公认的老饕来发起美食城口碑评价。

Q7. 在 PageRank 迭代中,死胡同会导致哪些问题?

多选题 · hard

  • A.概率和质量不再守恒← 正确答案
  • B.排名分数向死胡同泄漏← 正确答案
  • C.迭代过程可能无法收敛← 正确答案
  • D.计算机内存占用上升

答案:ABC。死胡同让随机游走者无法离开,总分数会不断沉积,导致概率不守恒、分数泄漏甚至不收敛。内存占用与死胡同没有直接关系。

Q8. Personalized PageRank 与全局 PageRank 的主要区别是什么?

单选题 · hard

  • A.用个性化向量替换均匀跳转← 正确答案
  • B.去掉了所有链接传播项
  • C.只计算用户直接访问的页面
  • D.用入链数量直接代替迭代

答案:A。PPR 把全局 PageRank 中的均匀随机跳转换成个性化向量,每次迭代以概率 α 跳回偏好页面;它并没有去掉链接传播,也不是只算直接点击,更不是用入链数量代替迭代。

Q9. 设 N=10 个页面,d=0.85,某页面没有任何入链,只靠均匀随机跳转获得的基础分为多少?

单选题 · hard

  • A.0.015← 正确答案
  • B.0.100
  • C.0.850
  • D.0.085

答案:A。均匀随机跳转项为 (1-d)/N = (1-0.85)/10 = 0.015。注意它只是基础分,若页面上还有死胡同泄漏重分配,总分还会更高。

Q10. 关于 PageRank 的迭代计算,下列说法正确的是?

多选题 · hard

  • A.初始分数可以任意归一化← 正确答案
  • B.最终排名与初始值无关← 正确答案
  • C.每轮更新需要全网数据← 正确答案
  • D.单次迭代即可精确收敛

答案:ABC。PageRank 的初始值只要满足总和为 1,最终都收敛到同一个稳态分布;每轮更新需要遍历全网的链接关系,因此不是单次迭代就能精确完成的。