Classement pondéré
Weighted Ranker combine et hiérarchise intelligemment les résultats de plusieurs recherches en leur attribuant des poids différents. À l'instar d'un chef cuisinier habile qui équilibre plusieurs ingrédients pour créer le plat parfait, Weighted Ranker équilibre différents résultats de recherche afin de fournir les résultats combinés les plus pertinents. Cette approche est idéale lorsque la recherche porte sur plusieurs champs vectoriels ou modalités et que certains champs doivent contribuer de manière plus significative que d'autres au classement final.
Quand utiliser Weighted Ranker ?
Weighted Ranker est spécialement conçu pour les scénarios de recherche hybride dans lesquels vous devez combiner des résultats provenant de plusieurs chemins de recherche vectorielle. Il est particulièrement efficace dans les cas suivants
Cas d'utilisation |
Exemple de cas d'utilisation |
Pourquoi Weighted Ranker fonctionne-t-il bien ? |
|---|---|---|
Recherche dans le domaine du commerce électronique |
Recherche de produits combinant la similarité des images et la description du texte |
Permet aux détaillants de donner la priorité à la similarité visuelle pour les articles de mode tout en mettant l'accent sur les descriptions textuelles pour les produits techniques. |
Recherche de contenu multimédia |
Recherche de vidéos utilisant à la fois des caractéristiques visuelles et des transcriptions audio |
Équilibre l'importance du contenu visuel par rapport au dialogue parlé en fonction de l'intention de la requête. |
Recherche de documents |
Recherche de documents d'entreprise à l'aide d'enchâssements multiples pour différentes sections |
Accorde plus d'importance au titre et au résumé tout en tenant compte du texte intégral. |
Si votre application de recherche hybride nécessite de combiner plusieurs chemins de recherche tout en contrôlant leur importance relative, Weighted Ranker est le choix idéal.
Mécanisme de Weighted Ranker
Le processus principal de la stratégie WeightedRanker est le suivant :
Collecte des scores de recherche: Rassembler les résultats et les scores de chaque chemin de recherche vectorielle (score_1, score_2).
Normalisation des scores: Chaque recherche peut utiliser des mesures de similarité différentes, ce qui se traduit par des distributions de scores variées. Par exemple, l'utilisation du produit intérieur (PI) comme type de similarité peut donner des résultats allant de [-∞,+∞], tandis que l'utilisation de la distance euclidienne (L2) donne des résultats allant de [0,+∞]. Étant donné que les scores des différentes recherches varient et ne peuvent pas être directement comparés, il est nécessaire de normaliser les scores de chaque chemin de recherche. En règle générale, la fonction
arctanest appliquée pour transformer les scores en une plage comprise entre [0 et 1] (score_1_normalisé, score_2_normalisé). Les scores plus proches de 1 indiquent une plus grande similarité.Attribuer des poids: En fonction de l'importance attribuée aux différents champs vectoriels, des poids(wi) sont attribués aux scores normalisés (score_1_normalisé, score_2_normalisé). Les poids de chaque chemin doivent être compris entre [0,1]. Les scores pondérés résultants sont score_1_pondéré et score_2_pondéré.
Fusionner les scores: Les scores pondérés (score_1_pondéré, score_2_pondéré) sont classés du plus élevé au plus bas pour produire un ensemble final de scores (score_final).
Classeur pondéré
Exemple de classificateur pondéré
Cet exemple illustre une recherche hybride multimodale (topK=5) impliquant des images et du texte et montre comment la stratégie WeightedRanker réorganise les résultats de deux recherches ANN.
Résultats de la recherche ANN sur les images (topK=5):
ID
Score (image)
101
0.92
203
0.88
150
0.85
198
0.83
175
0.8
Résultats de la recherche ANN sur les textes (topK=5):
ID
Score (texte)
198
0.91
101
0.87
110
0.85
175
0.82
250
0.78
Utilisez WeightedRanker pour attribuer des poids aux résultats de la recherche d'images et de textes. Supposons que la pondération pour la recherche d'images ANN soit de 0,6 et la pondération pour la recherche de texte de 0,4.
ID
Score (image)
Score (texte)
Score pondéré
101
0.92
0.87
0.6×0.92+0.4×0.87=0.90
203
0.88
N/A
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
Pas dans l'image
0.85
0.6×0+0.4×0.85=0.34
250
Pas dans l'image
0.78
0.6×0+0.4×0.78=0.312
Les résultats finaux après le reranking(topK=5):
Rang
ID
Score final
1
101
0.90
2
198
0.86
3
175
0.81
4
203
0.528
5
150
0.51
Utilisation du classificateur pondéré
Lors de l'utilisation de la stratégie WeightedRanker, il est nécessaire de saisir des valeurs de pondération. Le nombre de valeurs de poids à saisir doit correspondre au nombre de requêtes de recherche ANN de base dans la recherche hybride. Les valeurs de pondération doivent être comprises entre [0 et 1], les valeurs proches de 1 indiquant une plus grande importance.
Créer un classificateur pondéré
Supposons, par exemple, qu'une recherche hybride comporte deux requêtes de recherche ANN de base : une recherche de texte et une recherche d'image. Si la recherche de texte est considérée comme plus importante, il convient de lui attribuer un poids plus élevé.
Milvus 2.6.x et les versions ultérieures vous permettent de configurer les stratégies de reclassement directement via l'API Function. Si vous utilisez une version antérieure (avant v2.6.0), reportez-vous à la documentation Reranking pour les instructions de configuration.
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
Paramètres |
Nécessaire ? |
Description |
Valeur/Exemple |
|---|---|---|---|
|
Oui |
Identifiant unique pour cette fonction |
|
|
Oui |
Liste des champs vectoriels auxquels appliquer la fonction (doit être vide pour le Ranker pondéré) |
[] |
|
Oui |
Type de fonction à invoquer ; utiliser |
|
|
Oui |
Spécifie la méthode de reclassement à utiliser. La valeur |
|
|
Oui |
Tableau de poids correspondant à chaque chemin de recherche ; valeurs ∈ [0,1]. Pour plus de détails, reportez-vous à la section Mécanisme de classement pondéré. |
|
|
Non |
Normalisation ou non des scores bruts (à l'aide d'arctan) avant la pondération. Pour plus de détails, voir Mécanisme du classificateur pondéré. |
|
Application à la recherche hybride
Le classement pondéré est conçu spécifiquement pour les opérations de recherche hybride qui combinent plusieurs champs de vecteurs. Lors d'une recherche hybride, vous devez spécifier les poids pour chaque chemin de recherche :
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
Pour plus d'informations sur la recherche hybride, reportez-vous à la section Recherche hybride multi-vecteurs.