BM25:现代搜索引擎相关性算法的核心
你是否想过,当你在搜索引擎中输入关键词时,它是如何决定把哪些结果排在最前面的?这背后,一个名为 BM25(Best Matching 25) 的算法发挥着关键作用。作为现代信息检索领域的基石,BM25被广泛应用于Elasticsearch、Azure AI搜索等主流搜索引擎中,用于评估文档与用户查询的相关性。本文将带你深入浅出地了解BM25算法的核心思想、工作原理及其优势。
从TF-IDF到BM25:一次必要的进化
在BM25之前,TF-IDF(词频-逆文档频率) 是信息检索中最经典的算法。它通过两个关键指标来评估相关性:
- 词频(TF):一个词在文档中出现的次数越多,文档越相关。
- 逆文档频率(IDF):一个词在所有文档中越罕见,它的区分度越高,权重越大。
然而,TF-IDF存在一个明显的缺陷:它假设词频与相关性是线性关系。这意味着,一个词在文档中出现10次,其重要性就是出现1次的10倍。这在现实中并不成立——当某个词出现的次数足够多后,其边际贡献会迅速递减。例如,一篇提到“苹果”100次的长文,并不一定比提到“苹果”20次的短文更相关。
BM25正是为解决这一问题而诞生的。它基于概率检索模型,可以看作TF-IDF的“智能升级版”,通过引入更科学的权重计算方式,让相关性评分更加精准和符合直觉。
理解BM25的三大核心机制
BM25通过一个公式来综合计算文档的得分,其精妙之处在于引入了几个关键参数:
1. 对词频的“饱和”处理 (k1参数)
BM25认为词频对相关性的贡献不是无限的,而会趋于一个饱和值。其公式中通过参数k1来控制词频影响力的增长速度。k1的默认值通常设为1.2。
当k1=0时,词频完全不影响得分,变成只关心词是否存在的“二元模型”;k1值越大,词频的权重上限越高,收敛速度越慢。
2. 对文档长度的“归一化” (b参数)
这是一个极其符合直觉的设计:在较短的文档中匹配到关键词,比在长文档中匹配到,更能说明该文档主题的集中性。例如,在一篇短小的产品标题里出现“无线耳机”,比在一本500页的技术大全里出现同样词汇,更能说明该文档就是关于“无线耳机”的。
BM25通过参数b来控制文档长度对得分的影响,其默认值通常设为0.75。
- 当
b=0时,完全忽略文档长度的影响。 - 当
b=1时,则进行完全的长度归一化惩罚。
3. 逆文档频率 (IDF)
与TF-IDF类似,BM25也使用IDF来衡量一个词的重要性。其计算方式为:IDF = log( (N - n(qi) + 0.5) / (n(qi) + 0.5) ),其中N代表文档总数,n(qi)代表包含该词的文档数。一个词如果在越多的文档中出现,其IDF值就越低,重要性也越低。
BM25的算法公式一览
整合上述思想,BM25对一个查询Q(包含词qi)与文档D的相关性得分公式如下:
Score(Q, D) = Σ IDF(qi) * [ (fi * (k1 + 1)) / (fi + k1 * (1 - b + b * (|D|/avgdl)) ) ]
其中:
fi:词qi在文档D中的词频。|D|:文档D的长度。avgdl:文档集合的平均长度。k1和b:作为调节参数,默认值分别为1.2和0.75。
BM25在PostgreSQL中的实践应用
传统上,PostgreSQL内置的全文搜索使用tsvector和GIN索引,但缺乏类似BM25的现代相关性排序方法。如今,通过扩展如pg_bm25或VectorChord-BM25,PostgreSQL也具备了原生BM25排序能力。
在VectorChord-BM25中,一个典型的应用流程如下:
- 创建表:为文档创建一个包含
bm25vector类型列的表,该列用于存储文本分词后的稀疏向量。 - 分词与索引:使用
tokenize函数对文本进行分词,并创建BM25索引以加速搜索。 - 执行查询:使用
to_bm25query函数处理查询词,并通过<&>操作符计算BM25分数,最终按分数排序返回最相关的结果。
这种方式将现代搜索引擎的核心能力带入了传统的数据库,使得开发者可以更简单地构建高质量搜索应用。
结语
BM25通过巧妙的设计,解决了TF-IDF在词频饱和度和文档长度归一化方面的不足,提供了一种更精准、更符合人类直觉的搜索结果排序方案。它也因此成为了现代搜索引擎和信息检索系统中不可或缺的算法。无论是使用Elasticsearch这样的专业搜索工具,还是在PostgreSQL中通过扩展来利用其能力,理解BM25的原理都能帮助你更好地构建和优化搜索体验。