高斯衰減Compatible with Milvus 2.6.x

高斯衰減 (Gaussian Decay) 也稱為正常衰減 (normal decay),會對搜尋結果進行最自然的調整。就像人類的視力會隨著距離逐漸模糊一樣,高斯遞減創造了一個平滑的鐘形曲線,當項目離您的理想點越遠時,相關性就會逐漸降低。當您想要一個平衡的衰減,既不會嚴重懲罰超出您偏好範圍的項目,又能顯著降低遙遠項目的相關性時,這種方法是最理想的選擇。

與其他衰減排名器不同:

  • 指數衰減一開始會急速下降,產生較強的初始懲罰。

  • 線性衰減以固定速率遞減,直到達到零,創造一個明確的分界線

高斯遞減提供了更平衡、更直觀的方法,讓使用者感覺更自然。

何時使用高斯遞減

高斯衰減對以下情況特別有效

使用個案

範例

為什麼高斯效果好

基於位置的搜尋

餐廳搜尋器、商店定位器

模擬人類對距離相關性的自然感知

內容推薦

根據出版日期提供文章建議

隨著內容老化,相關性逐漸下降

產品清單

價格接近目標的商品

當價格偏離目標時,相關性平滑下降

專業知識匹配

尋找具有相關經驗的專業人士

經驗相關性的平衡評估

如果您的應用程式需要相關性自然下降的感覺,而不需要嚴苛的懲罰或嚴格的截止值,高斯衰減可能是您的最佳選擇。

貝爾曲線原理

高斯衰減會產生平滑的鐘形曲線,隨著與理想點的距離增加,相關性也會逐漸降低。此分佈以數學家 Carl Friedrich Gauss 命名,經常出現在自然界和統計學中,這也解釋了為什麼人類對它的感覺如此直覺。

Gaussian Decay 高斯衰減

上圖顯示高斯衰減如何影響行動搜尋應用程式中的餐廳排名:

  • origin (0 km):您目前的位置,相關性最高 (1.0)。

  • offset (±300 m):您周圍的 「滿分區」-300 公尺內的所有餐廳都維持完整的相關性評分 (1.0),確保附近的選項不會因為微小的距離差異而受到不必要的懲罰。

  • scale (±2 公里):相關度降至衰減值的距離 - 距離正好 2 公里的餐廳,其相關度分數會減半 (0.5)。

  • decay (0.5):尺度距離上的分數-此參數基本上控制分數隨距離遞減的速度。

從曲線可以看出,2 公里以外的餐廳相關度持續降低,但永遠不會達到零。即使是 4-5 公里外的餐廳,也會保留一些最低限度的相關性,讓優秀但距離較遠的餐廳仍然出現在您的結果中(儘管排名較低)。

這種行為模仿了人們對距離相關性的自然思考方式--鄰近的地方是首選,但我們願意為了特殊的選擇而走得更遠。

計算公式

計算高斯衰減分數的數學公式如下:

S(doc)=exp((max(0,fieldvaluedocoriginoffset))22σ2)S(doc) = \exp\left( -\frac{\left( \max\left(0, \left|fieldvalue_{doc} - origin\right| - offset \right) \right)^2}{2\sigma^2} \right)

其中:

σ2=scale22ln(decay)\sigma^2 = -\frac{scale^2}{2 \cdot \ln(decay)}

以簡明的語言分解:

  1. 計算欄位值離原點的距離:∣fieldvaluedoc-origin∣|fieldvalue_{doc} - origin|

  2. 減去偏移量(如果有),但永遠不低於零:max(0,distance-offset)\max(0, distance - offset)

  3. 將此調整後的距離平方:(adjusted_distance)2(adjusted\_distance)^2 2

  4. 除以2σ22\sigma^2 2,這是根據您的比例和衰減參數計算出來的

  5. 取負指數,得到介於 0 和 1 之間的值:exp(-value)\exp(-)-value

σ2\sigma^{2}σ

使用高斯衰減

在 Milvus 中,高斯衰減可應用於標準向量搜尋和混合搜尋運算。以下是實現此功能的關鍵程式碼片段。

在使用衰減函數之前,您必須先建立一個具有適當數值欄位 (如時間戳記、距離等) 的集合,這些欄位將用於衰減計算。如需完整的工作範例,包括集合設定、模式定義和資料插入,請參閱教學:在 Milvus 中實施以時間為基礎的排名

建立衰減排名器

在您的集合設定了數值欄位 (在本範例中,distance ,單位為距離使用者的公尺)之後,請建立一個高斯衰減排名器:

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)
    }
)
import io.milvus.v2.service.vector.request.ranker.DecayRanker;

DecayRanker ranker = DecayRanker.builder()
        .name("restaurant_distance_decay")
        .inputFieldNames(Collections.singletonList("distance"))
        .function("gauss")
        .origin(0)
        .offset(300)
        .decay(0.5)
        .scale(2000)
        .build();
import { FunctionType } from "@zilliz/milvus2-sdk-node";

const ranker = {
  name: "restaurant_distance_decay",
  input_field_names: ["distance"],
  function_type: FunctionType.RERANK,
  params: {
    reranker: "decay",
    function: "gauss",
    origin: 0,
    offset: 300,
    decay: 0.5,
    scale: 2000,
  },
};

// go
# restful

定義衰減排位器之後,您可以將它傳給ranker 參數,在搜尋作業中應用它:

# Apply decay ranker to restaurant vector search
result = milvus_client.search(
    collection_name,
    data=[your_query_vector],         # Replace with your query vector
    anns_field="dense",                   # Vector field to search
    limit=10,                             # Number of results
    output_fields=["name", "cuisine", "distance"],  # Fields to return
    ranker=ranker,                        # Apply the decay ranker
    consistency_level="Strong"
)
import io.milvus.v2.common.ConsistencyLevel;
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("italian restaurants")))
        .annsField("vector_field")
        .limit(10)
        .outputFields(Arrays.asList("name", "cuisine", "distance"))
        .functionScore(FunctionScore.builder()
                .addFunction(ranker)
                .build())
        .consistencyLevel(ConsistencyLevel.STRONG)
        .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: ["name", "cuisine", "distance"],
  rerank: ranker,
  consistency_level: "Strong",
});
// go
# restful

免費嘗試托管的 Milvus

Zilliz Cloud 無縫接入,由 Milvus 提供動力,速度提升 10 倍。

開始使用
反饋

這個頁面有幫助嗎?