Peluruhan EksponensialCompatible with Milvus 2.6.x
Peluruhan eksponensial menciptakan penurunan awal yang curam yang diikuti dengan ekor yang panjang dalam hasil pencarian Anda. Seperti siklus berita terbaru di mana relevansi berkurang dengan cepat pada awalnya, tetapi beberapa berita tetap penting dari waktu ke waktu, peluruhan eksponensial menerapkan penalti yang tajam pada item yang berada di luar jangkauan ideal Anda, namun tetap membuat item yang jauh tetap dapat ditemukan. Pendekatan ini sangat ideal ketika Anda ingin sangat memprioritaskan kedekatan atau kemutakhiran, tetapi tidak ingin sepenuhnya menghilangkan opsi yang lebih jauh.
Tidak seperti fungsi peluruhan lainnya:
Peluruhan Gaussian menciptakan penurunan yang lebih bertahap, berbentuk lonceng
Peluruhan linier menurun dengan kecepatan konstan hingga mencapai tepat nol
Peluruhan eksponensial secara unik "membebani" penalti di depan, menerapkan sebagian besar pengurangan relevansi lebih awal sambil mempertahankan ekor panjang dengan relevansi minimal tetapi tidak nol.
Kapan menggunakan peluruhan eksponensial
Peluruhan eksponensial sangat efektif untuk:
Kasus Penggunaan |
Contoh |
Mengapa Peluruhan Eksponensial Bekerja dengan Baik |
|---|---|---|
Umpan berita |
Portal berita terkini |
Dengan cepat mengurangi relevansi berita lama sambil tetap menampilkan berita penting dari beberapa hari yang lalu |
Linimasa media sosial |
Umpan aktivitas, pembaruan status |
Menekankan konten baru tetapi memungkinkan konten lama yang viral muncul ke permukaan |
Sistem pemberitahuan |
Pemrioritasan peringatan |
Menciptakan urgensi untuk pemberitahuan terbaru sambil mempertahankan visibilitas untuk pemberitahuan yang penting |
Penjualan kilat |
Penawaran waktu terbatas |
Dengan cepat mengurangi visibilitas saat tenggat waktu semakin dekat |
Pilih peluruhan eksponensial saat:
Pengguna mengharapkan item yang sangat baru atau terdekat untuk sangat mendominasi hasil
Item yang lebih lama atau lebih jauh harus tetap dapat ditemukan jika sangat relevan
Penurunan relevansi harus bersifat front-loaded (lebih curam di awal, lebih bertahap di kemudian hari)
Prinsip penurunan yang tajam
Peluruhan eksponensial menciptakan kurva yang turun dengan cepat pada awalnya, kemudian secara bertahap mendatar menjadi ekor panjang yang mendekati tetapi tidak pernah mencapai nol. Pola matematis ini sering muncul dalam fenomena alam seperti peluruhan radioaktif, penurunan populasi, dan relevansi informasi dari waktu ke waktu.
Semua parameter waktu (origin, offset, scale) harus menggunakan satuan yang sama dengan data koleksi. Jika koleksi Anda menyimpan cap waktu dalam satuan yang berbeda (milidetik, mikrodetik), sesuaikan semua parameter yang sesuai.
Peluruhan Eksponensial
Grafik di atas menunjukkan bagaimana peluruhan eksponensial akan memengaruhi peringkat artikel berita di platform berita digital:
origin(waktu saat ini): Saat ini, di mana relevansi berada pada titik maksimum (1,0).offset(3 jam): "Jendela berita terkini"-semua berita yang diterbitkan dalam 3 jam terakhir mempertahankan nilai relevansi penuh (1,0), memastikan bahwa berita yang sangat baru tidak dihukum karena perbedaan waktu yang kecil.decay(0.5): Skor pada jarak skala-parameter ini mengontrol seberapa dramatis skor berkurang seiring waktu.scale(24 jam): Periode waktu di mana relevansi turun ke nilai peluruhan-artikel berita yang berumur tepat 24 jam memiliki skor relevansinya berkurang setengahnya (0,5).
Seperti yang dapat Anda lihat dari kurva, artikel berita yang berusia lebih dari 24 jam terus mengalami penurunan relevansi, tetapi tidak pernah mencapai nol. Bahkan berita dari beberapa hari yang lalu pun tetap memiliki relevansi minimal, sehingga berita yang penting tetapi lebih lama masih muncul di feed Anda (meskipun peringkatnya lebih rendah).
Perilaku ini meniru cara kerja relevansi berita - berita yang sangat baru sangat mendominasi, tetapi berita yang lebih lama masih bisa menerobos jika sangat relevan dengan minat pengguna.
Rumus
Rumus matematika untuk menghitung skor peluruhan eksponensial adalah:
Di mana:
Menjabarkannya dalam bahasa yang sederhana:
asal
Kurangi offset (jika ada) tetapi jangan sampai di bawah nol: .
Kalikan dengan , yang dihitung dari skala dan parameter peluruhan Anda.
Ambil eksponennya, yang memberi Anda nilai antara 0 dan 1: .
Perhitungan mengubah parameter skala dan peluruhan Anda menjadi parameter laju untuk fungsi eksponensial. Nilai yang lebih negatif akan menghasilkan penurunan awal yang lebih curam.
Gunakan peluruhan eksponensial
Peluruhan eksponensial dapat diterapkan pada pencarian vektor standar dan operasi pencarian hibrida di Milvus. Di bawah ini adalah cuplikan kode kunci untuk mengimplementasikan fitur ini.
Sebelum menggunakan fungsi peluruhan, Anda harus terlebih dahulu membuat koleksi dengan bidang numerik yang sesuai (seperti stempel waktu, jarak, dll.) yang akan digunakan untuk perhitungan peluruhan. Untuk contoh kerja lengkap termasuk penyiapan koleksi, definisi skema, dan penyisipan data, lihat Tutorial Decay Ranker.
Membuat pemeringkat peluruhan
Setelah koleksi Anda disiapkan dengan bidang numerik (dalam contoh ini, publish_time), buatlah pemeringkat peluruhan eksponensial:
Konsistensi unit waktu: Ketika menggunakan peluruhan berbasis waktu, pastikan bahwa parameter origin, scale, dan offset menggunakan satuan waktu yang sama dengan data koleksi Anda. Jika koleksi Anda menyimpan stempel waktu dalam satuan detik, gunakan satuan detik untuk semua parameter. Jika menggunakan milidetik, gunakan milidetik untuk semua parameter.
from pymilvus import Function, FunctionType
import datetime
# Create an exponential decay ranker for news recency
# Note: All time parameters must use the same unit as your collection data
ranker = Function(
name="news_recency", # Function identifier
input_field_names=["publish_time"], # Numeric field to use
function_type=FunctionType.RERANK, # Function type. Must be RERANK
params={
"reranker": "decay", # Specify decay reranker
"function": "exp", # Choose exponential decay
"origin": int(datetime.datetime.now().timestamp()), # Current time (seconds, matching collection data)
"offset": 3 * 60 * 60, # 3 hour breaking news window (seconds)
"decay": 0.5, # Half score at scale distance
"scale": 24 * 60 * 60 # 24 hours (in seconds, matching collection data)
}
)
import io.milvus.v2.service.vector.request.ranker.DecayRanker;
DecayRanker ranker = DecayRanker.builder()
.name("news_recency")
.inputFieldNames(Collections.singletonList("publish_time"))
.function("exp")
.origin(System.currentTimeMillis())
.offset(3 * 60 * 60)
.decay(0.5)
.scale(24 * 60 * 60)
.build();
import { FunctionType } from "@zilliz/milvus2-sdk-node";
const ranker = {
name: "news_recency",
input_field_names: ["publish_time"],
type: FunctionType.RERANK,
params: {
reranker: "decay",
function: "exp",
origin: new Date(2025, 1, 15).getTime(),
offset: 3 * 60 * 60,
decay: 0.5,
scale: 24 * 60 * 60,
},
};
// go
# restful
Menerapkan ke pencarian vektor standar
Setelah mendefinisikan perangking peluruhan Anda, Anda dapat menerapkannya selama operasi pencarian dengan mengopernya ke parameter 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", "publish_time"], # 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("market analysis")))
.annsField("vector_field")
.limit(10)
.outputFields(Arrays.asList("title", "publish_time"))
.functionScore(FunctionScore.builder()
.addFunction(ranker)
.build())
.consistencyLevel(ConsistencyLevel.STRONG)
.build();
SearchResp searchResp = client.search(searchReq);
import { FunctionType MilvusClient } from "@zilliz/milvus2-sdk-node";
const milvusClient = new MilvusClient("http://localhost:19530");
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", "publish_time"],
rerank: ranker,
consistency_level: "Strong",
});
// go
# restful