BM25(Best Matching 25)是一种广泛使用的信息检索排序算法,用于计算查询(query)与文档(document)的相关性得分。它是 TF-IDF 的改进版本,通过引入更科学的归一化和参数调节,显著提升了搜索质量。
- 应用场景:搜索引擎、文档检索、问答系统等。
- 特点:
- 考虑词频(TF)和逆文档频率(IDF)的平衡。
- 对文档长度进行归一化,避免长文档占据不公平优势。
2. BM25 的核心公式 #
BM25 的得分公式如下:
$$ \text{score}(D, Q) = \sum_{i=1}^{n} \text{IDF}(q_i) \cdot \frac{f(q_i, D) \cdot (k_1 + 1)}{f(q_i, D) + k_1 \cdot (1 - b + b \cdot \frac{|D|}{\text{avgdl}})} $$
变量说明:
- $ Q $:查询(由词项 $ q_1, q_2, ..., q_n $ 组成)。
- $ D $:待评分的文档。
- $ f(q_i, D) $:词项 $ q_i $ 在文档 $ D $ 中的词频(TF)。
- $ |D| $:文档 $ D $ 的长度(总词数)。
- $ \text{avgdl} $:所有文档的平均长度。
- $ \text{IDF}(q_i) $:词项 $ q_i $ 的逆文档频率。
- $ k_1 $ 和 $ b $:可调参数(通常 $ k_1 \in [1.2, 2.0] $, $ b \in [0.5, 0.8] $)。
3. 公式拆解 #
(1)逆文档频率(IDF) #
衡量词项的全局重要性,罕见词得分更高:
$$ \text{IDF}(q_i) = \log \left( \frac{N - n(q_i) + 0.5}{n(q_i) + 0.5} + 1 \right) $$
- $ N $:文档集合中的总文档数。
- $ n(q_i) $:包含词项 $ q_i $ 的文档数。
(2)词频(TF)与文档长度归一化 #
BM25 通过以下部分调节词频的影响:
$$ \frac{f(q_i, D) \cdot (k_1 + 1)}{f(q_i, D) + k_1 \cdot (1 - b + b \cdot \frac{|D|}{\text{avgdl}})} $$
- $ k_1 $:控制词频饱和度的参数。
- 当 $ k_1 = 0 $,忽略词频;值越大,词频影响越强。
- $ b $:控制文档长度归一化的强度。
- $ b = 0 $:完全忽略文档长度。
- $ b = 1 $:强力惩罚长文档。
4. BM25 的排序逻辑(Rank_BM25) #
- 对每个文档计算 BM25 得分:根据上述公式,得到查询 $ Q $ 与每个文档 $ D $ 的相关性得分。
- 按得分降序排序:得分越高,文档与查询的相关性越强,排名越靠前。
5. 参数调优建议 #
- $ k_1 $(默认 1.5):
- 增大 $ k_1 $:词频高的词项贡献更大(适合长文档或重复词重要的场景)。
- 减小 $ k_1 $:降低词频影响(适合短查询或去重需求)。
- $ b $(默认 0.75):
- 增大 $ b $:更严厉惩罚长文档(避免长文档仅因长度占据高分)。
- 减小 $ b $:弱化长度影响(适合标题类短文本检索)。
6. BM25 与 TF-IDF 的对比 #
| 特性 | BM25 | TF-IDF |
|---|---|---|
| 词频处理 | 非线性饱和(避免高频词主导) | 线性增长(可能被高频词主导) |
| 文档长度归一化 | 动态调节(参数 $ b $ 控制) | 无直接归一化 |
| 参数灵活性 | 可调 $ k_1 $ 和 $ b $ | 无参数 |
7. 实际应用示例 #
假设有以下文档集和查询:
- 文档1:
"apple banana apple"(长度=3) - 文档2:
"apple fruit"(长度=2) - 查询:
"apple" - 平均文档长度 $ \text{avgdl} = 2.5 $,设 $ k_1 = 1.5 $, $ b = 0.75 $。
计算步骤:
- 计算 IDF:$ \text{IDF}("apple") = \log \frac{2 - 2 + 0.5}{2 + 0.5} + 1 \approx 0 $(因为“apple”出现在所有文档中,IDF 较低)。
- 文档1得分:
- 词频 $ f("apple", D1) = 2 $
- 长度归一化部分:$ 1 - b + b \cdot \frac{3}{2.5} = 1.15 $
- TF 部分:$ \frac{2 \cdot 2.5}{2 + 1.5 \cdot 1.15} \approx 1.32 $
- 总分:$ 0 \times 1.32 = 0 $(因 IDF=0)。
- 文档2得分类似(实际应用中需调整参数或处理 IDF 为零的情况)。
8. Rank_BM25 的优缺点 #
- 优点:
- 比 TF-IDF 更适应多样化文本长度。
- 参数可调,适合不同场景。
- 缺点:
- 需要预计算文档长度和 IDF。
- 对超短查询(如单字)可能效果不佳。
9. 工具实现 #
- Elasticsearch:默认使用 BM25 作为排序算法。
- Python 库:
rank_bm25(可直接计算文档排名):
# 导入BM25Okapi类,用于构建BM25检索模型
from rank_bm25 import BM25Okapi
# 定义语料库,每个元素为一个文档字符串
corpus = ["apple banana apple", "apple fruit"]
# 对每个文档进行分词,得到分词后的语料库
tokenized_corpus = [doc.split() for doc in corpus]
# 基于分词后的语料库构建BM25模型
bm25 = BM25Okapi(tokenized_corpus)
# 定义查询,并进行分词
query = "apple".split()
# 计算查询与每个文档的BM25得分
scores = bm25.get_scores(query) # 得到文档得分
# 输出每个文档的得分
print(scores)