TF-IDF vs BM25:搜索算法终极对比
本文对比了文本检索中的TF-IDF和BM25算法。TF-IDF通过词频和逆文档频率计算相关性,但存在词频无限增长和长文档偏见问题。BM25作为改进版,引入k1(控制词频饱和度)和b(文档长度归一化)参数,使评分更合理。核心差异体现在:BM25对高频词进行渐进式惩罚,动态调整文档长度影响,且参数可调性更强。实际应用中,BM25已成为工业标准(如Elasticsearch),特别适合搜索引擎和RAG系
前言
在 NLP 和搜索领域,文本相似度计算和文档排序是两大基石。
尽管现在基于 Transformer 的 Embedding(向量检索)非常火热,但在很多场景下(如精确匹配专有名词、低频词检索),传统的统计模型依然占据统治地位。甚至在目前最先进的 RAG(检索增强生成) 架构中,“混合检索”(Hybrid Search = Vector + BM25) 也是提升召回率的标准做法。
很多同学了解 TF-IDF,但对 BM25 知之甚少,或者只知道它是“升级版”。本文将从数学原理、评分机制、以及优缺点等多个维度,带你彻底搞懂这两个算法的区别。
一、 TF-IDF:经典的基石
TF-IDF (Term Frequency-Inverse Document Frequency) 是信息检索领域最早期的权重计算方法。它的核心思想非常朴素:如果一个词在当前文档中出现很多次(TF 高),但在所有文档中出现很少次(IDF 高),那么这个词最能代表当前文档。
1. 数学公式
$$Score(q, d) = \sum_{t \in q} TF(t, d) \times IDF(t)$$
-
TF (词频):词 $t$ 在文档 $d$ 中出现的次数(或归一化后的频率)。
-
IDF (逆文档频率):衡量词的稀缺程度。
$$IDF(t) = \log \frac{N}{DF(t)}$$
其中 $N$ 是文档总数,$DF(t)$ 是包含词 $t$ 的文档数。
2. TF-IDF 的局限性(这也是 BM25 诞生的原因)
-
词频无限增长问题:在 TF-IDF 中,TF 值与最终得分是线性关系。如果一个词在文档中出现 10 次,得分是出现 1 次的 10 倍;出现 100 次,得分就是 100 倍。这显然不合理——出现 100 次“苹果”的文档,相关性真的比出现 10 次的高 10 倍吗?
-
长文档偏见:长文档天然包含更多的词,更容易获得高 TF 值,导致 TF-IDF 倾向于推荐长文档,而忽略了文档长度对相关性的稀释作用。
二、 BM25:现代搜索的标准
BM25 (Best Matching 25) 是对 TF-IDF 的一种基于概率模型的改进,也是 Elasticsearch 和 Lucene 默认的评分算法。
它通过引入两个超参数 $k_1$ 和 $b$,巧妙地解决了 TF-IDF 的上述痛点。
1. 数学公式(核心部分)
$$Score(q, d) = \sum_{t \in q} IDF(t) \cdot \frac{TF(t, d) \cdot (k_1 + 1)}{TF(t, d) + k_1 \cdot (1 - b + b \cdot \frac{|d|}{avgdl})}$$
乍一看很复杂,其实核心在于分母的调整:
-
$k_1$ (词频饱和度):通常取值 [1.2, 2.0]。它控制 TF 得分的增长速度。
-
$b$ (长度归一化):通常取值 0.75。它控制文档长度对得分的惩罚力度。
-
$|d|$:当前文档长度。
-
$avgdl$:所有文档的平均长度。
三、 深度对比:TF-IDF vs BM25
这是本文的重点,我们将从以下 4 个维度进行对比:
1. 词频饱和度 (TF Saturation)
这是两者最大的区别。
-
TF-IDF:线性增长。词频越高,得分越高,没有上限。这容易导致某些恶意堆砌关键词的网页获得高分。
-
BM25:渐进饱和。随着词频增加,得分的增长幅度会越来越小,最终趋近于一个由 $k_1$ 决定的上限。
直观理解:在 BM25 中,单词出现 1 次和 0 次区别很大,但出现 100 次和 110 次区别很小。这更符合人类的认知。
2. 文档长度归一化 (Document Length Normalization)
-
TF-IDF:原始版本没有考虑文档长度。虽然后期改进版引入了余弦相似度(Cosine Similarity)来消除长度影响,但不够灵活。
-
BM25:通过参数 $b$ 动态调整。
-
如果文档很长,分母变大,得分降低(惩罚长文档)。
-
$b=1$:完全归一化;$b=0$:不归一化。
-
BM25 认为:如果两个词出现在一篇短文中,比它们出现在一篇长文中更具相关性(因为短文的信息密度更高)。
-
3. 参数可调性
-
TF-IDF:几乎无参数可调,是一个静态的统计公式。
-
BM25:拥有 $k_1$ 和 $b$ 两个超参数,可以根据具体业务场景(如电商搜索 vs 法律文档检索)进行微调,灵活性更强。
4. 实际应用场景
| 维度 | TF-IDF | BM25 |
| 计算复杂度 | 低,适合快速粗排 | 略高,但在现代 CPU 上可忽略不计 |
| 适用场景 | 简单的关键词提取、文本挖掘特征工程 | 搜索引擎、推荐系统、RAG 检索 |
| 抗作弊能力 | 弱(容易被关键词堆砌攻击) | 强(有饱和机制) |
| 工业界地位 | 教学与基准算法 | 工业级默认标准 (ES, Solr) |
四、 代码实战 (Python)
我们可以使用 rank_bm25 库快速体验 BM25 的效果。
Python
# 安装: pip install rank_bm25
from rank_bm25 import BM25Okapi
corpus = [
"Hello there good man",
"It is quite windy in London",
"How is the weather today"
]
tokenized_corpus = [doc.split(" ") for doc in corpus]
# 初始化 BM25
bm25 = BM25Okapi(tokenized_corpus)
# 查询
query = "windy London"
tokenized_query = query.split(" ")
# 获取文档分数
doc_scores = bm25.get_scores(tokenized_query)
print(doc_scores)
# 结果会显示第二个句子的分数最高
五、 总结与建议
在构建 AI 应用或搜索引擎时,不要犹豫,优先选择 BM25。
虽然 TF-IDF 在特征提取(如提取文章关键词标签)时依然有效,但在衡量“查询-文档”相关性的任务上,BM25 是对 TF-IDF 的全面升级。
特别是在 RAG 系统中:
现在的最佳实践是使用 Hybrid Search(混合检索):
-
用 Embeddings (向量) 捕捉语义(解决“苹果”和“iphone”相关的问题)。
-
用 BM25 捕捉精确匹配(解决专有名词、特定型号检索的问题)。
-
通过 Rerank (重排序) 模型合并两者的结果。
理解了 BM25 的 $k_1$ 和 $b$,你就在搜索优化的路上迈出了一大步!
更多推荐
所有评论(0)