最近我读了十几种关于BM25的解释——从学术论文到“像给10岁小孩解释”的博客文章。每一种解释都集中在同一个三点上。这是因为BM25真的就是这么简单。

BM25是一种排名算法。你输入一个查询,它会为语料库中的每份文档打分,最高分获胜。自1994年以来,它一直在这样做。Google、Elasticsearch、Lucene、OpenSearch等系统都使用它或其变体作为默认评分器。即使依赖密集向量检索的RAG系统也几乎总是将BM25作为混合管道的一部分。

“25”只是一个版本号。就像iPhone 25一样。Stephen Robertson和Karen Spärck Jones尝试了24个版本才最终确定了这个版本。

三个规则

BM25会针对每份文档提出三个问题:

1. 它包含你搜索的词语吗?

如果一份文档提到了“恐龙”10次,它很可能比只提到一次的文档更关于恐龙。这就是词频——搜索中最基本的信号。

但BM25对此很聪明。从0次提到1次是一个巨大的变化。从1次提到2次仍然有显著意义。从50次提到51次几乎没有什么变化。收益会逐渐饱和。

这被称为TF饱和,它阻止了垃圾邮件发送者通过重复一个关键词500次获胜。BM25会限制这种奖励。就像老师给你一个好答案一个金星——而不是通过一遍遍喊出来获得100个金星。

2. 匹配的词语是否罕见?

有些词语几乎出现在每份文档中:“the”、“and”、“is”。找到这些词语告诉不了你什么。但如果一份文档包含“三角龙”、“代谢组学”或“Part 11”——这些词语是罕见的。在罕见词语上的匹配比在常见词语上的匹配要重要得多。

这就是逆文档频率(IDF)。大家常用的类比是:如果一栋楼里每个人都穿着蓝色衬衫,那不会帮助你找到任何人。但如果一个人戴着紫色帽子,这就是你的线索。罕见词语就是紫色帽子。

3. 文档的长度是否合适?

一份提到“树蛙”三次的10页传单显然关于树蛙。一份1000页的百科全书提到“树蛙”三次?可能不是。

BM25会给较短的文档提供公平性加分。较长的文档自然包含更多的词语,因此仅因为篇幅大就会匹配更多的词语——这不是相关性的信号。文档长度规范化会调整这一点。

公式(用中文解释)

分数 = 词的稀有性 × (计数上限) / (词计数 + 页面长度惩罚)

对于查询中的每个词语,BM25都会为每份文档计算这个分数。将所有查询词的分数相加。分数最高的获胜。

实际的公式:

Score(D, Q) = Σ IDF(qi) × [f(qi, D) × (k1 + 1)] / [f(qi, D) + k1 × (1 - b + b × |D|/avgdl)]

两个调节旋钮:

  • k1(通常为1.2–2.0):重复的词语停止提供帮助的速度。数值越高,重复的词语获得的信用越多。
  • b(通常为0.75):惩罚长文档的程度。0 = 完全忽略长度。1 = 完全惩罚。

为什么它没有过时

每隔几年,就会有人宣布BM25过时了。Word2vec、BERT嵌入、密集检索、基于LLM的搜索——每个都被认为会取代它。但没有一个做到了。

原因很简单:BM25速度快、可解释性强,非常擅长精确词匹配。它不需要GPU推理。它不会产生幻觉。它不需要微调。它只是智能地计数词语。

向量搜索在找到语义相似的内容方面非常出色——“电子记录应保持安全的连续历史”与“审计追踪要求”匹配,因为它们的意义重叠。但向量搜索在精确词匹配方面却很挣扎:系统名称、文档ID、缩写、监管章节号。BM25对这些内容应对自如。

这就是为什么最有效的RAG检索架构是混合的:

查询 → BM25(精确词语)+ 向量搜索(意义) → 组合 → 重新排序 → LLM

BM25捕捉精确的术语。向量搜索捕捉同义词。重新排序将它们合并。LLM则兼得两者之长。

最后总结

BM25就是三个计数规则和两个旋钮。罕见词语更重要。重复的提及有帮助但会饱和。较短的文档获得公平性加分。就是这样。

它已经作为信息检索的支柱超过30年了。如果你正在构建搜索、RAG或任何需要找到相关文档的系统——你需要理解BM25。不是因为它复杂,而是因为它有效。