Decay Ranker 概述
在传统的向量搜索中,结果纯粹是按照向量相似度来排序的,即向量在数学空间中的匹配程度。但在实际应用中,使内容真正相关的因素往往不仅仅取决于语义相似度。
思考一下这些日常场景:
-
一个新闻搜索,其中昨天的文章应该比三年前的类似文章排名更高
-
一款餐厅查找器,优先推荐距离5分钟路程的场所,而非需要30分钟车程的场所
-
一个电子商务平台,即使热门产品与搜索查询的相似度略低,也能提升其热度
这些场景都有一个共同的需求:平衡向量相似度与其他数值因素,如时间、距离或受欢迎程度。
Zilliz Cloud 中的 Decay Ranker 通过根据数字类型字段的值调整搜索排名来满足这一需求。它们使您能够在向量相似度与数据的“新鲜度”、“接近度”或其他数值属性之间取得平衡,从而创造出更直观、与上下文相关的搜索体验。
使用说明
-
Decay Ranker 不能用于 Grouping Search。
-
Decay Ranker 中引用的字段必须为数字类型(
INT8
、INT16
、INT32
、INT64
、FLOAT
或DOUBLE
)。 -
每个 Decay Ranker 只能使用一个数字类型的字段。
-
时间单位一致性:使用基于时间的 Decay Ranker 时,
origin
、scale
和offset
等参数的单位必须与集合数据中使用的单位相匹配:-
如果您的集合以秒为单位存储时间戳,请对所有参数使用秒
-
如果您的集合以毫秒为单位存储时间戳,请对所有参数使用毫秒
-
如果您的集合以微秒为单位存储时间戳,请对所有参数使用微秒
-
工作原理
Decay Ranker 通过将时间或地理距离等数值因素纳入排序过程,增强了传统向量搜索。整个过程遵循以下阶段:
阶段1:计算归一化相似度得分
首先,Zilliz Cloud 计算并归一化向量相似度得分,以确保比较的一致性:
-
对于 L2 和 JACCARD 等基于距离的相似性度量类型(其中值越低表示相似度越高):
normalized_score = 1.0 - (2 × arctan(score))/π
这将距离转换为 0 到 1 之间的相似度得分,得分越高越好。
-
对于 IP、COSINE 和 BM25 等基于得分的相似性度量类型(其中较高的分数已经表示更好的匹配):分数直接使用,不进行归一化处理。
阶段2:计算衰减分数
接下来,Zilliz Cloud 会使用您选择的 Decay Ranker,根据指定的数字段的值(如时间戳或距离)计算衰减分数:
-
每个 Decay Ranker 将原始数值转换为 0 到 1 之间的归一化相关性得分
-
衰减得分表示一个项目基于其与理想点的“距离”的相关性
具体的计算公式因 Decay Ranker 类型而异。有关如何计算衰减分数的详细信息,请参考高斯衰减、指数衰减、线性衰减。
阶段3:计算最终得分
最后,Zilliz Cloud 将归一化相似度得分和衰减得分相结合,得出最终排名得分:
final_score = normalized_similarity_score × decay_score
在混合搜索(结合多个向量字段)的情况下,Zilliz Cloud 会采用搜索请求中的最大归一化相似度得分:
final_score = max([normalized_score₁, normalized_score₂, ..., normalized_scoreₙ]) × decay_score
例如,在混合搜索中,如果一篇研究论文的向量相似度评分为 0.82,基于 BM25 的文本检索评分为0.91,Zilliz Cloud 在应用衰减因子之前会使用0.91作为基础相似度评分。
使用 Decay Ranker
让我们来看一个在实际场景中使用 Decay Ranker 的示例——以基于时间的衰减来搜索**"AI research papers"**:
在这个示例中,衰减分数反映了相关性如何随时间减弱——较新的论文得分更接近1.0,较旧的论文得分较低。这些值是使用特定的 Decay Ranker 计算得出的。有关详细信息,请参阅选择合适的 Decay Ranker。
论文 | 向量相似度 | 归一化相似度得分 | 出版日期 | 衰减得分 | 最终得分 | 最终排名 |
---|---|---|---|---|---|---|
论文 A | 高 | 0.85 ( | 两周前 | 0.80 | 0.68 | 2 |
论文 B | 非常高 | 0.92 ( | 6个月前 | 0.45 | 0.41 | 3 |
论文 C | 中等 | 0.75 ( | 1天前 | 0.98 | 0.74 | 1 |
文件 D | 中高 | 0.76 ( | 3周前 | 0.70 | 0.53 | 4 |
如果不使用 Decay Ranker,论文 B 将基于纯向量相似度(0.92)排名最高。然而,应用 Decay Ranker 后:
-
论文 C 尽管相似度中等,但因其非常新(昨天发表)而跃升至第 1 位
-
论文 B 尽管相似度极高,但由于相对较旧,仍降至第 3 位
-
论文 D 使用L2距离(数值越低越好),因此在应用衰减之前,其得分从 1.2 归一化为 0.76
选择合适的 Decay Ranker
Milvus提供了不同的 Decay Ranker - 高斯(gauss
)、指数(exp
)、线性(linear
),每个 Ranker 都针对特定用例设计:
衰减排序器 | 特性 | 理想用例 | 示例场景 |
---|---|---|---|
高斯( | 自然的、适度延伸的渐进式衰退 |
| 在餐厅搜索中,距离3公里的优质场所仍可被发现,不过排名会低于附近的选项 |
指数( | 起初迅速下降,但保持长尾 |
| 在新闻应用中,昨天的报道排名远高于一周前的内容,但高度相关的旧文章仍可能出现 |
线性( | 有明确界限的一致、可预测的下降 |
| 在活动查找器中,超过两周未来时间范围的活动根本不会显示 |
有关每个 Decay Ranker 如何计算分数以及具体衰减模式的详细信息,请参考相关文档:
实施示例
Decay Ranker 可应用于 Zilliz Cloud 中的标准向量搜索和混合搜索操作。以下是实现此功能的关键代码片段。
在使用 Decay Ranker 之前,你必须首先创建一个包含适当数字类型字段(如时间戳、距离等)的集合,这些字段将用于衰减计算。有关包括 Collection 设置、 Schema 定义和数据插入的完整工作示例,请参考教程:实现基于时间的搜索结果重排。
创建一个衰减排序器
要实现衰减排序,首先定义一个 Function
对象,并进行适当的配置:
- Python
- Java
- NodeJS
- Go
- cURL
from pymilvus import Function, FunctionType
# Create a decay function for timestamp-based decay
# Note: All time parameters must use the same unit as your collection data
decay_ranker = Function(
name="time_decay", # Function identifier
input_field_names=["timestamp"], # Numeric field to use for decay
function_type=FunctionType.RERANK, # Must be set to RERANK for decay rankers
params={
"reranker": "decay", # Specify decay reranker. Must be "decay"
"function": "gauss", # Choose decay function type: "gauss", "exp", or "linear"
"origin": int(datetime.datetime(2025, 1, 15).timestamp()), # Reference point (seconds)
"scale": 7 * 24 * 60 * 60, # 7 days in seconds (must match collection data unit)
"offset": 24 * 60 * 60, # 1 day no-decay zone (must match collection data unit)
"decay": 0.5 # Half score at scale distance
}
)
// java
// nodejs
// go
# restful
参数 | 是否必需? | 描述 | 值/示例 |
---|---|---|---|
| 是 | 执行搜索时使用的函数标识符。选择一个与你的用例相关的描述性名称。 |
|
| 是 | 用于衰减分数计算的数字字段名称列表。确定将使用数据集的哪个属性来计算衰减(例如,基于时间的衰减使用时间戳,基于位置的衰减使用坐标)。 必须是 Collection 中包含相关数值的字段。支持INT8/16/32/64、FLOAT、DOUBLE。 |
|
| 是 | 指定正在创建的函数类型。 所有 Decay Ranker 都必须设置为 |
|
| 是 | 指定要使用的重排序方法。 必须设置为 |
|
| 是 | 指定要应用的 Decay Ranker 类型。确定相关性下降的曲线形状。 请参阅选择合适的 Decay Ranker 部分,以获取相关指导。 |
|
| 是 | 计算衰减分数的参考点。处于该值的项目将获得最大相关性分数。 对于基于时间的衰减,时间单位必须与您的集合数据相匹配。 |
|
| 是 | 相关性降至 对于基于时间的衰减,时间单位必须与您的 Collection 中的数据相匹配。 较大的值会使相关性下降更为平缓;较小的值则会使相关性下降更为陡峭。 |
|
| 否 | 在 对于基于时间的衰减,时间单位必须与您的 Collection 中的数据相匹配。 在 |
|
| 否 | 在 必须介于 0 和 1 之间。 |
|
在标准向量搜索中使用
定义 Decay Ranker 后,您可以在搜索请求中通过将其传递给 ranker
参数来应用它:
- Python
- Java
- NodeJS
- Go
- cURL
# Use the decay function in standard vector search
results = milvus_client.search(
collection_name,
data=["search query"],
anns_field="vector_field",
limit=10,
output_fields=["document", "timestamp"], # Include the decay field in outputs to see values
# highlight-next-line
ranker=decay_ranker, # Apply the decay ranker here
consistency_level="Strong"
)
// java
// nodejs
// go
# restful
在混合搜索中使用
衰减排序器也可应用于结合多个向量字段的混合搜索操作:
- Python
- Java
- NodeJS
- Go
- cURL
from pymilvus import AnnSearchRequest
# Define search requests for different vector fields
dense_request = AnnSearchRequest(
data=["search query"],
anns_field="dense_vector",
param={},
limit=20
)
sparse_request = AnnSearchRequest(
data=["search query"],
anns_field="sparse_vector",
param={},
limit=20
)
# Apply decay ranker to hybrid search
hybrid_results = milvus_client.hybrid_search(
collection_name,
[dense_request, sparse_request],
# highlight-next-line
ranker=decay_ranker, # Same decay ranker works with hybrid search
limit=10,
output_fields=["document", "timestamp"]
)
// java
// nodejs
// go
# restful
在混合搜索中,Zilliz Cloud 首先从所有向量字段中找到最大相似度得分,然后对该得分应用衰减因子。