Decay Ranker 總覽Compatible with Milvus 2.6.x
在傳統的向量搜尋中,搜尋結果的排序純粹取決於向量的相似性-向量在數學空間中的匹配程度。但在現實世界的應用中,內容是否真正相關往往不只取決於語意相似度。
請考慮這些日常情境:
在新聞搜尋中,昨天的文章應該比三年前的類似文章排名更高
餐廳搜尋器會優先搜尋 5 分鐘車程內的餐廳,而非 30 分鐘車程內的餐廳
一個電子商務平台,能提升趨勢商品的排名,即使這些商品與搜尋查詢的相似度稍低。
這些情境都有一個共同的需求:平衡向量相似度與其他數值因素,例如時間、距離或知名度。
Milvus 的 Decay rankers 可根據數值字段值調整搜尋排名,從而滿足此需求。它們可讓您平衡向量相似性與資料的「新鮮度」、「接近度」或其他數值屬性,創造更直覺且與上下文相關的搜尋體驗。
使用注意事項
衰減排名不能用於群組搜尋。
用於衰減排名的欄位必須是數值 (
INT8,INT16,INT32,INT64,FLOAT, 或DOUBLE)。每個衰減排名只能使用一個數值欄位。
時間單位一致性:使用以時間為基礎的衰減排名時,
origin,scale, 和offset參數的單位必須與您的收集資料中使用的單位相符:如果您的資料集以秒為單位儲存時間戳記,請對所有參數使用秒。
如果您的資料集以毫秒為單位儲存時間戳記,則所有參數都使用毫秒。
如果您的集合以微秒為單位儲存時間戳記,則所有參數均使用微秒。
如何運作
衰減排序將時間或地理距離等數字因素納入排序過程中,增強了傳統向量搜尋的功能。整個過程遵循以下幾個階段
第一階段:計算標準化的相似性分數
首先,Milvus 會計算向量相似性分數並加以規範化,以確保比較結果一致:
對於L2和JACCARD距離指標 (較低的值表示較高的相似性):
normalized_score = 1.0 - (2 × arctan(score))/π這將距離轉換成 0-1 之間的相似性分數,越高越好。
對於IP、COSINE 和BM25公約 (分數越高表示匹配度越高):直接使用分數,無需標準化。
第二階段:計算衰減分數
接下來,Milvus 會根據數值字段值 (如時間戳記或距離),使用您選擇的衰減排名器計算衰減得分:
每個衰減排名器將原始數值轉換為 0-1 之間的規範化相關性分數。
衰減分數會根據項目與理想點的「距離」來表示其相關程度
具體的計算公式根據衰減排名器類型而有所不同。有關如何計算衰減分數的詳細資訊,請參閱高斯衰減、指數衰減、線性衰減的專用頁面。
第三階段:計算最終得分
最後,Milvus 結合規範化的相似度得分和衰減得分,產生最終的排名得分:
final_score = normalized_similarity_score × decay_score
在混合搜尋 (結合多向量領域) 的情況下,Milvus 取搜尋請求中最大的歸一化相似度得分:
final_score = max([normalized_score₁, normalized_score₂, ..., normalized_scoreₙ]) × decay_score
例如,在混合搜尋中,如果一篇研究論文的向量相似度得分為 0.82,而以 BM25 為基礎的文字檢索得分為 0.91,Milvus 會先使用 0.91 作為基本相似度得分,然後再套用衰減因子。
衰減排序的實際應用
讓我們來看看衰減排序在實際情境中的應用-以時間為基礎的衰減來搜尋「AI 研究論文」:
在這個範例中,衰減分數反映出相關性會隨著時間遞減-較新的論文會得到較接近 1.0 的分數,較舊的論文則會得到較低的分數。這些值是使用特定的衰減排名器計算出來的。如需詳細資訊,請參閱Choose the right decay ranker。
論文 |
向量相似度 |
標準化相似度得分 |
發表日期 |
衰減分數 |
最終得分 |
最終排名 |
|---|---|---|---|---|---|---|
論文 A |
高分數 |
0.85 ( |
2 週前 |
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 |
如果不進行衰變重排,根據純向量相似度 (0.92) 計算,論文 B 的排名最高。但是,如果使用衰減重排:
儘管相似度中等,論文 C 躍升至第 1 位,因為它是最近發表的論文 (昨天發表)。
儘管相似性極佳,論文 B 卻因為相對較舊而降到第 3 位。
論文 D 使用 L2 距離 (越低越好),因此在應用衰減之前,其分數從 1.2 正態化為 0.76。
選擇正確的衰減排名器
Milvus 提供不同的衰減排名器 -gauss,exp,linear, 每種排名器都是針對特定的使用情況而設計的:
衰減排名器 |
特性 |
理想用例 |
範例情境 |
|---|---|---|---|
高斯 ( |
自然感覺的漸進式下降,適度延伸 |
|
在餐廳搜尋中,3 公里外的優質餐廳仍可被發現,儘管排序低於附近的選擇 |
指數 ( |
一開始快速下降,但會保持長尾 |
|
在新聞應用程式中,昨天的新聞排名遠高於一周前的內容,但高度相關的舊文章仍會出現 |
線性 ( |
持續、可預測的下降,且有明確的分界線 |
|
在事件搜尋器中,超過兩週未來視窗的事件根本不會出現 |
有關每個衰減排名器如何計算分數和特定衰減模式的詳細資訊,請參閱專用文件:
實施範例
衰減排名器可以應用在 Milvus 的標準向量搜尋和混合搜尋運算。以下是實現此功能的主要程式碼片段。
在使用衰減函數之前,您必須先建立一個具有適當數值欄位 (如時間戳記、距離等) 的集合,這些欄位將用於衰減計算。如需完整的工作範例,包括集合設定、模式定義和資料插入,請參閱教學:在 Milvus 中實施以時間為基礎的排名。
建立衰減排名器
要實現衰減排名,首先要定義一個具有適當配置的Function 物件:
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
}
)
import io.milvus.v2.service.vector.request.ranker.DecayRanker;
import java.time.ZoneId;
import java.time.ZonedDateTime;
ZonedDateTime zdt = ZonedDateTime.of(2025, 1, 25, 0, 0, 0, 0, ZoneId.systemDefault());
DecayRanker ranker = DecayRanker.builder()
.name("time_decay")
.inputFieldNames(Collections.singletonList("timestamp"))
.function("gauss")
.origin(zdt.toInstant().toEpochMilli())
.scale(7 * 24 * 60 * 60)
.offset(24 * 60 * 60)
.decay(0.5)
.build();
import {FunctionType } from "@zilliz/milvus2-sdk-node";
const decayRanker = {
name: "time_decay",
input_field_names: ["timestamp"],
function_type: FunctionType.RERANK,
params: {
reranker: "decay",
function: "gauss",
origin: new Date(2025, 1, 15).getTime(),
scale: 7 * 24 * 60 * 60,
offset: 24 * 60 * 60,
decay: 0.5,
},
};
// go
# restful
參數 |
需要嗎? |
說明 |
值/範例 |
|---|---|---|---|
|
是 |
執行搜尋時使用的功能識別碼。請選擇與您的使用情況相關的描述性名稱。 |
|
|
是 |
用於計算衰減分數的數字欄位。決定哪個資料屬性將用於計算衰減(例如,時間戳記用於基於時間的衰減,坐標用於基於位置的衰減)。 必須是您的資料集中包含相關數值的欄位。支援 INT8/16/32/64、FLOAT、DOUBLE。 |
|
|
是 |
指定正在建立的函數類型。 必須設定為 |
|
|
是 |
指定要使用的排名方法。 必須設定為 |
|
|
是 |
指定要應用的數學衰減排名器。決定相關性下降的曲線形狀。 |
|
|
是 |
計算衰減分數的參考點。處於此值的項目可獲得最大相關性得分。 對於以時間為基礎的遞減,時間單位必須符合您的收集資料。 |
|
|
是 |
相關性下降到 對於以時間為基礎的遞減,時間單位必須符合您的收集資料。 較大的值會使相關性逐漸下降;較小的值則會使相關性急速下降。 |
|
|
無 |
在 對於以時間為基礎的衰減,時間單位必須符合您的收集資料。
|
|
|
無 |
必須介於 0 和 1 之間。 |
|
套用至標準向量搜尋
定義衰退排序器之後,您可以將它傳給ranker 參數,在搜尋作業時套用:
# Use the decay function in standard vector search
results = milvus_client.search(
collection_name,
data=[your_query_vector], # Replace with your query vector
anns_field="vector_field",
limit=10,
output_fields=["document", "timestamp"], # Include the decay field in outputs to see values
ranker=decay_ranker, # Apply the decay ranker here
consistency_level="Strong"
)
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.response.SearchResp;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
SearchReq searchReq = SearchReq.builder()
.collectionName(COLLECTION_NAME)
.data(Collections.singletonList(new EmbeddedText("search query")))
.annsField("vector_field")
.limit(10)
.outputFields(Arrays.asList("document", "timestamp"))
.functionScore(FunctionScore.builder()
.addFunction(ranker)
.build())
.build();
SearchResp searchResp = client.search(searchReq);
const result = await milvusClient.search({
collection_name: "collection_name",
data: [your_query_vector], // Replace with your query vector
anns_field: "dense",
limit: 10,
output_fields: ["document", "timestamp"],
rerank: ranker,
consistency_level: "Strong",
});
// go
# restful