Classifica ponderata
Weighted Ranker combina in modo intelligente e prioritario i risultati di più percorsi di ricerca, assegnando a ciascuno di essi pesi di importanza diversi. Come un cuoco esperto bilancia più ingredienti per creare il piatto perfetto, Weighted Ranker bilancia diversi risultati di ricerca per fornire i risultati combinati più rilevanti. Questo approccio è ideale quando si effettuano ricerche in più campi vettoriali o modalità in cui alcuni campi dovrebbero contribuire in modo più significativo alla classifica finale rispetto ad altri.
Quando usare Weighted Ranker
Weighted Ranker è stato progettato specificamente per gli scenari di ricerca ibrida in cui è necessario combinare i risultati di più percorsi di ricerca vettoriale. È particolarmente efficace per:
Caso d'uso |
Esempio |
Perché Ranker ponderato funziona bene |
|---|---|---|
Ricerca nel commercio elettronico |
Ricerca di prodotti che combina la somiglianza di immagini e descrizioni testuali |
Consente ai rivenditori di dare priorità alla somiglianza visiva per gli articoli di moda, mentre enfatizza le descrizioni testuali per i prodotti tecnici. |
Ricerca di contenuti multimediali |
Recupero di video utilizzando sia le caratteristiche visive che le trascrizioni audio |
Bilancia l'importanza dei contenuti visivi rispetto al dialogo parlato, in base all'intento della query. |
Ricerca di documenti |
Ricerca di documenti aziendali con incorporazioni multiple per sezioni diverse |
Attribuisce un peso maggiore alle incorporazioni del titolo e dell'abstract, pur continuando a considerare le incorporazioni del testo completo. |
Se la vostra applicazione di ricerca ibrida richiede la combinazione di più percorsi di ricerca e il controllo della loro importanza relativa, Weighted Ranker è la scelta ideale.
Meccanismo di Weighted Ranker
Il flusso di lavoro principale della strategia WeightedRanker è il seguente:
Raccogliere i punteggi di ricerca: Raccogliere i risultati e i punteggi di ogni percorso di ricerca vettoriale (score_1, score_2).
Normalizzazione dei punteggi: Ogni ricerca può utilizzare metriche di somiglianza diverse, con conseguenti distribuzioni di punteggio diverse. Ad esempio, l'uso del prodotto interno (IP) come tipo di somiglianza può produrre punteggi che vanno da [-∞,+∞], mentre l'uso della distanza euclidea (L2) produce punteggi che vanno da [0,+∞]. Poiché i punteggi delle diverse ricerche variano e non possono essere direttamente confrontati, è necessario normalizzare i punteggi di ogni percorso di ricerca. In genere si applica la funzione
arctanper trasformare i punteggi in un intervallo compreso tra [0, 1] (score_1_normalizzato, score_2_normalizzato). I punteggi più vicini a 1 indicano una maggiore somiglianza.Assegnazione dei pesi: In base all'importanza assegnata ai diversi campi vettoriali, vengono assegnati dei pesi(wi) ai punteggi normalizzati (score_1_normalizzato, score_2_normalizzato). I pesi di ogni percorso devono essere compresi tra [0,1]. I punteggi ponderati risultanti sono score_1_pesato e score_2_pesato.
Unire i punteggi: I punteggi ponderati (score_1_pesato, score_2_pesato) vengono classificati dal più alto al più basso per produrre un insieme finale di punteggi (score_finale).
Classificatore ponderato
Esempio di classificatore ponderato
Questo esempio mostra una ricerca ibrida multimodale (topK=5) che coinvolge immagini e testo e illustra come la strategia WeightedRanker classifica i risultati di due ricerche ANN.
Risultati della ricerca ANN sulle immagini (topK=5): ID
ID
Punteggio (immagine)
101
0.92
203
0.88
150
0.85
198
0.83
175
0.8
Risultati della ricerca della RNA sui testi (topK=5):
ID
Punteggio (testo)
198
0.91
101
0.87
110
0.85
175
0.82
250
0.78
Utilizzare WeightedRanker per assegnare pesi ai risultati della ricerca per immagini e per testo. Supponiamo che il peso per la ricerca RNA di immagini sia 0,6 e il peso per la ricerca di testo sia 0,4.
ID
Punteggio (immagine)
Punteggio (testo)
Punteggio ponderato
101
0.92
0.87
0.6×0.92+0.4×0.87=0.90
203
0.88
N/D
0.6×0.88+0.4×0=0.528
150
0.85
N/A
0.6×0.85+0.4×0=0.51
198
0.83
0.91
0.6×0.83+0.4×0.91=0.86
175
0.80
0.82
0.6×0.80+0.4×0.82=0.81
110
Non nell'immagine
0.85
0.6×0+0.4×0.85=0.34
250
Non nell'immagine
0.78
0.6×0+0.4×0.78=0.312
I risultati finali dopo la riclassificazione (topK=5)
Classifica
ID
Punteggio finale
1
101
0.90
2
198
0.86
3
175
0.81
4
203
0.528
5
150
0.51
Utilizzo di Weighted Ranker
Quando si utilizza la strategia WeightedRanker, è necessario inserire i valori dei pesi. Il numero di valori di peso da inserire deve corrispondere al numero di richieste di ricerca della RNA di base nella Ricerca ibrida. I valori dei pesi inseriti devono rientrare nell'intervallo [0,1], con valori più vicini a 1 che indicano una maggiore importanza.
Creare un classificatore ponderato
Ad esempio, supponiamo che in una ricerca ibrida vi siano due richieste di ricerca ANN di base: ricerca di testo e ricerca di immagini. Se la ricerca di testo è considerata più importante, ad essa dovrebbe essere assegnato un peso maggiore.
Milvus 2.6.x e successive consentono di configurare le strategie di reranking direttamente tramite l'API Function. Se si utilizza una versione precedente (prima della v2.6.0), consultare la documentazione sul reranking per le istruzioni di configurazione.
from pymilvus import Function, FunctionType
rerank = Function(
name="weight",
input_field_names=[], # Must be an empty list
function_type=FunctionType.RERANK,
params={
"reranker": "weighted",
"weights": [0.1, 0.9],
"norm_score": True # Optional
}
)
import io.milvus.common.clientenum.FunctionType;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
CreateCollectionReq.Function rerank = CreateCollectionReq.Function.builder()
.name("weight")
.functionType(FunctionType.RERANK)
.param("reranker", "weighted")
.param("weights", "[0.1, 0.9]")
.param("norm_score", "true")
.build();
import { FunctionType } from '@zilliz/milvus2-sdk-node';
const rerank = {
name: "weight",
input_field_names: [],
function_type: FunctionType.RERANK,
params: {
reranker: "weighted",
weights: [0.1, 0.9],
norm_score: true
}
};
// Go
# Restful
Parametro |
Richiesto? |
Descrizione |
Valore/Esempio |
|---|---|---|---|
|
Sì |
Identificatore univoco per questa funzione |
|
|
Sì |
Elenco di campi vettoriali a cui applicare la funzione (deve essere vuoto per Weighted Ranker) |
[] |
|
Sì |
Il tipo di Funzione da invocare; utilizzare |
|
|
Sì |
Specifica il metodo di reranking da utilizzare. Deve essere impostato su |
|
|
Sì |
Array di pesi corrispondenti a ciascun percorso di ricerca; valori ∈ [0,1]. Per i dettagli, fare riferimento a Meccanismo del Ranker ponderato. |
|
|
No |
Normalizzazione dei punteggi grezzi (tramite arctan) prima della ponderazione. Per i dettagli, vedere Meccanismo del classificatore ponderato. |
|
Applicare alla ricerca ibrida
Weighted Ranker è stato progettato specificamente per le operazioni di ricerca ibrida che combinano più campi vettoriali. Quando si esegue una ricerca ibrida, è necessario specificare i pesi per ogni percorso di ricerca:
from pymilvus import MilvusClient, AnnSearchRequest
# Connect to Milvus server
milvus_client = MilvusClient(uri="http://localhost:19530")
# Assume you have a collection setup
# Define text vector search request
text_search = AnnSearchRequest(
data=["modern dining table"],
anns_field="text_vector",
param={},
limit=10
)
# Define image vector search request
image_search = AnnSearchRequest(
data=[image_embedding], # Image embedding vector
anns_field="image_vector",
param={},
limit=10
)
# Apply Weighted Ranker to product hybrid search
# Text search has 0.8 weight, image search has 0.3 weight
hybrid_results = milvus_client.hybrid_search(
collection_name,
[text_search, image_search], # Multiple search requests
ranker=rerank, # Apply the weighted ranker
limit=10,
output_fields=["product_name", "price", "category"]
)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.AnnSearchReq;
import io.milvus.v2.service.vector.request.HybridSearchReq;
import io.milvus.v2.service.vector.response.SearchResp;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
import io.milvus.v2.service.vector.request.data.FloatVec;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("http://localhost:19530")
.build());
List<AnnSearchReq> searchRequests = new ArrayList<>();
searchRequests.add(AnnSearchReq.builder()
.vectorFieldName("text_vector")
.vectors(Collections.singletonList(new EmbeddedText("\"modern dining table\"")))
.limit(10)
.build());
searchRequests.add(AnnSearchReq.builder()
.vectorFieldName("image_vector")
.vectors(Collections.singletonList(new FloatVec(imageEmbedding)))
.limit(10)
.build());
HybridSearchReq hybridSearchReq = HybridSearchReq.builder()
.collectionName(COLLECTION_NAME)
.searchRequests(searchRequests)
.ranker(ranker)
.limit(10)
.outputFields(Arrays.asList("product_name", "price", "category"))
.build();
SearchResp searchResp = client.hybridSearch(hybridSearchReq);
import { MilvusClient, FunctionType } from "@zilliz/milvus2-sdk-node";
const milvusClient = new MilvusClient({ address: "http://localhost:19530" });
const text_search = {
data: ["modern dining table"],
anns_field: "text_vector",
param: {},
limit: 10,
};
const image_search = {
data: [image_embedding],
anns_field: "image_vector",
param: {},
limit: 10,
};
const rerank = {
name: "weight",
input_field_names: [],
function_type: FunctionType.RERANK,
params: {
reranker: "weighted",
weights: [0.1, 0.9],
norm_score: true,
},
};
const search = await milvusClient.search({
collection_name: collection_name,
limit: 10,
data: [text_search, image_search],
rerank: rerank,
output_fields = ["product_name", "price", "category"],
});
// go
# restful
Per ulteriori informazioni sulla ricerca ibrida, consultare la sezione Ricerca ibrida multivettoriale.