想象一座大型美食城,里面有几十家小吃店。每家店门口挂着一块推荐板,顾客吃完后可以写上自己喜欢的店名。怎么判断哪家店最受欢迎?一个简单办法是数谁被写到的次数最多。但你很快会发现,一位连续十年探店的老饕和一位只吃过一家店的路人,签名分量完全不同;更复杂的是,这位老饕自己也是被大家推荐的“名店”的常客。于是每家店的推荐权,取决于推荐者自己的“口碑”,而口碑又来自别人的推荐……这个互相决定的口碑系统,就是 PageRank 算法的核心模型。谷歌用它从海量网页中找出真正重要的页面,后来它成为图分析、网络科学与推荐系统的基石。这篇文章会带你从美食城口碑模型出发,理解原始 PageRank 的数学公式、常见缺陷,以及 Personalized PageRank 等优秀变体。
掌握 PageRank,等于拿到一套分析任意网络影响力的通用工具;无论是搜索引擎排序、社交网络挖掘还是推荐系统,都能用它解决现实问题。
可视化演示
本节配有交互动效(进入视口后自动加载,约 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)$ 表示网页 $u$ 的排名得分,得分越高代表页面越重要。
- 入链集合$B_u$ 是所有通过超链接指向 $u$ 的页面构成的集合。
- 集合大小$|B_u|$ 表示集合中元素的数量,也就是指向 $u$ 的链接总数。
随机游走模型
顾客在美食城并不会看完整张地图才决定去下一家,更多时候是顺着刚吃完饭的店家推荐,随机走向下一家。把这种“随机乱逛”重复无数次,哪家店被踏访的次数多,哪家店就人气高。PageRank 的发明人布林和佩奇正是这样想象用户在网页上的浏览行为——这就是随机游走模型。
如果当前在页面 $v$,它一共链接到 $N_v$ 个页面,那么用户点击其中某个页面 $u$ 的概率就是 $1/N_v$。这相当于把 $v$ 的推荐信均匀地抄送给了所有被链接的页面:
这里的 $P(v \to u)$ 是“从 $v$ 一步跳到 $u$”的转移概率。
随机游走者长期停留在各页面的比例,就是 PageRank 分数。这也是为什么 PageRank 可以被理解为图上的一种“稳态分布”:逛得越久,越常待的店,排名越高。
- 转移概率$P(v \to u)$ 表示用户正停留在页面 $v$,并点击链接跳到页面 $u$ 的概率。
- 出链均分$N_v$ 是页面 $v$ 的出链数量,每个出链被选中的机会相等。
- 概率和为一从 $v$ 出发到所有出链的概率加起来必须等于 1,保证用户一定要选一条路离开。
原始公式推导
美食家的推荐信不能只看一次,因为推荐者本身也在被别人推荐;每家店的推荐价值都与其他店纠缠在一起。PageRank 用迭代的方法破解这种“鸡生蛋、蛋生鸡”:先给每家店一个相同初始分,然后不断按推荐关系重新分配,直到分数稳定。
当一个页面 $v$ 指向另一个页面 $u$ 时,$v$ 会把自己当前的得分平均分成 $N_v$ 份,其中一份送给 $u$。网页 $u$ 的总分就是所有送来的份额之和:
这里的 $B_u$ 是所有指向 $u$ 的页面集合。
需要提醒的是,这个原始版本还没有阻尼因子,后文会看到它在真实网络上很容易出现收敛问题。
- 累加所有入链$\sum_{v \in B_u}$ 表示把所有指向 $u$ 的页面 $v$ 各自贡献的分数加起来。
- 按出链分摊$\frac{R(v)}{N_v}$ 表示页面 $v$ 把自己的得分 $R(v)$ 平均分给它的 $N_v$ 个出链页面,每个出链得到其中一份。
- 迭代逼近由于页面互相引用,公式实际是一个方程组,需要从初始值开始反复迭代求解。
阻尼因子作用
真实顾客不会永远顺着推荐链走下去。他们可能突然想起想吃的麻辣烫,直接打开另一家店的页面。PageRank 把这种“跳出”建模为阻尼因子 $d$:以概率 $d$ 继续点链接,以概率 $1-d$ 随机跳到任意一家店。这样既保留了链接推荐的主线,又给整个系统注入外部流动性。
引入阻尼因子后的迭代公式是:
其中 $N$ 是全网页面总数,$d$ 通常取 0.85。
如果没有这种“跳出”,某些互相抬分的小圈子会不断累积分数,导致排名失衡。阻尼因子相当于给口碑系统安装了“通风口”,让流量不会被局部小团体垄断。
- 随机跳转项$\frac{1-d}{N}$ 表示用户以概率 $1-d$ 不再点链接,而是等概率随机打开全网的 $N$ 个页面之一。
- 链接传播项$d \sum_{v \in B_u} \frac{R(v)}{N_v}$ 表示用户以概率 $d$ 继续点击链接,并按原始 PageRank 规则把分数传给 $u$。
- 系数选择$d=0.85$ 是实验中的常用值,它让算法在“保留链接推荐”和“保证全局可达”之间取得平衡。
死胡同与修正
美食城里总有一些店从来不写推荐信,只默默收下别人的推荐。放在随机游走里,顾客一旦走进这种“没有出链”的页面,就像进了死胡同,再也没法继续点链接,排名分数会不断沉积在这里。这种页面叫做死胡同或悬挂节点,是每个 PageRank 初学者都会遇到的坑。
为了解决泄漏,Google 的做法是把死胡同收集到的分数统一拿出来,再平均分给所有页面。修正后的迭代式可以写成:
其中 $\text{leak}$ 是所有死胡同页面得分之和。
死胡同的修正让总分数始终守恒,迭代才能稳定收敛。没有这一步,排名分数会像漏水的水池一样越来越少。
- 死胡同泄漏$\text{leak}$ 是所有出链数为 0 的页面当前得分总和,它们会让随机游走无法离开。
- 泄漏再分配$\frac{\text{leak}}{N}$ 是把死胡同积攒的分数平均分给全网 $N$ 个页面。
- 修正后的传播括号内同时包含“正常链接传入的分数”和“从死胡同逃逸后重新分配的分数”。
个性化变体
如果你是素食主义者,走进美食城时并不会参考肉食老饕的推荐,而会从自己常去的素食店出发,沿着“气味相投”的推荐链探索。Personalized PageRank(个性化 PageRank)正是把全局排名里的“均匀随机跳转”,换成“按你的偏好跳转”。
设 $s(u)$ 表示你对页面 $u$ 的先验偏好,且所有 $s(u)$ 之和为 1。替代阻尼公式中的均匀项,就能得到个性化 PageRank 的迭代式:
其中 $\alpha$ 是重启概率,常用取值与 $1-d$ 类似,约 0.15。
当 $s$ 取均匀分布时,个性化 PageRank 退化为带阻尼的全局 PageRank;当 $s$ 按主题构造时就是主题敏感搜索;当 $s$ 来自可信种子网站时就是 TrustRank;在推荐系统里,这种方法也叫带重启的随机游走(RWR)。变体的核心是改变“按什么偏好进行随机跳转”,而传播逻辑本身不变。
- 个性化偏好项$\alpha s(u)$ 表示以概率 $\alpha$ 不继续点链接,而是直接跳回用户偏好的页面 $u$,偏好强度由 $s(u)$ 决定。
- 链接传播项$(1-\alpha)\sum_{v \in B_u} \frac{R(v)}{N_v}$ 表示以概率 $1-\alpha$ 继续沿着链接网络传播分数。
- 偏好向量约束$s(u)$ 必须满足 $\sum_u s(u)=1$,这样它才能被解释为“随机跳转的目标概率分布”。
应用场景
美食城口碑模型的适用范围远超餐厅:只要有一张“谁指向谁”的有向图,PageRank 就能回答“哪个节点更重要”。这也解释了为什么一个搜索引擎时代诞生的算法,今天依然活跃在各类图分析任务中。
在搜索引擎中,PageRank 曾经是谷歌排序的核心信号之一,帮助用户从内容农场中筛选出权威页面。在社交网络中,研究者用 Personalized PageRank 从少量可信种子出发计算影响力,找出真正的意见领袖。在推荐系统中,用户和商品可以构成一张二部图,带重启的随机游走能计算任意用户与商品之间的多跳相关性,为“猜你喜欢”提供召回候选。
这类应用共同点是:把具体业务关系抽象成图,再把 PageRank 或它的变体当作图上的相关性度量。只要某个场景能表示为“节点 + 边”,美食城的口碑传播逻辑就能迁移过去。
AI 应用场景
搜索引擎网页排序
阶段:信息检索与网页排序
解决的问题:传统关键词匹配无法区分垃圾站与权威站。就像美食城只看推荐条数会被刷单一样,PageRank 通过链接传递权威分数,让高质量页面浮出水面。
具体案例:Google 早期在搜索结果中融合 PageRank,用户可以更少看到内容农场;直到今天,链接分析仍是大型搜索引擎排序的重要信号之一。
社交网络意见领袖识别
阶段:图特征工程与网络分析
解决的问题:只看粉丝数很容易被僵尸粉欺骗,PageRank 或 TrustRank 从少量可信种子用户出发传播信任,评估真实影响力。
具体案例:Twitter 上分析话题传播网络,从可信媒体种子出发计算 TrustRank 分数,找出真正带动讨论的关键节点。
推荐系统召回
阶段:候选召回与图计算
解决的问题:用户与物品的交互矩阵非常稀疏,直接算相似度经常无解;用带重启的随机游走在用户-物品二部图上做相关性传播,可以找到多跳相关的物品。
具体案例:Pinterest 的 Pixie 推荐系统在超大规模图上用 Personalized PageRank 做毫秒级召回,大幅提升推荐点击率和转化率。
Python 演示
# -*- 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))
rank = [1.0 / n for _ in pages]初始化每个网页得分相等,保证所有分数总和为 1。leak = sum(rank[index[p]] for p in pages if out_degree[p] == 0)计算死胡同页面攒下的分数,后面会分给全网。share = rank[index[p]] / out_degree[p]把页面 p 的得分按出链数均匀分给每个被链接页面。new_rank[index[q]] += damping * share只有 d 比例的分数通过链接传播,剩下的留给随机跳转。new_rank[i] += damping * leak / n把死胡同泄漏的分数重新平均分配到每个页面。if diff < tol: break当两轮之间的变化足够小,就认为 PageRank 已经收敛。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 中,一个网页的排名得分主要由什么决定?
- A.域名年龄和服务器速度
- B.来自重要页面的入链加权← 正确答案
- C.页面上的图片数量大小
- D.提交搜索引擎的次数
答案:B。PageRank 看入链,但更看入链来源本身的重要性;域名年龄、图片数量、提交次数都不是核心。就像美食城口碑不是看推荐条数,而是看推荐人的口碑。
Q2. 一个网页有 4 个出链,在随机游走中它如何把得分分给每个出链?
- A.全部分给第一个出链
- B.按出链权重四六分配
- C.平均分配四分之一得分← 正确答案
- D.随机分配不确定份额
答案:C。随机游走假设点击每条链接的概率相等,所以每个出链得到四分之一的分数。相当于店家把推荐信平均抄送给四个被推荐对象。
Q3. PageRank 引入阻尼因子 d 的主要目的是?
- A.提高网页的加载速度
- B.模拟用户停链随机跳转← 正确答案
- C.降低服务器并发压力
- D.仅用于处理死胡同节点
答案:B。阻尼因子 d 模拟用户以概率 1-d 停止点链接、直接换一个网址。它保证随机游走不会困在小圈子里,也让迭代能够收敛。其余选项与算法设计动机无关。
Q4. 哪种页面被称为死胡同(Dead End)?
- A.没有任何入链的页面
- B.没有任何出链的页面← 正确答案
- C.加载速度特别慢的页面
- D.内容完全重复的页面
答案:B。死胡同是没有出链的页面,走进去的游走者无处可去,因此迭代时必须处理分数泄漏。没有入链只是不接收投票,并不是死胡同。
Q5. 以下哪些属于 PageRank 的个性化变体?
- A.个性化 PageRank 算法← 正确答案
- B.TrustRank 可信排名算法← 正确答案
- C.TF-IDF 关键词加权法
- D.主题敏感 PageRank 法← 正确答案
答案:ABD。个性化 PageRank、TrustRank、主题敏感 PageRank 都通过改变随机跳转偏好形成变体;TF-IDF 是文本检索中的词语权重方法,与链接传播无关。
Q6. TrustRank 的种子集合通常选择什么页面?
- A.随机抽取的所有页面
- B.人工筛选的高可信页面← 正确答案
- C.页面数量最多的站点
- D.出链数量最多的页面
答案:B。TrustRank 从人工筛选的可信页面出发传播信任分,避免垃圾网站靠互相链接刷排名。就像选一批公认的老饕来发起美食城口碑评价。
Q7. 在 PageRank 迭代中,死胡同会导致哪些问题?
- A.概率和质量不再守恒← 正确答案
- B.排名分数向死胡同泄漏← 正确答案
- C.迭代过程可能无法收敛← 正确答案
- D.计算机内存占用上升
答案:ABC。死胡同让随机游走者无法离开,总分数会不断沉积,导致概率不守恒、分数泄漏甚至不收敛。内存占用与死胡同没有直接关系。
Q8. Personalized PageRank 与全局 PageRank 的主要区别是什么?
- A.用个性化向量替换均匀跳转← 正确答案
- B.去掉了所有链接传播项
- C.只计算用户直接访问的页面
- D.用入链数量直接代替迭代
答案:A。PPR 把全局 PageRank 中的均匀随机跳转换成个性化向量,每次迭代以概率 α 跳回偏好页面;它并没有去掉链接传播,也不是只算直接点击,更不是用入链数量代替迭代。
Q9. 设 N=10 个页面,d=0.85,某页面没有任何入链,只靠均匀随机跳转获得的基础分为多少?
- A.0.015← 正确答案
- B.0.100
- C.0.850
- D.0.085
答案:A。均匀随机跳转项为 (1-d)/N = (1-0.85)/10 = 0.015。注意它只是基础分,若页面上还有死胡同泄漏重分配,总分还会更高。
Q10. 关于 PageRank 的迭代计算,下列说法正确的是?
- A.初始分数可以任意归一化← 正确答案
- B.最终排名与初始值无关← 正确答案
- C.每轮更新需要全网数据← 正确答案
- D.单次迭代即可精确收敛
答案:ABC。PageRank 的初始值只要满足总和为 1,最终都收敛到同一个稳态分布;每轮更新需要遍历全网的链接关系,因此不是单次迭代就能精确完成的。