Skip to content

BM25检索

Milvus BM25设计

介绍

BM25(Best Matching 25 / 最佳匹配 25)是一种经典的关键词匹配型全文检索算法。BM25 特别擅长处理精确关键词匹配,比如订单号 A-9527、错误码 ERR_404、合同编号等——这些往往是向量检索(语义相似)容易忽略的“硬信息”。

稀疏向量

稀疏向量与稠密向量

img

稀疏向量可通过两种方法生成:

  • 传统的统计技术:Milvus 利用 BM25 方法提供内置的全文搜索功能,可自动将文本转换为稀疏向量,无需人工预处理。
  • 神经稀疏嵌入模型:Milvus 还支持由SPLADE 等模型外部生成的稀疏嵌入。

全文搜索

全文搜索是一种在文本数据集中检索包含特定术语或短语的文档,然后根据相关性对结果进行排序的功能。

工作流程

  • 原始文本输入:插入文本文档或使用纯文本提供查询,无需嵌入模型。
  • 文本分析:Milvus 使用分析器将您的文本处理成可索引和搜索的有意义术语。
  • BM25 函数处理:一个内置函数可将这些术语转换为针对 BM25 评分优化的稀疏向量表示。
  • Collections 存储:Milvus 将生成的稀疏嵌入存储在一个 Collections 中,以便快速检索和排序。
  • BM25 相关性评分:在搜索时,Milvus 应用 BM25 评分函数计算文档相关性,并返回与查询词最匹配的排序结果。

img

参考资料

Milvus BM25实战

配置

从 Milvus 2.5 开始,原生集成了 BM25 全文检索能力(基于 Tantivy 引擎),无需额外部署 Elasticsearch 或 Whoosh。

定义 Schema 和 BM25 函数

python
from pymilvus import DataType, MilvusClient, Function, FunctionType

collection_schema = MilvusClient.create_schema(enable_dynamic_field=True)
collection_schema.add_field(
    field_name="id",
    datatype=DataType.INT64,
    is_primary=True,
    auto_id=True,
    description="主键ID(自增)",
)
collection_schema.add_field(
    field_name="vector",
    datatype=DataType.FLOAT_VECTOR,
    dim=settings.MILVUS_DIMENSION,
    description="向量数据",
)
# 稀疏向量:用于混合搜索
collection_schema.add_field(
    field_name="sparse_vector",
    datatype=DataType.SPARSE_FLOAT_VECTOR,
    description="稀疏向量数据(BM25)",
)
collection_schema.add_field(
    field_name="text",
    datatype=DataType.VARCHAR,
    max_length=65535,
    enable_analyzer=True,  # 启用文本分析器
    description="文本数据",
)
# BM25 函数将文本转换为支持 BM25 评分的稀疏向量
bm25_function = Function(
    name="text_bm25_emb",
    input_field_names=["text"],
    output_field_names=["sparse_vector"],
    function_type=FunctionType.BM25,
)
collection_schema.add_function(bm25_function)

配置索引

python
### 配置集合索引参数
index_params = MilvusClient.prepare_index_params()
index_params.add_index(
    field_name="sparse_vector",
    index_type="SPARSE_INVERTED_INDEX",
    metric_type="BM25",
    params={"inverted_index_algo": "DAAT_MAXSCORE", "bm25_k1": 1.2, "bm25_b": 0.75},
)

全文搜索

创建 Collections,插入数据后,可以进行全文搜索

python
from pymilvus import MilvusClient, SearchResult


client = MilvusClient(uri="http://127.0.0.1:19530")
client.use_database(db_name="default_db")

query = "危险化学品"
res = client.search(
    collection_name="default_collection",
    data=[query],
    anns_field="sparse_vector",
    output_fields=["text"],
    limit=3,
)
print(type(res))
print(len(res[0]))
for i in res[0]:
    print(i)

输出结果示例

说明:若不匹配,结果可能为空

bash
<class 'pymilvus.client.search_result.SearchResult'>
3
{'id': 464289779212620353, 'distance': 5.397517204284668, 'entity': {'text': '合格,取得特种作\n业证书。\n4.其他从业人员\n按照国家有关规\n定,经过安全教育\n培训。\n10\n《危险化学品\n生产企业安全\n生产许可实施\n办法》第十七条\n企业应当按照国家规定提取与安全生产有关的\n费用 '}}
{'id': 464289779212620351, 'distance': 5.232833385467529, 'entity': {'text': '须适用同一标准的规定。\n符 合\n要求\n1.相关单位具备\n国家规定的资质\n2.不涉及国家命\n令淘汰、禁止使用\n和危及安全生产\n的工艺、设备。\n3.设置可燃气体\n报警系统。\n4.生产区和非生\n产分开设置\n5.'}}
{'id': 464289779212620352, 'distance': 4.690459251403809, 'entity': {'text': '(八)重大危险源评估和安全管理制度;\n(九)变更管理制度;\n(十)应急管理制度;\n(十一)生产安全事故或者重大事件管理制度;\n(十二)防火、防爆、防中毒、防泄漏管理制度;\n(十三)工艺、设备、电气仪表、公用工程'}}