ysf
ysf
Published on 2025-12-07 / 15 Visits
0

RAG中的精确检索算法:从TF-IDF到BM25

检索质量决定生成质量

检索模块负责“找对信息”,生成模块负责“组织表达”

在RAG系统中,生成模块并不会凭空创造知识,而是依赖检索模块提供的上下文信息,检索质量直接决定生成结果的准确性与可靠性。

想象这样一个场景:用户在企业内部知识库中提问:“如何在 Elasticsearch 中调整 BM25 的 k1b 参数?” 系统需要从大量技术文档、配置说明和实践笔记中快速定位最相关的内容,再将其组织成可读答案。如果检索模块没有准确命中包含 “BM25” “k1” “b” “Elasticsearch” 等关键术语的文档,而是返回一些泛泛讨论搜索引擎原理的材料,那么即使后续生成模型表达能力再强,也难以给出真正可用的回答。

从系统视角来看,RAG可以抽象为:

因此,检索算法本质上是整个系统的信息过滤机制,其设计质量直接影响系统整体性能。

TF-IDF算法

TF-IDF(Term Frequency-Inverse Document Frequency) 是信息检索领域最早且最广泛应用的算法之一,诞生于20世纪70年代,用于评估一个词语对于一个文档集或语料库中的某一份文档的重要程度。核心思想可以概括为:

一个词在单篇文档中出现的频率越高(TF),同时在所有文档中出现的频率越低(IDF),那么这个词就越能代表这篇文档的核心内容,越重要。

  1. 词频(TF):一个词项在文档中出现的次数越多,该文档与这个词项的相关性越高

  1. 逆文档频率(IDF):一个词项在整个语料库中出现的文档越少,这个词项的区分度越高

TF-IDF的计算公式

在 TF-IDF 中,相关性评分由两个核心部分构成:词频(TF)与逆文档频率(IDF)。二者分别刻画了词项在局部文档中的重要性在全局语料中的区分能力

TF-IDF的核心计算公式为:

TFIDF(t,d)=TF(t,d)×IDF(t)TF-IDF(t,d)=TF(t,d)\times IDF(t)

其中,tt 表示某个词项,dd 表示文档库

其核心逻辑是:

  • TF:这个词在当前文档中重要吗?

  • IDF:这个词在所有文档中稀有吗?

只有同时满足这两点,词项才具有高权重

从信息论角度来看:

  • TF 反映的是局部信息量

  • IDF 近似刻画全局信息增益

因此,TF-IDF 实际上是在估计:一个词在当前文档中,能够为区分该文档提供多少“有效信息”

(1)TF(Term Frequency):词项的局部重要性

最基础的词频定义为:

TF(t,d)=f(t,d)TF(t,d)=f(t,d)

其中,f(t,d)f(t,d)表示词项 tt在文档 dd中的出现次数。

在实际应用中,通常会对 TF 进行一些改进,常见的 TF 变体有:

  1. 相对词频:缓解长文档偏置

TF(t,d)=f(t,d)dTF(t,d) = \frac{f(t,d)}{|d|}

将词频除以文档总数,缓解长文档偏置问题。

  1. 对数缩放

TF(t,d)={1+logf(t,d),f(t,d)>00,f(t,d)=0TF(t,d)= \begin{cases} 1 +\mathrm{log} f(t,d), & f(t,d)>0 \\ 0, & f(t,d)=0 \end{cases}

核心思想:词频的贡献应当递减,而非线性增长
例如:

  • 出现1次 → 权重1

  • 出现10次 → 权重约3

  • 出现100次 → 权重约5

  1. 双归一化:抑制极端高频词

TF(t,d)=0.5+0.5f(t,d)maxtdf(t,d)TF(t,d) = 0.5 + 0.5 \cdot \frac{f(t,d)}{\mathrm{max}_{t\prime \in d}f(t\prime, d)}

将词频映射到 [0.5,1][0.5, 1] 区间,减少极端高频词的影响。

(2)IDF(Inverse Document Frequency):词项的全局区分能力

IDF衡量的是一个词在整个语料库中的稀有程度,其基本形式为:

IDF(t)=logNdf(t)IDF(t)=\mathrm{log}\frac{N}{df(t)}

其中:

  • NN:语料库中总文档数

  • df(t)df(t):包含词项 tt 的文档数量

引入 IDF 的核心目的,是为了解决单纯依靠 TF 所带来的“词频陷阱”,主要作用就是抑制“高频但无信息量”的词(如停用词)

TF 只能告诉你一个词在文章里出现的频率有多高,但无法告诉你这个词有多重要。 如果没有 IDF,像“的”、“是”、“系统”、“方法”这类随处可见的词,往往会因为出现次数多而被误判为关键词。

常见的IDF变体有:

  1. 平滑IDF(避免除零问题)

IDF(t)=logN+1df(t)+1+1IDF(t) = \mathrm{log}\frac{N+1}{\mathrm{d}f(t)+1}+1

  • 避免分母为零

  • 防止IDF为负值

  1. BM25风格IDF(更具有鲁棒性)

IDF(t)=log(Ndf(t)+0.5df(t)+0.5)+1IDF(t) = \mathrm{log}\left(\frac{N-\mathrm{d}f(t)+0.5}{\mathrm{d}f(t)+0.5} \right)+1

  • 引入 0.5 平滑项

  • 对高频词抑制更稳定

  • 实际工程中更常用

TF-IDF算法的局限性

随着数据规模的增长和检索任务复杂度的提升,TF-IDF的局限性逐渐显现:

(1)词频线性增长问题

TF-IDF中,词频(TF)与相关性呈线性关系。即某个词在文档中出现次数越多,其贡献就按比例增加(如果一个词在文档中出现100次,其贡献是出现10次的10倍)。然而,在真实语义场景中,词频的贡献通常具有明显的边际递减特性:一个关键词从出现1次增加到3次,可能显著提升相关性;但从10次增加到20次,信息增量却十分有限。这种线性建模方式会导致一个问题:高频重复词被过度放大。例如,一个文档中反复出现“RAG”但缺乏实质性内容,可能会被错误地认为高度相关,而真正提供详细解释的文档反而被低估。

(2)长文档偏向问题:对信息密度缺乏约束

TF-IDF 没有考虑到文档长度的影响。在实际计算中,文档中每个查询词的词频都会对最终得分产生贡献,因此相较于短文档,长文档更有可能包含更多查询词或更高的词频,从而在统计上更容易获得较高的相关性得分。然而,这种优势并不一定反映真实的语义相关性,因为长文档往往同时包含更多无关信息,其信息密度可能较低。

(3)缺乏文档长度归一化机制:跨文档比较不公平

进一步来看,TF-IDF 并未对文档长度进行归一化处理,使得不同长度文档之间的相关性评分缺乏可比性。换言之,TF-IDF 隐含假设“词频越高越重要”,但没有考虑:

同样出现 3 次关键词,在 50 词文档中与在 500 词文档中的意义是完全不同的。

缺乏这一归一化机制,使得模型难以区分“高密度匹配”和“低密度匹配”,从而影响排序的精确性。

(4)对语义结构与词序缺乏建模能力

TF-IDF 基于词袋模型(Bag-of-Words),将文本表示为无序的词项集合,忽略词序信息及上下文依赖关系。因此,对于包含相同词项但排列方式不同的文本,其表示结果高度相似。例如:

  • “machine learning for healthcare”

  • “healthcare machine learning challenges”

在 TF-IDF 表示下,这两类文本由于共享大量相同词项,通常会获得相近的表示与相似度评分。然而,它们在语义重点上存在显著差异:前者强调“机器学习在医疗领域的应用”,而后者更侧重“医疗场景中的机器学习挑战”。

这一点,BM25也没完全解决

BM25算法

为了解决这些问题,BM25(Best Matching 25) 算法在1990年代被提出。它是"最佳匹配"系列算法的第25个版本,由英国计算机科学家Stephen Robertson和Karen Spärck Jones等人开发。

为什么叫BM25? 这其实是开发过程中的第25个实验版本,没想到这个版本效果最好,就沿用至今。