線形減衰Compatible with Milvus 2.6.x
線形減衰は、検索結果の絶対的なゼロポイントで終了する直線的な減少を作成します。イベントが過ぎ去るまで関連性が徐々に薄れていくイベントのカウントダウンのように、リニア減衰はアイテムが完全に消えるまで、理想的なポイントから遠ざかるにつれて予測可能で着実な関連性の減少を適用します。このアプローチは、特定の境界を超えたアイテムが結果から完全に除外されるように、明確なカットオフで一貫した減衰率を求める場合に最適です。
他の減衰関数とは異なります:
ガウス減衰は、徐々にゼロに近づくが決してゼロにはならないベル曲線に従います。
指数関数的減衰は、最小限の関連性のロングテールを維持し、無限に広がります。
線形減衰は、明確な終点を独自に作成するため、自然な境界や期限があるアプリケーションに特に効果的です。
リニアディケイを使用する場合
リニア減衰は特に次のような場合に効果的です:
使用例 |
使用例 |
リニアが効果的な理由 |
|---|---|---|
イベントリスト |
コンサートチケットのプラットフォーム |
遠すぎる未来のイベントに対する明確なカットオフを作成します。 |
期間限定オファー |
フラッシュセール、プロモーション |
期限切れや期限間近のオファーが表示されないようにします。 |
配達範囲 |
フードデリバリー、宅配サービス |
厳しい地理的境界を強制 |
年齢制限コンテンツ |
出会い系プラットフォーム、メディアサービス |
年齢のしきい値の設定 |
次のような場合にリニアディケイを選択します:
アプリケーションに自然な境界、期限、しきい値がある場合
あるポイントを超えたアイテムは、結果から完全に除外する必要がある。
予測可能で一貫した関連性の低下率が必要な場合。
関連性のある項目と関連性のない項目を明確に区別する必要がある。
安定した減少の原則
線形減衰は、正確にゼロに達するまで一定の割合で減少する直線的なドロップを作成します。このパターンは、カウントダウンタイマー、在庫の枯渇、関連性に明確な期限がある期限アプローチなど、多くの日常的なシナリオに現れる。
すべての時間パラメータ (origin,offset,scale) は、コレクションデータと同じ単位を使用する必要があります。コレクションが異なる単位(ミリ秒、マイクロ秒)でタイムスタンプを保存する場合、それに応じてすべてのパラメータを調整します。
線形減衰
上のグラフは、線形減衰がチケット販売プラットフォームのイベントリストにどのように影響するかを示しています:
origin(現在の日付):現在の日付):関連性が最大(1.0)になる現在。offset(1日):(1日): "直近のイベントウィンドウ"-翌日以内に開催されるすべてのイベントは、関連性のスコア(1.0)を維持し、非常に差し迫ったイベントがわずかな時間差でペナルティを受けないようにします。decay(0.5):このパラメータは関連性の低下率をコントロールします。scale(10日):関連性が減衰値まで低下する期間。10日先のイベントの関連性スコアは半分(0.5)になる。
直線カーブからわかるように、約16日以上先のイベントは関連性が完全にゼロとなり、検索結果にまったく表示されなくなります。これは、ユーザーが定義された時間ウィンドウ内で関連する今後のイベントのみを見ることを保証する明確な境界線を作成します。
この動作は、イベントプランニングの一般的な仕組みを反映したもので、直近のイベントは最も関連性が高く、今後数週間のイベントは重要性が低下し、あまりにも未来の(またはすでに過去の)イベントはまったく表示されないはずです。
計算式
線形減衰スコアの計算式は以下の通りです:
となる:
これをわかりやすく説明すると
フィールド値が原点からどれだけ離れているかを計算: オフセット(もしあれば)を引く。
オフセット(もしあれば)を引くが、ゼロ以下にはならない:
パラメータs をスケールとディケイ値から決定する。
調整した距離をs から引き、s で割る。
結果がゼロ以下にならないようにする:0
s の計算は、スケールとディケイパラメータをスコアがゼロになるポイントに変換します。例えば、decay=0.5、scale=7 の場合、distance=14(scale の 2 倍)でスコアはちょうどゼロになります。
リニアディケイを使用する
リニアディケイはmilvusの標準的なベクトルサーチとハイブリッドサーチの両方に適用することができます。以下にこの機能を実装するための主要なコードスニペットを示します。
減衰関数を使用する前に、まず減衰計算に使用する適切な数値フィールド(タイムスタンプ、距離など)を持つコレクションを作成する必要があります。コレクションのセットアップ、スキーマ定義、データ挿入を含む完全な作業例については、ディケイランカーチュートリアルを参照してください。
ディケイランカーの作成
コレクションに数値フィールド(この例では、event_date as seconds from now)を設定したら、線形ディケイランカーを作成します:
時間単位の一貫性時間ベースのディケイを使用する場合、origin 、scale 、offset パラメータがコレクションデータと同じ時間単位を使用していることを確認します。コレクションがタイムスタンプを秒単位で保存する場合、すべてのパラメータに秒を使用します。ミリ秒を使用する場合は、すべてのパラメータにミリ秒を使用する。
from pymilvus import Function, FunctionType
import time
# Calculate current time
current_time = int(time.time())
# Create a linear decay ranker for event listings
# Note: All time parameters must use the same unit as your collection data
ranker = Function(
name="event_relevance", # Function identifier
input_field_names=["event_date"], # Numeric field to use
function_type=FunctionType.RERANK, # Function type. Must be RERANK
params={
"reranker": "decay", # Specify decay reranker
"function": "linear", # Choose linear decay
"origin": current_time, # Current time (seconds, matching collection data)
"offset": 12 * 60 * 60, # 12 hour immediate events window (seconds)
"decay": 0.5, # Half score at scale distance
"scale": 7 * 24 * 60 * 60 # 7 days (in seconds, matching collection data)
}
)
import io.milvus.v2.service.vector.request.ranker.DecayRanker;
DecayRanker ranker = DecayRanker.builder()
.name("event_relevance")
.inputFieldNames(Collections.singletonList("event_date"))
.function("linear")
.origin(System.currentTimeMillis())
.offset(12 * 60 * 60)
.decay(0.5)
.scale(7 * 24 * 60 * 60)
.build();
import { FunctionType } from "@zilliz/milvus2-sdk-node";
const ranker = {
name: "event_relevance",
input_field_names: ["event_date"],
type: FunctionType.RERANK,
params: {
reranker: "decay",
function: "linear",
origin: new Date(2025, 1, 15).getTime(),
offset: 12 * 60 * 60,
decay: 0.5,
scale: 7 * 24 * 60 * 60,
},
};
// go
# restful
標準ベクトル検索への適用
減衰ランカーを定義した後、ranker パラメータに渡すことで、検索操作中に適用できます:
# Apply decay ranker to 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=["title", "venue", "event_date"], # 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.FloatVec;
SearchReq searchReq = SearchReq.builder()
.collectionName(COLLECTION_NAME)
.data(Collections.singletonList(new FloatVec(embedding)))
.annsField("dense")
.limit(10)
.outputFields(Arrays.asList("title", "venue", "event_date"))
.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: ["title", "venue", "event_date"],
rerank: ranker,
consistency_level: "Strong",
});
// go
# restful