BM25全文检索

概述

BM25是一种经典的全文检索排序算法,常用于搜索引擎、RAG和文档检索。它的核心目标是:根据用户查询中的关键词,判断哪些文档最相关,并给这些文档打分排序。

你可以把BM25理解成,比简单关键词匹配更聪明的TF-IDF( Term Frequency-Inverse Document Frequency , 词频-逆文档频率 )。

比如用户搜索:

latex 复制代码
GitNexus MCP Stdio

系统里有3篇文档:

latex 复制代码
文档A:GitNexus MCP Server使用Stdio通信
文档B:MCP支持Stdio和SSE
文档C:GitNexus代码索引架构

BM25会分别计算这3篇文档和查询的相关性分数:

latex 复制代码
文档A:8.7
文档B:6.2
文档C:2.1

然后按分数排序返回:

latex 复制代码
文档A
文档B
文档C

BM25考虑3件事

关键词出现次数

比如搜索:

latex 复制代码
MCP Stdio

如果一篇文章里频繁出现:

latex 复制代码
MCP
Stdio

那么它通常会获得更高分。

但BM25不会认为出现越多越无限重要。

例如:

latex 复制代码
出现1次 → 提升明显
出现3次 → 继续提升
出现20次 → 提升已经很有限

这叫**词频饱和**。因为一个词出现100次,并不意味着相关性就是出现10次的10倍。


关键词的稀有程度

假设整个文档库里:

latex 复制代码
"the"出现100万次
"GitNexus"出现100次

那么搜索:

latex 复制代码
GitNexus

这个词的信息量明显更大。所以BM25会让稀有词获得更高权重。

这部分本质上就是IDF(Inverse Document Frequency, 逆文档频率),也就是说:一个词在整个语料库里越少见,它越有区分度。

比如:

latex 复制代码
"server" → 权重较低
"GitNexus" → 权重较高
"CompatibleStdioServerTransport" → 权重更高

文档长度

假设:

latex 复制代码
文档A:100字,其中MCP出现5次
文档B:10000字,其中MCP出现5次

虽然出现次数一样,但显然文档A更可能专门讨论MCP。所以BM25会做文档长度归一化。也就是说:短文档中关键词密集通常比长文档中偶尔出现关键词得分更高。

BM25公式

给定查询Q和文档D主要,经典形式可以写成:

$ score(D,Q)=\sum_{q_i\in Q}

IDF(q_i)

\cdot

\frac{f(q_i,D)(k_1+1)}

{f(q_i,D)+k_1(1-b+b\frac{|D|}{avgdl})} $

看几个变量:

  • f(q_i,D) 表示某个关键词在文档中出现几次。
  • IDF(q_i) 表示这个词有多稀有
  • \|D\| 表示当前文档长度
  • avgdl 表示所有文档的平均长度。
  • k1控制词频饱和程度, 常见k1 ≈ 1.2~2.0
  • b控制文档长度归一化程度,b ≈ 0.75
相关推荐
SamChan902 小时前
用Python+Requests批量翻译PDF:从脚本到调度
后端·python·microsoft·ai·pdf·机器翻译
草莓熊Lotso2 小时前
【LangChain】核心技术:嵌入模型与向量存储完全指南
服务器·网络·python·langchain
油丶酸萝卜别吃7 小时前
utils.js 说明文档
开发语言·javascript·ecmascript
leisoo80979 小时前
100GBA股股票数据怎么存ClickHouseRedisMySQLJSON完整对比
大数据·linux·服务器·开发语言·python
WangYan202210 小时前
基于XGBoost与AI的生态—地学多源数据建模:植被与土地利用识别、土壤碳氮空间预测、生物多样性驱动机制、土壤微生物功能预测、生态退化与风险识别
python·机器学习·xgboost
不会代码的小猴10 小时前
21. 泛型编程上
开发语言·c++·笔记·算法
一只旭宝11 小时前
细讲C加加【9】C++ std::function与std::bind详解|仿函数、绑定器、类成员绑定、占位符、成员偏移指针
开发语言·c++·算法
金銀銅鐵12 小时前
[Python] 借助 turtle 逐字展示唐诗《金缕衣》
python
coder!mq13 小时前
说几个常见的语法糖?
java·开发语言·算法