# Summary
BM25 (Best Matching 25)
BM25 就像在图书馆找书:
- 你要找关于"养猫"的书
- 书名或简介里多次提到"养猫"的书,比只提了一次的更相关(词频)
- "养猫"这个专业词比"动物"这种宽泛词更能帮你定位(逆文档频率)
- 一本薄薄的《养猫指南》里出现5次"养猫",比一本厚厚的《动物百科全书》里出现5次更说明这本书就是专门讲养猫的(文档长度归一化)
# Cues
# Notes
BM25 是一个用来给搜索结果打分排序的算法,让我用简单的例子来解释:
想象你在搜索引擎里搜索"如何做番茄炒蛋",搜索引擎需要从海量网页中找出最相关的结果。BM25 就是帮助判断哪个网页最相关的"评分员"。
## BM25 的核心思想
BM25 主要考虑三个因素来给文档打分:
**1. 词频(TF)- 关键词出现的次数**
- 如果一篇文章多次提到"番茄炒蛋",说明这篇文章很可能就是在讲这道菜
- 但也不是出现越多越好——如果一篇文章把"番茄炒蛋"重复了100次,可能就是在堆砌关键词,反而不太靠谱
**2. 逆文档频率(IDF)- 关键词的稀有程度**
- "番茄炒蛋"这个词比较特殊,不是每篇文章都会提到,所以包含这个词的文章更有价值
- 而像"的"、"是"这种常见词,几乎每篇文章都有,就没什么区分度
**3. 文档长度**
- 在一篇100字的食谱里出现3次"番茄炒蛋",比在一本10万字的烹饪书里出现3次更能说明相关性
- BM25 会根据文档长度来调整评分,避免长文档占便宜
## BM25 的优势
1. **效果好**:比简单的关键词匹配更智能,搜索结果更准确
2. **速度快**:计算简单,即使处理海量文档也很快
3. **可调节**:有参数可以根据不同场景调整
这就是为什么 BM25 从1994年提出到现在,仍然是很多搜索引擎的核心算法之一。即使在深度学习时代,它依然是一个非常实用的基础算法。
## BM25(Okapi BM25 相关度算法)
| | |
| ---- | -------------------------------------------------------------------------------------------------------- |
| 关键词 | 说明 |
| 作用 | 把一段文本(帖子)与一条“查询”进行打分,衡量它们相关程度;是搜索引擎经典的 基于词频的排序公式 |
| 核心公式 | \(\displaystyle \text{score}(D, Q)=\sum_{t\in Q} \text{IDF}(t), \frac{tf,(k_1+1)}{tf + k_1,(1-b+b,\frac{ |
| 直观理解 | - 词出现得多→分高(但饱和,tf 再增收益递减)<br>- 罕见词→分高(IDF 大)<br>- 文档太长→分被“压一压”(防止长文自然含词多而刷高分)|
| 典型场景 | Elasticsearch / Solr 的默认打分方式;FAQ 智能问答的文本检索 |
| 优点 | - 只用词频统计,计算量小,离线建索快 <br>- 对短查询效果好、业界验证成熟 |
| 缺点 | - 完全基于“词袋模型”,忽略语序与上下文 <br>- 对口语化、拼写错误、同义词敏感度低 <br>- 无法理解语义(“紫禁城”≠“故宫”)|
**在你的项目里** 把每个 POI(故宫、紫禁城…)做成一条“文档”,利用 Elasticsearch/OpenSearch 建立倒排索引。给帖子跑 BM25,与这些文档求分:
- 分数 < 阈值(如 3.0)→ 认为与任何 POI 都**不相关**,直接淘汰;
- 分数 ≥ 阈值 → 进入 LLM 精判。
id source status country province city name summary days labels score popularity sequence_score detail poi_list real_destinations abstract_destinations poi_names create_time update_time
1 xhs 6 中国 上海 上海 上海城市步行与迪士尼游 为期三天的上海行程,结合了市区的拍照打卡和迪士尼游玩。3["城市漫步","打卡"]62.40776910797608 125.03514766540745 0.0 {"route":"[{\"day\":1,\"poiList\":[{\"id\":\"10559490\",\"name\":\"武康路\",\"type\":3,\"imageUrl\":\"https://dimg04.c-ctrip.com/images/0101112000hk8rpvx48D1.jpg\",\"poiScore\":1,\"playSpendTime\":\"1-2小时\",\"districtInfo\":\"上海/中国/亚洲\"},{\"id\":\"75611\",\"name\":\"外滩\",\"type\":3,\"imageUrl\":\"https://dimg04.c-ctrip.com/images/10040m000000dht6p0F19.jpg\",\"poiScore\":1,\"playSpendTime\":\"1-3小时\",\"districtInfo\":\"上海/中国/亚洲\"}]},{\"day\":2,\"poiList\":[{\"id\":\"13412802\",\"name\":\"上海迪士尼度假区\",\"type\":3,\"imageUrl\":\"https://dimg04.c-ctrip.com/images/01055120008ji2uc75021.jpg\",\"districtInfo\":\"上海/中国/亚洲\"}]},{\"day\":3,\"poiList\":[{\"id\":\"148547980\",\"name\":\"外滩观景台\",\"type\":3,\"imageUrl\":\"https://dimg04.c-ctrip.com/images/fd/tg/g1/M06/FC/24/CghzflW7H_iATdynAAA-FlXAIeA738.jpg\",\"poiScore\":1,\"playSpendTime\":\"\",\"districtInfo\":\"上海/中国/亚洲\"},{\"id\":\"82870\",\"name\":\"外白渡桥\",\"type\":3,\"imageUrl\":\"https://dimg04.c-ctrip.com/images/100f1f000001gqbop5073.jpg\",\"poiScore\":1,\"playSpendTime\":\"0.5-1小时\",\"districtInfo\":\"上海/中国/亚洲\"},{\"id\":\"75611\",\"name\":\"外滩\",\"type\":3,\"imageUrl\":\"https://dimg04.c-ctrip.com/images/10040m000000dht6p0F19.jpg\",\"poiScore\":1,\"playSpendTime\":\"1-3小时\",\"districtInfo\":\"上海/中国/亚洲\"},{\"id\":\"31660589\",\"name\":\"洛克外滩源\",\"type\":3,\"imageUrl\":\"https://dimg04.c-ctrip.com/images/1A0f1d000001em91n485C.jpg\",\"poiScore\":1,\"playSpendTime\":\"1-2小时\",\"districtInfo\":\"上海/中国/亚洲\"},{\"id\":\"31675785\",\"name\":\"乍浦路桥\",\"type\":3,\"imageUrl\":\"https://dimg04.c-ctrip.com/images/0105t12000f6u0ykp7FBB.jpg\",\"poiScore\":1,\"playSpendTime\":\"0.5-1小时\",\"districtInfo\":\"上海/中国/亚洲\"}]}]"} {"code":"[[\"10559490\",\"75611\"],[\"13412802\"],[\"148547980\",\"82870\",\"75611\",\"31660589\",\"31675785\"]]","source":"xhs"} 上海/中国/亚洲 武康路,外白渡桥,洛克外滩源,外滩,乍浦路桥,外滩观景台,上海迪士尼度假区 2025-06-30 11:03:25 2025-07-29 01:41:36