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

在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,用户可以灵活调整各字段的影响,从而获得更加精确的搜索结果。

### 向量数据库中的混合检索 向量数据库通过结合结构化查询相似度搜索来支持混合检索。这种能力使得应用程序不仅能够高效处理大规模高维数据集上的近似最近邻 (ANN) 查询,还能执行传统的 SQL 类型操作。 #### 结构化与非结构化数据的融合 为了实现高效的混合检索,向量数据库通常会集成两种主要的数据访问模式: - **基于标签或属性的精确匹配**:允许用户根据元数据字段(如时间戳、类别等)过滤结果。 - **基于嵌入式的相似度搜索**:利用预先计算好的特征向量来进行语义级比较[^1]。 #### 技术架构设计 对于希望构建具备混合检索功能的应用程序而言,推荐采用分层索引策略。具体来说,在底层存储引擎之上叠加一层或多层索引来加速不同类型的查询请求。例如,可以使用倒排列表加快布尔逻辑运算的速度;而对于 kNN 查找,则依赖于专门优化过的图遍历算法或者树形结构,比如 HNSW 图[^2]。 #### 开发者指南 以下是几个有助于开发人员实施上述方案的关键建议: - 设计合理的表结构调整模型以适应业务需求变化; - 对频繁更新的部分考虑增量式维护机制减少开销; - 预先评估并测试各种参数配置下的性能表现找到最优解。 ```python from milvus import Milvus, IndexType, MetricType client = Milvus(host='localhost', port='19530') collection_param = { 'collection_name': 'example_collection', 'dimension': 128, 'index_file_size': 1024, # Optional: specify the size of each segment file. 'metric_type': MetricType.L2 } status, collection_id = client.create_collection(collection_param) # Create index on vectors to support efficient similarity search. index_param = {'nlist': 16384} # Number of clusters for IVF-based indexes. status = client.create_index('example_collection', IndexType.IVF_SQ8, index_param) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值