ガウシアンディケイCompatible with Milvus 2.6.x
通常の減衰としても知られるガウス減衰は、検索結果を最も自然な感じに調整します。距離によって徐々にぼやけていく人間の視覚のように、ガウス減衰はアイテムが理想的なポイントから遠ざかるにつれて関連性が緩やかに減少する、滑らかな釣鐘型の曲線を作成します。このアプローチは、好みの範囲外のアイテムに厳しいペナルティを与えず、それでも遠くのアイテムの関連性を大幅に下げる、バランスの取れた減衰を望む場合に理想的です。
他のディケイランカーとは異なります:
指数関数的減衰は、最初に急激に減少し、より強い初期ペナルティを生み出します。
線形減衰は、ゼロに達するまで一定の割合で減少し、明確なカットオフを作成します。
ガウス減衰は、よりバランスの取れた直感的なアプローチを提供し、ユーザーにとって自然に感じられます。
ガウス減衰を使用する場合
ガウス減衰は特に以下のような場合に効果的です:
使用例 |
使用例 |
ガウシアンが効果的な理由 |
|---|---|---|
ロケーションベースの検索 |
レストラン検索、店舗検索 |
距離の関連性に関する人間の自然な知覚を模倣 |
コンテンツ推薦 |
出版日に基づく記事の提案 |
コンテンツが古くなるにつれ、関連性が徐々に低下 |
商品リスト |
ターゲットに近い価格の商品 |
価格がターゲットから乖離するにつれて、関連性がスムーズに低下 |
専門知識のマッチング |
関連する経験を持つ専門家の検索 |
経験の関連性をバランスよく評価 |
厳しいペナルティや厳格なカットオフなしに、関連性が自然に低下していく感覚を必要とするアプリケーションには、ガウス減衰が最適です。
ベル曲線の原理
ガウス減衰は、理想的な点からの距離が長くなるにつれて関連性が徐々に低下する、滑らかなベル型の曲線を描きます。数学者カール・フリードリッヒ・ガウスにちなんで名付けられたこの分布は、自然界や統計学に頻繁に登場し、人間の知覚に直感的に感じられる理由にもなっています。
ガウスの減衰
上のグラフは、ガウス減衰がモバイル検索アプリのレストランランキングにどのような影響を与えるかを示している:
origin(0 km):(0km):現在地、関連性が最大(1.0)。offset(±300 m):(±300m):あなたの周囲にある「満点ゾーン」。300m以内のレストランはすべて関連性の満点(1.0)を維持し、ごく近くの選択肢がわずかな距離の違いで不必要なペナルティを受けることはありません。scale(±2 km):ちょうど2キロメートル離れたレストランは、関連性スコアが半分(0.5)になります。decay(0.5):スケール距離でのスコア-このパラメータは基本的に距離によってスコアがどの程度早く減少するかをコントロールする。
曲線からわかるように、2キロを超えたレストランは関連性が下がり続けますが、ゼロになることはありません。4-5キロ離れたレストランでさえ、最低限の関連性を維持し、素晴らしいが遠いレストランが(ランクは低いものの)結果に表示されることを可能にしています。
この行動は、人々が距離の関連性について自然に考える方法を模倣しています-近くの場所が好まれますが、私たちは例外的なオプションのために遠くまで行くことをいとわないのです。
計算式
ガウス減衰スコアの計算式は以下の通りです:
ここで
これをわかりやすく説明すると
フィールド値が原点からどれだけ離れているかを計算: オフセットを引く。
オフセット(もしあれば)を引くが、ゼロ以下にはならない:
この調整距離を2乗する: 2
スケールと減衰パラメータから計算される 2で割る。
負の指数をとり、0と1の間の値を得る:
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