在AI驱动的搜索系统中,如何有效地结合多模态的向量数据是关键。Milvus 的 hybrid_search()
API 提供了这种混合搜索的功能,支持通过多种重排策略来进一步优化搜索结果。这篇文章将详细介绍 Milvus 中重排的过程、其重要性以及如何实现不同的重排策略。
什么是重排?
重排(Reranking)是混合搜索中的一个关键步骤,它用于整合多个向量场的结果,以确保最终输出具有相关性和优先级。当前 Milvus 提供两种重排策略:
- WeightedRanker - 基于权重分配,通过计算加权平均值来合并不同向量场的搜索结果。
- RRFRanker - 基于互易等级融合 (Reciprocal Rank Fusion, RRF),通过倒数计算排名融合,以平衡每个向量字段的影响。
以下内容将详细介绍这两种策略的原理、使用场景及代码示例。
WeightedRanker:加权评分
当需要根据向量字段的重要性优先排序结果时,可以使用 WeightedRanker。例如,在多模态搜索中,可能需要将文本描述权重设置得比图像特征更高,以反映其更大的重要性。
基本流程:
-
收集分数:在检索过程中收集来自不同向量检索路径的得分。
-
分数归一化:将每条路径的得分归一化为 [0,1]。因为不同度量方法的分数分布差异很大,如 IP 的距离范围为 [-∞,+∞],L2 为 [0,+∞]。Milvus 使用
arctan
函数将分数归一化,以确保不同度量的标准化。arctan-function
-
权重分配:根据每个字段的重要性分配权重
w𝑖
,取值范围为 [0,1]。用户定义的权重通常反映了数据源的相关性或可靠性。 -
分数融合:最终分数通过加权平均值计算得出。结果会根据这些分数进行排序,从而生成最终的优先级顺序。
代码示例:
假设我们在 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 是非常有效的重排策略。
基本流程:
-
收集排名:在检索过程中,跨多个向量字段检索并对结果进行排序。
-
排名融合:RRF 算法使用如下公式对每个检索器的排名进行权衡和合并:
rrf-ranker
其中,𝑁 表示不同检索路径的数量,rank𝑖(𝑑) 是第 𝑖 个检索器对文档𝑑 的排名位置,𝑘 是平滑参数(默认设置为 60)。
-
综合排名: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,用户可以灵活调整各字段的影响,从而获得更加精确的搜索结果。