稀缺即正义:搜索引擎的评分哲学
经济学里有个概念叫"稀缺性"——用来衡量价值。黄金比铁贵,钻石比玻璃贵。
但在搜索技术中,"稀缺性"却能带来另外一种重要作用——消除歧义。
想想看:为什么有些词一搜就能精准定位,有些词一搜却冒出一堆无关结果?
答案就藏在"稀缺性"里。
从一个直觉问题开始
搜"拙政园"时,我们立刻就能想到苏州那个园林——全中国只有一个拙政园,没有任何歧义。但搜"西湖"时,我们可能会愣一下:扬州还有个瘦西湖,名字里也带着"西湖"两个字。到底是杭州的西湖,还是扬州的瘦西湖?
搜"人民广场"时,我们更懵了:全国几乎每个城市都有一个人民广场,到底想找哪一个?
为什么同样是搜索,有的词能让我们秒定位,有的词却让我们犯难?
这个问题的答案,藏在"区分度"三个字里,而区分度本身,则与文本的稀缺性息息相关。
区分度:一个连续的光谱
假设你手里只有全国 5A 级景区名录,大概三百多个。"拙政园"和"西湖"的区分度都很高。但"西湖"略输一筹——扬州的瘦西湖也是 5A 级,名字里带着"西湖",多少带来一丝模糊。而"拙政园"独一无二,没有这个问题。
把资源池扩大到 4A + 5A 级景区,几千个。"西湖"的区分度进一步下降:安徽阜阳的"颍州西湖"、杭州的"西湖龙坞茶镇",名字里都带着"西湖"。光是这个级别,"西湖"就已经被好几个景区共享了。"拙政园"依然稳如泰山。
再扩展到地图上的全部 POI——几千万个。周边 POI 大量出现:"拙政园苏博站"、"如家酒店拙政园店"、"拙政园停车场"……但即便如此,"拙政园"仍保持较高区分度——这些周边 POI 全都围绕在苏州拙政园附近。"西湖"就没这么幸运——瘦西湖的 POI 分词时可能被拆成"瘦"+"西湖",再加上"西湖文化广场"、"西湖大学"……区分度被进一步稀释。而"人民广场"呢?上千条 POI 分布在全国各地,已经完全无法定位到任何一条。
这就是区分度:一个词在总资源池中出现得越多,反而越不聚焦。
IDF 就是区分度的数学表达——一个词在资源池中出现的范围越窄,IDF 越高,区分度越强。
搜索引擎用"文档频率"来近似衡量一个词的区分度——一个词出现的文档越少,说明它的区分度越强。TF-IDF 就是为了解决这个问题而生的,它用 IDF 量化了词的区分度,用 TF 筛选出最专注的文档。
TF-IDF
怎么用数学来量化这种区分度?评分由两部分组成——词本身的专属性(IDF)和文档的专注度(TF)。TF-IDF 分别量化了这两个维度。
假设我们的语料库是全国所有大小景点的介绍文章,总共有几万篇。你希望搜一个词,就能从里面找出最相关的那篇。
怎么判断哪篇最相关?这里主要依靠两个直觉。
第一个直觉:这个词在多少篇文章里出现过?
当你搜"拙政园"时,为什么能秒定位?因为"拙政园"这个名字,几乎只属于苏州那一个地方——提到它的文章可能有几百篇。而"人民广场"呢?几乎每个城市都有一个,成千上万篇文章都可能提到了它。两相对比,"拙政园"有一种独一无二的确定性——我们此前说过:一个词出现的地方越少,说明它的专属性越强,指向性越明确。
看看这几个词的专属性梯度:
-
"拙政园"只出现在几百篇文章中——这个名字几乎专属于苏州那一个地方
-
"西湖"出现在几千篇中——虽然最知名的是杭州西湖,但瘦西湖、颍州西湖也在分享这个名字
-
"人民广场"、"人民公园"出现在上万篇中——这个名字太泛了,谁都能叫
这种不需要人工标注,不需要知识图谱,只靠统计词在文档中的分布,就能自动衡量一个词的"专属性",就是"逆文档频率"(IDF,Inverse Document Frequency):
说明:这是 Lucene 实际使用的平滑版本,与经典版本 相比更稳定,避免了除零问题。
第二个直觉:这个词在某篇文章里出现了多少次?
光有专属性还不够。提到了"拙政园"的文章里,都是真的与"拙政园"紧密相关吗?拙政园官方的景区介绍,可能一千字里会反复提及"拙政园"好多次;而它旁边的苏州博物馆的介绍里可能只是顺带说一句"与拙政园相邻"。很显然拙政园官方的景区介绍才是更符合我们预期的——它在某篇文章中出现得越多,说明这篇文章越专注于这个词。
而这就是"词频"(TF,Term Frequency)的直觉:
专门介绍拙政园的文章,"拙政园"可能出现 20 次——TF 很高;苏州博物馆的文章可能只出现 1 次——TF 很低。
补充说明:实际应用中,TF 还有归一化版本(词数 / 文档总词数),可以避免长文档天然占优势。但为了简化理解,本文使用基础版本。
TF-IDF = TF × IDF
当我们把两个值相乘,就得到了 TF-IDF 的结果:
通过这个值很好地表达出了这种数学关系:一个词在某篇文章中出现得越多(TF 高),且在整个语料中出现的地方越少(IDF 高),那它和这篇文章的"相关性"就越强。
这就是为什么,搜索引擎天然偏爱那些"只此一家"的名字。
有了 TF-IDF 就一定能在所有场景下,帮我们找到最相关的文档吗?让我们来看一个反直觉的例子。
假设有一篇 5000 字的苏州旅游攻略,介绍了苏州各种好玩的地方,里面可能提到了"拙政园"10 次;而另一篇 50 字的拙政园简介,只提到"拙政园"3 次。根据我们的直觉认知,后者应该与拙政园更相关,但如果按照 TF-IDF 的逻辑,前者的 TF 更高,反而应该排在前面。
问题出在哪?
其实这就是 TF-IDF 的问题:因为它只看"出现次数",不看"浓度"。而这个问题,自有更完善的算法会解决。
BM25
1994 年,Stephen Robertson 等人提出了 BM25(Best Matching 25),针对 TF-IDF 的弱点做出了改进。
改进一:TF 饱和
TF-IDF 让 TF 线性增长,按照算法,文档中出现 10 次的得分将是 1 次的 10 倍。但出现 10 次真的比 1 次要更加"相关 10 倍"吗?也许文章只是在堆砌关键词罢了。
BM25 用一个带饱和效应的函数替代了原始 TF(这里展示的是简化形式,假设文档长度等于平均长度):
其中 tf 是词在这篇景点介绍中的出现次数, 是控制饱和速度的参数(通常取 1.2 ~ 2.0)。
相比原始的 tf 值可能无限增长不同,TF 的值将会随着 tf 的增长逐渐收敛,通过计算不难得出:
也就是说,当 时,TF 饱和项的最大值约为 2.2。
让我们来简单计算一下:当 tf 从 1 涨到 5 时,分数从 1.00 涨到 1.77,涨了将近一倍;但从 10 涨到 100 时,分数只从 1.96 涨到 2.17 —— 几乎到顶了。
这就是"饱和":词频越高,额外增加一次出现带来的收益越小。 一篇景点介绍提到"拙政园" 3 次确实比 1 次更相关,但提到 100 次并不会比 10 次多出多少。
词频的收益会饱和,但区分度永远不会 —— 这是 BM25 对 TF-IDF 的核心修正。
参数如何选择?
控制 TF 饱和的速度。让我们看看不同 值下的曲线差异:

-
(蓝色):饱和最快, 时就接近上限,适合短文本场景
-
(红色):工业界默认值,平衡了区分度和饱和速度
-
(绿色):饱和最慢, 时还在快速增长,适合长文档场景
实际经验:如果你的语料以短文本为主(如商品标题、POI 名称), 可以设小一点(0.5~1.0);如果以长文本为主(如文章、攻略), 可以设大一点(1.5~2.0)。
改进二:描述长度归一化
想象两篇景点介绍:一篇 50 字,提到"拙政园" 3 次;另一篇 500 字,也提到"拙政园" 3 次。你直觉上会觉得哪篇更相关?
显然是那篇短的——50 字里 3 次提到,浓度极高,整篇都在讲拙政园;500 字里 3 次提到,可能只是一笔带过。
BM25 的长度归一化就是来做这件事的:
其中 dl 是当前文章的字数,avgdl 是所有文章的平均篇幅,b 是控制惩罚力度的参数(通常取 0.75)。
-
篇幅等于平均长度时:不增不减
-
篇幅是平均长度的 2 倍时:TF 项被除以 1.75,分数被压低
-
篇幅是平均长度的一半时:TF 项被除以 0.875,分数被放大
篇幅长的文章里词频高,可能是"水"出来的,要打折;篇幅短的文章里词频高,说明浓度更高,要加分。
想象一个极端案例:一篇 5000 字的攻略提到"拙政园"5 次,一篇 50 字的介绍提到 3 次——BM25 会告诉你,50 字那篇更相关。为什么?因为 5000 字里 5 次提到,浓度只有 0.1%;50 字里 3 次提到,浓度高达 6%。
浓度才是真相,总量会骗人。
参数如何选择?
控制文档长度对分数的影响程度。让我们看看不同 b 值下的曲线差异:

-
(蓝色):完全忽略文档长度,所有文档一视同仁
-
(橙色):适度惩罚长文档
-
(红色):工业界默认值,平衡了长短文档的差异
-
(紫色):完全按长度比例惩罚,长文档被大幅压分
实际经验:如果你的语料长度比较均匀(如都是商品标题), 可以设小一点(0~0.3);如果长度差异很大(如混合了标题、简介、长文), 可以设大一点(0.75~1.0)。
BM25 完整公式
把两个改进合在一起:
看着复杂,但和 TF-IDF 的 TF × IDF 对比,其实也就只是把 TF 换成了 TF 饱和项 / 长度归一化项。
用具体例子算一下
假设文章的平均篇幅 字,参数 。用户搜索"拙政园",有 3 篇景点介绍命中:
| 文章 | 篇幅 (dl) | "拙政园"出现次数 (tf) |
|---|---|---|
| A(苏州拙政园景区介绍) | 80 字 | 4 次 |
| B(拙政园苏博站介绍) | 150 字 | 2 次 |
| C(如家酒店拙政园店介绍) | 200 字 | 1 次 |
假设语料有 100 篇文章,"拙政园"只出现在其中 2 篇中:
以文章 A 为例:篇幅 80 字,"拙政园"出现 4 次。
用同样的方法计算 B 和 C,结果分别是 4.46 和 2.63。
文章越短、词频越集中,BM25 给分越高——浓度胜过总量。
注意看趋势:文章越短、词频越高,分数越高。长度归一化在背后默默调节——短的加分,长的打折。
苏州拙政园景区的介绍虽然只有 80 字,但"拙政园"出现了 4 次,而且因为篇幅短、浓度高,长度归一化反而给了加分。如家酒店的介绍虽然也提到了"拙政园",但篇幅长(200 字),浓度低,被大幅压分了。
BM25 没有改变区分度的计算方式(IDF 保持不变),但它修复了区分度的两个干扰因素——不再被词频堆砌和文章长度误导。
BM25 的局限性:虽然 BM25 解决了 TF-IDF 的核心问题,但它仍有不足——比如不考虑关键词的位置(标题中的关键词和正文中的关键词权重相同),也不考虑语义关联("人工智能"和"AI"被视为两个不同的词)。这些是后续算法(如 BM25F、向量检索)要解决的问题。
两个算法的对比
TF-IDF 和 BM25 的核心差异在于 TF 的处理方式:TF-IDF 让 TF 线性增长,BM25 用饱和函数限制了 TF 的上限,同时引入了长度归一化。
用一张图来理解 TF 处理的差异:

TF-IDF 是一条直线,无限增长。BM25 是一条渐近线,趋近于某个上限。
写在最后
从 TF-IDF 到 BM25,我们看到的不是两个算法的简单替换,而是搜索引擎对"区分度"理解的不断深化:
-
TF-IDF 发现了区分度,用 IDF 量化了它
-
BM25 修复了区分度,让 IDF 不再被 TF 堆砌和文档长度干扰
这两个算法不是"新的替代旧的",而是"新的在特定场景下更好"。BM25 至今仍是工业界的主流选择,TF-IDF 作为最简单的基线仍有教学价值。
理解了这一点,你就掌握了搜索引擎评分逻辑的本质。