BM42介绍

为什么需要BM42

BM25(Best Matching 25)是一个基于概率模型的检索函数,主要用于评估文档与查询之间的相关性。它在信息检索系统中广泛使用,比如搜索引擎和推荐系统。但是自从引入 RAG 以来,文本检索的用例发生了显著变化。BM25 所基于的许多假设不再有效。

  • 由于RAG模型的引入,文本检索不再仅依赖于词频和逆文档频率等传统假设,而是结合了语义理解和上下文信息,从而提升了检索的准确性和相关性。
  • 传统网络搜索和现代 RAG 系统之间文档和查询的典型长度存在大差异,RAG 中文档的典型长度比网络搜索的文档长度短得多。

BM42是开源向量数据库供应商 Qdrant 开发了的 搜索算法,将向量和标准 BM25 关键字搜索方法相结合,以获得更好的 RAG 结果,声称该方法降低了成本。

BM42的工作原理

  1.  BM42保留了BM25的逆文档频率(IDF)计算,这部分在Qdrant引擎中进行,以确保IDF计算实时更新。
  2. 利用Transformer模型的注意力矩阵,特别是从[CLS]标记的行提取各个token对整个文档的重要性。注意力权重反映了每个token在文档中的重要性。
    • 输入查询和文档,利用Transformer模型生成注意力权重矩阵。注意力矩阵是一个方阵,其中每一行和每一列代表输入序列中的一个token
  3. 最终的BM42得分公式结合了IDF和注意力权重\text{score}(D, Q) = \sum_{i=1}^{N} \text{IDF}(q_i) \times \text{Attention}(\text{CLS}, q_i)
  4. 使用WordPiece tokenization,并在计算注意力权重后合并子词token,确保准确性。在BM42中,Token重组步骤非常关键,它确保了从注意力机制中提取的权重可以准确地应用于词频统计。
    •  Transformer模型通常使用WordPiece tokenization将单词拆分成更小的子词单元。例如,“programming”可能被拆分成“pro”,“##gram”,“##ming”。
    • 为了将注意力权重应用于BM25的IDF计算,必须将子词Token的注意力权重合并回原始单词。例如,对于“programming”:
      •  原始子词权重可能是 [0.03, 0.05, 0.07]
      • 合并后,整个单词的权重为 0.03 + 0.05 + 0.07 = 0.15
    • 通过这种方式,我们可以显著减少 token 的数量,从而最大限度地减少稀疏嵌入的内存占用。我们不会同时损害匹配(几乎)精确 token 的能力。

BM42效果

BM42对于小文档处理的准确性远远高于BM25,但对于长查询和复杂查询,效果可能不如 BM42。

 代码解释

在原库中总共进行了三种方法,这里只介绍BM42的代码

要运行的代码主要是两个,一个是index_bm42.py,一个是evaluate_bm42.

需要的库

运行代码前,需要先安装所需要的库。

tqdm
qdrant-client>=1.10.0
fastembed>=0.3.3
tantivy
ipdb

在运行代码之前,请确保已启动 Qdrant 容器。可以通过以下命令启动 Qdrant Docker 容器:

docker run --rm -d --network=host qdrant/qdrant:v1.10.0
index

index 主要是用来将文档嵌入到向量空间中并在 Qdrant 中储存。

在训练的过程中我们只需要文档中的`_id`和`text`

之后我们将每个id和text转换成稀疏向量,上传到Qdrant上面

client.create_collection(

        collection_name=DATASET,

        vectors_config={},

        sparse_vectors_config={

            "bm42": models.SparseVectorParams(

                modifier=models.Modifier.IDF

            )

        }

    )

在Qdrant中创建一个新的集合,配置其稀疏向量,并使用IDF作为稀疏向量的修饰符,以便后续在该集合中存储和检索文档向量。

使用 BM42 编码后,每个文档的平均向量大小仅为 5.6 个元素。

evaluate

evaluate主要是将query转化成稀疏向量,在Qdrant数据库中搜索最近的向量,结合Bm42model返回前十个相似的文档

dataset:

图中是储存query的json文件,这里面每个query都有id,text,metadata三列

图中是存储每个query应该对应的文档,表示一个查询与一个文档的对应关系,最后一列是文档与query的相关关系,1代表相关

preprocess

通过对两个文件进行预处理后,我们应该得到一个结构的数据

{

    "2254": {

        "_id": "2254",

        "text": "Who were the Aztec?",

        "metadata": {},

        "doc_ids": ["101", "103"]

    }

}

这里doc_ids是相关的文档标签

model
model = SparseTextEmbedding(

    model_name="Qdrant/bm42-all-minilm-l6-v2-attentions"

)

SparseTextEmbedding是一个预训练的Transformer模型,专门用于生成稀疏嵌入向量。
 

 result = client.query_points(

            collection_name=DATASET,

            query=sparse_vector,

            using="bm42",

            with_payload=True,

            limit=limit

        )

这里使用bm42计算输入的query与其他文档的得分,并且返回分数最高的前10个文档,这里limit定义为10所以返回前十个,可以更改limit值

  • 29
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值