ElasticSearch的KNN向量语义检索与MB25关键词检索原理
这两个检索算法是混合检索的左膀右臂,理解它们的底层逻辑,才能解释清楚为什么要“混合”。
一、 ES KNN 向量语义检索原理
核心逻辑: “不再匹配字面词语,而是匹配语义概念。”
1. 向量化
KNN 检索的第一步是将文本转化为计算机能理解的数学形式——向量。
- 过程:利用 Embedding 模型(如 BERT, OpenAI Embedding, HuggingFace 模型)将文本映射为高维空间中的坐标点(例如 768 维或 1536 维浮点数数组)。
- 语义空间:在这个高维空间中,语义相似的词或句子,距离会非常近。
- 例如:“苹果”和“水果”的距离,要比“苹果”和“汽车”的距离近得多。
- 甚至“Nvidia”和“显卡”在空间中也会有较近的距离,因为它们经常出现在相似的上下文中。
2. 相似度计算
当用户查询“Nvidia显卡性能”时,查询语句也会被转化为一个向量。ES 需要在库中找到与这个查询向量距离最近的文档向量。常用的距离度量有:
- 余弦相似度:衡量两个向量方向的夹角,适合衡量语义相似度(方向一致即可,长度不重要)。
- 欧氏距离:衡量两点间的直线距离。
- 点积:衡量向量长度和方向的综合性指标。
3. KNN 搜索与 HNSW 索引
这是 ES 实现高效向量检索的核心技术。如果用暴力的方式计算查询向量与库中所有向量的距离,速度极慢($O(N)$ 复杂度)。 ES 使用了 HNSW (Hierarchical Navigable Small World) 算法:
- 原理:借鉴了“六度人脉理论”。它构建了一张分层的图,上层是稀疏的高速公路,下层是稠密的精确节点。
- 搜索过程:从图的最上层入口开始,像坐飞机一样快速跳转到目标区域附近,然后逐层向下,像坐火车、再坐汽车,最后精确锁定最近的几个邻居。
- 特点:牺牲了极微小的精度(近似搜索),换取了极高的速度($O(\log N)$ 复杂度)。
4. KNN 的优劣势
- 优势:具备泛化能力。搜“好吃的红色水果”,能召回“苹果”的文档,即使文档里没有“水果”二字。
- 劣势:对专有名词“失忆”。因为模型训练时是根据上下文概率预测的,专有名词(如“Nvidia RTX 4090”)被压缩进向量后,可能丢失了精确的字面特征。如果模型训练不好,它可能把“Nvidia”和“AMD”混淆,因为它们总是出现在相似的上下文(“显卡”、“性能”)中。
二、 BM25 关键词检索原理
核心逻辑: “基于概率论的字面精确匹配与权重排序。”
BM25 是目前最权威的全文检索排序算法,是对传统 TF-IDF 的改进。
1. 核心公式拆解
BM25 的核心在于计算一个文档 $D$ 与查询词 $Q$ 的相关性得分。公式看起来复杂,其实逻辑很清晰:
$$ \text{Score}(D, Q) = \sum_{i=1}^{n} \text{IDF}(q_i) \cdot \frac{f(q_i, D) \cdot (k_1 + 1)}{f(q_i, D) + k_1 \cdot (1 - b + b \cdot \frac{|D|}{\text{avgdl}})} $$
我们可以把它拆解为三个部分来理解:
A. IDF (Inverse Document Frequency) - 逆向文档频率
- 含义:这个词“稀不稀罕”?
- 逻辑:如果全库只有 1 篇文档提到“Nvidia”,那它的权重极高;如果所有文档都提到了“显卡”,那“显卡”这个词的权重就低。
- 作用:区分度高,能快速定位关键线索。
B. TF (Term Frequency) - 词频饱和度
- 含义:这个词在文档里出现了几次?
- 改进点:传统的 TF-IDF 认为出现次数越多越重要,这容易被长文档作弊(比如关键词堆砌)。
- BM25 的优化:引入了饱和函数。出现 1 次到 2 次得分增加明显,但出现 100 次和出现 50 次的得分差距就很小了。它有一个上限(渐近线),防止词频过高主导得分。公式中的 $k_1$ 参数就控制了这个饱和速度。
C. 文档长度归一化
- 含义:文档是不是太长了?
- 逻辑:长文档天然容易包含更多关键词。如果不惩罚,长文档总是排名靠前。
- 参数 $b$:控制惩罚力度。如果文档越长,分母越大,得分越低。
2. BM25 的优劣势
- 优势:精确。只要文档里有“Nvidia”这个字,BM25 就一定能搜到,且会因为 IDF 高而给很高的权重。
- 劣势:语义鸿沟。搜“番茄”找不到“西红柿”;搜“显卡性能”找不到“GPU 跑分”。
三、 总结
可以这样总结这两个原理,并自然引出混合检索的必要性:
BM25 是基于‘概率统计’的精确匹配。 它通过 IDF 计算词的稀有度,通过带有饱和限制的 TF 计算词频权重。它非常严谨,对‘Nvidia’这种专有名词极其敏感,能精准锁定目标,但它不懂语义,搜‘苹果’找不到‘水果’。
KNN 是基于‘几何距离’的语义匹配。 它通过深度模型将文本映射到高维向量空间,通过 HNSW 图索引快速搜索最近邻。它具备强大的泛化能力,能理解‘性能’和‘跑分’是近义词,但在处理专有名词时,可能会因为模型压缩导致的语义边界模糊,混淆了‘Nvidia’和‘AMD’。
混合检索的本质,就是结合‘精确的统计信息’与‘模糊的语义理解’。 这也是为什么我在项目中引入 RRF 算法,让 BM25 纠正 KNN 在专有名词上的偏差,同时让 KNN 补充 BM25 无法召回的语义相关文档。