高斯衰减
高斯衰减,也称为正态衰减,能对搜索结果进行最自然的调整。就像人类的视觉会随着距离逐渐模糊一样,高斯衰减会创建一条平滑的钟形曲线,随着项目远离理想点,逐渐降低其相关性。当你希望实现一种平衡的衰减,既不会对刚好超出首选范围的项目进行大举罚分,又能显著降低远距离项目的相关性时,这种方法是理想之选。
与其他 Decay Ranker 不同:
-
指数衰减起初下降迅速,产生更强的初始罚分
-
线性衰减以恒定速率下降直至归零,形成明确的截止点
高斯衰减提供了一种更加平衡、直观的方法,让用户感觉自然。
何时使用高斯衰减
高斯衰减在以下方面特别有效:
用例 | 示例 | 高斯衰减为何效果良好 |
---|---|---|
基于位置的搜索 | 餐厅查找器、店铺定位器 | 模拟人类对距离相关性的自然感知 |
内容推荐 | 基于发表日期的文章推荐 | 随着内容老化,相关性逐渐下降 |
产品列表 | 价格接近目标的商品 | 当价格偏离目标时,相关性平稳下降 |
专业匹配 | 寻找有相关经验的专业人士 | 对经验相关性的平衡评估 |
如果你的应用程序需要一种自然的相关性衰减感觉,而不采用严厉的惩罚或严格的截断,高斯衰减可能是你的最佳选择。
钟形曲线原理
高斯衰减会产生一条平滑的钟形曲线,随着与理想点的距离增加,相关性逐渐降低。这种分布以数学家卡尔·弗里德里希·高斯的名字命名,在自然界和统计学中经常出现。这也说明了为什么它在人类的感知中如此直观。
上图展示了高斯衰减如何影响移动搜索应用中的餐厅排名:
-
origin
(0公里):又被称为原点,表示您当前的位置。此处相关性达到最大值(1.0)。 -
offset
(±300米):又被称为偏移量,表示您周围的“完美得分区域”——300米范围内的所有餐厅均保持满分相关性得分(1.0),确保非常近的选项不会因微小的距离差异而被不必要地扣分。 -
scale
(±2公里):又被称为关注范围,表示相关性降至衰减值的距离——距离正好2公里的餐厅,其相关性得分减半(0.5)。 -
decay
(0.5):又被称为衰减值,表示在关注范围边缘的得分——此参数本质上控制得分随距离衰减的速度。
从曲线中可以看出,距离超过2公里的餐厅的相关性持续下降,但永远不会完全降至零。即使是4 - 5公里外的餐厅也保留了一定的最低相关性,这使得优质但距离较远的餐厅仍能出现在你的搜索结果中(尽管排名较低)。
这种行为模仿了人们自然思考距离相关性的方式——人们倾向于选择附近的地方,但为了特别的选择,也愿意走得更远。
公式
计算高斯衰减得分的数学公式为:
S(doc) = \exp\left( -\frac{\left( \max\left(0, \left|fieldvalue_{doc} - origin\right| - offset \right) \right)^2}{2\sigma^2} \right)其中:
用通俗易懂的语言来解释就是:
-
计算字段值离原点的距离:
-
减去偏移量(如果有的话),但结果永远不能小于零:
-
将这个调整后的距离平方:
-
除以,它是根据您的缩放和衰减参数计算得出的
-
取负指数,它会给出一个介于 0 和 1 之间的值:
该 计算将您的不衰减范围和衰减参数转换为高斯分布的均方差平方。这就是该函数呈现其特征钟形的原因。
使用高斯衰减
高斯衰减可应用于 Zilliz Cloud 中的标准向量搜索和混合搜索操作。以下是实现此功能的关键代码片段。
在使用 Decay Ranker 之前,你必须首先创建一个包含适当数字类型字段(如时间戳、距离等)的集合,这些字段将用于衰减计算。有关包括 Collection 设置、 Schema 定义和数据插入的完整工作示例,请参考教程:实现基于时间的搜索结果重排。
创建一个 Decay Ranker
在您的集合设置了一个数字字段(此处,以 distance
为例,单位为米)后,创建一个使用高斯衰减的 Decay Ranker:
- Python
- Java
- NodeJS
- Go
- cURL
from pymilvus import Function, FunctionType
# Create a Gaussian decay ranker for location-based restaurant search
ranker = Function(
name="restaurant_distance_decay", # Function identifier
input_field_names=["distance"], # Numeric field for distance in meters
function_type=FunctionType.RERANK, # Function type. Must be RERANK
params={
"reranker": "decay", # Specify decay reranker
"function": "gauss", # Choose Gaussian decay
"origin": 0, # Your current location (0 meters)
"offset": 300, # 300m no-decay zone
"decay": 0.5, # Half score at scale distance
"scale": 2000 # 2 km scale (2000 meters)
}
)
// java
// nodejs
// go
# restful
在标准向量搜索中使用
定义 Decay Ranker 后,您可以在搜索请求中通过将其传递给 ranker
参数来应用它:
- Python
- Java
- NodeJS
- Go
- cURL
# Apply decay ranker to restaurant vector search
result = milvus_client.search(
collection_name,
data=["italian restaurants"], # Query text
anns_field="dense", # Vector field to search
limit=10, # Number of results
output_fields=["name", "cuisine", "distance"], # Fields to return
# highlight-next-line
ranker=ranker, # Apply the decay ranker
consistency_level="Strong"
)
// java
// nodejs
// go
# restful
在混合搜索中使用
Decay Ranker 也可应用于结合多个向量字段的混合搜索操作:
- Python
- Java
- NodeJS
- Go
- cURL
from pymilvus import AnnSearchRequest
# Define dense vector search request
dense = AnnSearchRequest(
data=["italian restaurants"],
anns_field="dense",
param={},
limit=10
)
# Define sparse vector search request
sparse = AnnSearchRequest(
data=["italian restaurants"],
anns_field="sparse_vector",
param={},
limit=10
)
# Apply decay ranker to restaurant hybrid search
hybrid_results = milvus_client.hybrid_search(
collection_name,
[dense, sparse], # Multiple search requests
# highlight-next-line
ranker=ranker, # Same decay ranker
limit=10,
output_fields=["name", "cuisine", "distance"]
)
// java
// nodejs
// go
# restful
有关混合搜索操作的更多信息,请参阅多向量混合搜索。