Milvus - 混合搜索和重排策略详解

news/2024/11/6 12:23:42 标签: milvus, 人工智能, 深度学习, embedding, AI编程, AIGC

在AI驱动的搜索系统中,如何有效地结合多模态的向量数据是关键。Milvus 的 hybrid_search() API 提供了这种混合搜索的功能,支持通过多种重排策略来进一步优化搜索结果。这篇文章将详细介绍 Milvus 中重排的过程、其重要性以及如何实现不同的重排策略。


什么是重排?

重排(Reranking)是混合搜索中的一个关键步骤,它用于整合多个向量场的结果,以确保最终输出具有相关性和优先级。当前 Milvus 提供两种重排策略:

  1. WeightedRanker - 基于权重分配,通过计算加权平均值来合并不同向量场的搜索结果。
  2. RRFRanker - 基于互易等级融合 (Reciprocal Rank Fusion, RRF),通过倒数计算排名融合,以平衡每个向量字段的影响。

以下内容将详细介绍这两种策略的原理、使用场景及代码示例。


WeightedRanker:加权评分

当需要根据向量字段的重要性优先排序结果时,可以使用 WeightedRanker。例如,在多模态搜索中,可能需要将文本描述权重设置得比图像特征更高,以反映其更大的重要性。

基本流程:

  1. 收集分数:在检索过程中收集来自不同向量检索路径的得分。

  2. 分数归一化:将每条路径的得分归一化为 [0,1]。因为不同度量方法的分数分布差异很大,如 IP 的距离范围为 [-∞,+∞],L2 为 [0,+∞]。Milvus 使用 arctan 函数将分数归一化,以确保不同度量的标准化。

    arctan-function
    
  3. 权重分配:根据每个字段的重要性分配权重 w𝑖,取值范围为 [0,1]。用户定义的权重通常反映了数据源的相关性或可靠性。

  4. 分数融合:最终分数通过加权平均值计算得出。结果会根据这些分数进行排序,从而生成最终的优先级顺序。

代码示例:

假设我们在 Milvus 中有两个向量字段,例如图像特征(image_embedding)和文本描述特征(text_embedding),并希望在搜索结果中将文本描述的权重设置得比图像特征更高。可以通过 WeightedRanker 实现这一需求。

from pymilvus import Collection, WeightedRanker, AnnSearchRequest

# 假设我们已经创建了 collection
collection = Collection("example_collection")

# 1. 创建两个 AnnSearchRequest 实例
# 图像特征的搜索请求
image_search_request = AnnSearchRequest(
    field_name="image_embedding",
    query_vectors=[[0.1, 0.2, 0.3, ...]],  # 替换为实际的查询向量
    metric_type="L2",
    top_k=10
)

# 文本特征的搜索请求
text_search_request = AnnSearchRequest(
    field_name="text_embedding",
    query_vectors=[[0.5, 0.6, 0.7, ...]],  # 替换为实际的查询向量
    metric_type="IP",
    top_k=10
)

# 2. 定义 WeightedRanker,指定各个向量字段的权重
# 这里给文本描述较高的权重 0.8,图像特征较低的权重 0.7
weighted_ranker = WeightedRanker(0.7, 0.8)

# 3. 使用 collection 的 hybrid_search 方法执行搜索并应用 WeightedRanker
results = collection.hybrid_search(
    search_requests=[image_search_request, text_search_request],
    ranker=weighted_ranker
)

# 打印最终结果
print("WeightedRanker 搜索结果:")
for result in results:
    print(result)

在这个示例中,WeightedRanker(0.7, 0.8) 表示对两个向量字段的搜索结果进行加权,分别为图像特征 0.7 和文本特征 0.8。更高的权重会使该字段在最终排序中更加突出。


RRFRanker:互易等级融合

RRFRanker 基于 RRF 算法,通过排名的倒数来融合排名列表。在没有明确优先级或需要平衡所有向量场影响时,RRF 是非常有效的重排策略。

基本流程:

  1. 收集排名:在检索过程中,跨多个向量字段检索并对结果进行排序。

  2. 排名融合:RRF 算法使用如下公式对每个检索器的排名进行权衡和合并:

    rrf-ranker
    

    其中,𝑁 表示不同检索路径的数量,rank𝑖(𝑑) 是第 𝑖 个检索器对文档𝑑 的排名位置,𝑘 是平滑参数(默认设置为 60)。

  3. 综合排名:RRF 综合每个检索器的排名并重新排序,得到最终的排序结果。

代码示例:

RRFRanker 是一种无需指定权重的重排策略,适合在不确定字段优先级的情况下使用。RRFRanker 会根据各个搜索请求的倒数排名进行综合排序。

from pymilvus import Collection, RRFRanker, AnnSearchRequest

# 假设我们已经创建了 collection
collection = Collection("example_collection")

# 1. 创建两个 AnnSearchRequest 实例
# 图像特征的搜索请求
image_search_request = AnnSearchRequest(
    field_name="image_embedding",
    query_vectors=[[0.1, 0.2, 0.3, ...]],  # 替换为实际的查询向量
    metric_type="L2",
    top_k=10
)

# 文本特征的搜索请求
text_search_request = AnnSearchRequest(
    field_name="text_embedding",
    query_vectors=[[0.5, 0.6, 0.7, ...]],  # 替换为实际的查询向量
    metric_type="IP",
    top_k=10
)

# 2. 定义 RRFRanker 实例(可选 k 值)
rrf_ranker = RRFRanker(k=60)  # 平滑参数默认为 60,可调整

# 3. 使用 collection 的 hybrid_search 方法执行搜索并应用 RRFRanker
results = collection.hybrid_search(
    search_requests=[image_search_request, text_search_request],
    ranker=rrf_ranker
)

# 打印最终结果
print("RRFRanker 搜索结果:")
for result in results:
    print(result)

在这个示例中,RRFRanker(k=60) 将两个向量字段的排名结果进行融合,无需用户指定具体权重。结果中,多个字段一致认为优先的条目会自动提升优先级。


总结

Milvus 提供的重排策略在多模态数据搜索中发挥了重要作用。通过加权排序的 WeightedRanker 和互易等级融合的 RRFRanker,用户可以灵活调整各字段的影响,从而获得更加精确的搜索结果。


http://www.niftyadmin.cn/n/5740872.html

相关文章

大模型学习笔记------CLIP模型的再思考

大模型学习笔记------CLIP模型的再思考 1、CLIP模型与Prompt(提示)的思考2、CLIP模型与ResNet等分类模型的根本区别3、结束语 上文已经讲 CLIP(Contrastive Language-Image Pretraining)这个模型,也讲了我的一些思考。但是,随着深…

【手撕排序1】希尔排序(直接插入排序)

🍃 如果觉得本系列文章内容还不错,欢迎订阅🚩 🎊个人主页:小编的个人主页 🎀 🎉欢迎大家点赞👍收藏⭐文章 ✌️ 🤞 🤟 🤘 🤙 👈 &…

springboot3.3.4集成接口文档Swagger、Knife4j

1、springboot3.3.4集成Swagger 1、导包 <!--springboot3.3.4集成Swagger--> <dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.0.2</version> </…

Mysql海量数据经常有下面这些操作,离被开除就不远了(持续更新)

目录 1. INSERT INTO SELECT 2. JOIN 多表连接查询 3. SELECT * 查询 4. ORDER BY 无索引 5. UPDATE 无条件更新 6. DELETE 操作删除所有记录 7. OR 连接条件查询 8. DISTINCT 操作 9. GROUP BY 操作 10. LIKE 操作 11. HAVING 子句 1. INSERT INTO SELECT 问题描述…

Flutter中有趣的级联语法

目录 前言 一、基本语法 二、级联语法的优点 三、使用场景 1.初始化对象的多个属性 2.Widget 链式构建 3.调用多个方法 4.链式操作异步请求 前言 在 Flutter&#xff08;Dart&#xff09;中&#xff0c;级联操作符&#xff08;cascade notation&#xff09; 使用两个点…

Ansible 部署 Windows QQ 详解

1. Ansible 基础概述 Ansible 是一个开源的自动化工具&#xff0c;适用于配置管理、应用部署、任务自动化和 IT 编排。它通过简单的 YAML 格式的配置文件&#xff08;称为 Playbooks&#xff09;将复杂的操作简化为可重复执行的流程。 2. Windows 环境准备 安装 Ansible 在…

LeetCode30:串联所有单词的子串

原题地址&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。 例如&#xff0c;如果 words ["…

如何在一个 Docker 容器中运行多个进程 ?

在容器化的世界里&#xff0c;Docker 彻底改变了开发人员构建、发布和运行应用程序的方式。Docker 容器封装了运行应用程序所需的所有依赖项&#xff0c;使其易于跨不同环境一致地部署。然而&#xff0c;在单个 Docker 容器中管理多个进程可能具有挑战性&#xff0c;这就是 Sup…