Skip to content

Commit

Permalink
feat: ✨ BM25详解
Browse files Browse the repository at this point in the history
  • Loading branch information
vimpas committed Oct 21, 2024
1 parent 0ea0c23 commit 9f7235f
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 1 deletion.
2 changes: 1 addition & 1 deletion app/tag-data.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"celery":1,"signal":1,"异步任务":1,"事件驱动":1,"next-js":1,"react":1,"javascript":1,"web开发":1,"ssh":1,"vim":1,"剪切板同步":1,"远程服务器":1,"neovim":1,"dp":1,"python":2,"rag":3}
{"rag":4,"信息检索":1,"bm25":1,"python":2,"dp":1,"celery":1,"signal":1,"异步任务":1,"事件驱动":1,"ssh":1,"vim":1,"剪切板同步":1,"远程服务器":1,"neovim":1,"next-js":1,"react":1,"javascript":1,"web开发":1}
106 changes: 106 additions & 0 deletions data/blog/rag/BM25关键字召回详解.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
title: 'BM25关键字召回详解, 及纯python实现'
date: '2024-10-21'
tags: [RAG, 信息检索, BM25]
draft: false
summary: '深入解析BM25算法的原理、公式及其在信息检索中的应用,探讨其优势及与其他召回方法的比较。'
---

# 前言

最近RAG项目中BM25用的地方很多, 所以就想着把BM25的原理和公式好好研究一下, 加深理解.

# BM25算法的原理与公式

BM25(Best Matching 25)是一种基于概率的排名函数,广泛应用于信息检索领域,用于评估文档与用户查询之间的相关性。它是Okapi BM25算法的一部分,最早由Robertson和Jones在1980年代提出。

## 基本原理

BM25的核心思想是:某个查询项在相关文档中出现的频率高于在非相关文档中的频率。该算法通过结合以下两个重要因素来计算文档得分:

- **词项频率(TF)**:指一个词项在某个具体文档中出现的次数。BM25对传统TF进行了调整,引入了饱和度和长度归一化,以防止长文档因包含更多词项而获得不公平的高评分。

- **逆文档频率(IDF)**:衡量词项稀有程度的指标,计算方式基于整个文档集合,旨在降低常见词项的权重,提高稀有词项的权重。

## 计算公式

BM25的基本函数如下:

$$
\text{Score}(D,Q) = \sum_{q \in Q} \left( IDF(q) \cdot \frac{TF(q,D) \cdot (k1 + 1)}{TF(q,D) + k1 \cdot (1 - b + b \cdot \frac{|D|}{avgdl})} \right)
$$

### 参数解释

全局的范围:

- $$ IDF(q) $$ 是词项q的逆文档频率, 衡量词项q的稀有程度, 当 $$ IDF(q) $$ 越大, 说明q这个词越稀有, 越重要, 是一个全局的概念, 是计算所有文档计算出这个词的稀有程度
- $$ avgdl $$ 是文档集合的平均长度

文档的范围:

- $$ TF(q,D) $$ 是词项q在具体文档D中的词频, 也就是q这个词在D文档中出现的次数, 当 $$ TF(q,D) $$ 越大, 说明q这个词在D文档中越重要, 针对当前文档是一个局部的概念
- $$ D $$ 是具体文档
- $$ Q $$ 是查询
- $$ q $$ 是查询中的词项
- $$ |D| $$ 是文档长度
- $$ k1 $$$$ b $$ 是可调节参数,通常设置为 $$ k1 = 1.2 $$$$ 2.0 $$$$ b = 0.75 $$

### 公式分析

#### $$ TF(q,D) $$ 详细分析

1. 当TF(q,D)增大时,分子 TF(q,D) · (k1 + 1) 会线性增加。
2. 当TF(q,D)增大时,分母 TF(q,D) + k1 · (1 - b + b · |D|/avgdl) 也会增加,但增加的速度相对较慢,因为k1是一个大于1的常数。
3. 因此,当TF(q,D)增大时,分数的值会增大,但增加的速度会逐渐减缓。

#### $$ IDF(q) $$ 详细分析

1. 当IDF(q)增大时,分子 IDF(q) 会线性增加。
2. 当IDF(q)增大时,分母 TF(q,D) + k1 · (1 - b + b · |D|/avgdl) 也会增加,但增加的速度相对较慢,因为k1是一个大于1的常数。
3. 因此,当IDF(q)增大时,分数的值会增大,但增加的速度会逐渐减缓。

### BM25扩展版本

BM25的一个扩展版本,通常称为BM25F或BM25+,引入了额外的参数k2来处理查询词频率。这个扩展版本的公式如下:

$$
\text{Score}(D,Q) = \sum_{q \in Q} \left( IDF(q) \cdot \frac{TF(q,D) \cdot (k1 + 1)}{TF(q,D) + k1 \cdot (1 - b + b \cdot \frac{|D|}{avgdl})} \cdot \frac{(k2 + 1) \cdot QTF(q)}{k2 + QTF(q)} \right)
$$

其中:

- $$ QTF(q) $$ 是查询词q在查询Q中的频率
- $$ k2 $$ 是一个新的可调参数,通常设置在0到1000之间

这个扩展版本通过考虑查询词在查询中的频率,进一步优化了相关性评分。参数k2允许调整查询词频率对最终得分的影响程度。



# BM25的优势与比较

## 优势

- **准确性**:BM25通过考虑词频饱和度和文档长度归一化,能够提供更精准的相关性评分。

- **灵活性**:可调节参数使得BM25能够适应不同类型的数据和查询需求。

## 与其他召回方法比较

| 特点 | BM25 | TF-IDF |
|---------------|---------------------------|---------------------------|
| 复杂性 | 较高 | 较低 |
| 参数调节 | 需要调节参数 | 无需调节 |
| 文档长度影响 | 考虑文档长度 | 不考虑 |
| 性能 | 在长文档中表现更佳 | 对短文档效果较好 |
| 语义理解能力 | 较弱 | 较弱 |

BM25相较于TF-IDF在处理复杂场景时表现更佳,尤其是在长文档中提供更准确的排名和相关性评分。然而,它在语义理解方面仍然存在局限性,因此在某些情况下可能无法捕捉到文档之间的深层次语义关系。

# 代码:

https://github.com/moyueheng/BM25

# 参考
https://www.cnblogs.com/novwind/p/15177871.html

0 comments on commit 9f7235f

Please sign in to comment.