Partager via


Pertinence dans la recherche vectorielle

Pendant l’exécution d’une requête vectorielle, le moteur recherche des vecteurs similaires pour trouver les meilleurs candidats à retourner dans les résultats de la recherche. Selon la manière dont vous avez indexé le contenu vectoriel, la recherche des correspondances pertinentes est exhaustive ou limitée aux voisins les plus proches pour un traitement plus rapide. Une fois les candidats trouvés, des métriques de similarité sont utilisées pour évaluer chaque résultat en fonction de la force de la correspondance.

Cet article explique les algorithmes utilisés pour trouver les correspondances pertinentes et les métriques de similarité utilisées pour le scoring. Il contient également des conseils pour améliorer la pertinence si les résultats de la recherche ne répondent pas aux attentes.

Les algorithmes de recherche vectorielle sont les suivants :

Seuls les champs vectoriels marqués comme searchable dans l’index ou searchFields dans la requête sont utilisés pour la recherche et le scoring.

À propos de l'exhaustivité de KNN

L’algorithme KNN exhaustif calcule les distances entre toutes les paires de points de données et recherche les plus proches voisins k exacts pour un point de requête. Étant donné que l’algorithme ne nécessite pas d’accès aléatoire rapide aux points de données, KNN ne consomme pas de quota de taille d’index vectoriel . Toutefois, il fournit l’ensemble global des voisins les plus proches.

Le KNN exhaustif est gourmand en calcul, donc utilisez-le pour les jeux de données de petite à moyenne taille ou lorsque la précision dépasse la nécessité de performances des requêtes. Un autre cas d'utilisation consiste à créer un ensemble de données pour évaluer le rappel d'un algorithme ANN, car un KNN exhaustif peut être utilisé pour créer l'ensemble de vérité fondamentale des voisins les plus proches.

À propos de HNSW

HNSW est un algorithme ANN optimisé pour les applications à haute rappel et faible latence avec une distribution de données inconnue ou volatile. Lors de l’indexation, HNSW crée des structures de données supplémentaires qui organisent les points de données dans un graphique hiérarchique. Pendant l’exécution de la requête, HNSW navigue dans ce graphique pour trouver les correspondances les plus pertinentes, ce qui permet d’effectuer des recherches de voisins les plus efficaces.

HNSW nécessite que tous les points de données résident en mémoire pour un accès aléatoire rapide, qui consomme le quota de taille d’index vectoriel . Cette conception équilibre la précision de la recherche avec une efficacité de calcul et rend HNSW adapté à la plupart des scénarios, en particulier lors de la recherche sur des jeux de données plus volumineux.

HNSW offre plusieurs paramètres de configuration paramétrables pour optimiser le débit, la latence et le rappel de votre application de recherche. Par exemple, les champs qui spécifient HNSW prennent également en charge le KNN exhaustif à l'aide du paramètre de requête de requête"exhaustive": true. Toutefois, les champs indexés pour exhaustiveKnn ne prennent pas en charge les requêtes HNSW, car les structures de données supplémentaires qui permettent une recherche efficace n’existent pas.

À propos d’ANN

ANN est une classe d’algorithmes permettant de rechercher des correspondances dans l’espace vectoriel. Cette classe d’algorithmes utilise différentes structures de données ou méthodes de partitionnement de données pour réduire considérablement l’espace de recherche et accélérer le traitement des requêtes.

Les algorithmes ANN sacrifient une certaine précision, mais offrent une récupération évolutive et plus rapide des voisins les plus proches, ce qui les rend idéales pour équilibrer la précision et l’efficacité dans les applications de récupération d’informations modernes. Vous pouvez ajuster les paramètres de votre algorithme afin d'affiner les exigences de votre application de recherche en matière de rappel, de latence, de mémoire et d'empreinte disque.

Recherche Azure AI utilise HNSW pour son algorithme ANN.

Fonctionnement de la recherche du plus proche voisin

Les requêtes vectorielles s’exécutent sur un espace d’incorporation composé de vecteurs générés à partir du même modèle d’incorporation. En règle générale, la valeur d’entrée dans une demande de requête est transmise au même modèle Machine Learning que celui qui a généré des incorporations dans l’index vectoriel. La sortie est un vecteur dans le même espace d’incorporation. Étant donné que les vecteurs similaires sont regroupés dans un même cluster, la recherche de correspondances équivaut à rechercher les vecteurs les plus proches du vecteur de requête et à renvoyer les documents associés comme résultat de recherche.

Par exemple, si une demande de requête concerne des hôtels, le modèle mappe la requête à un vecteur existant dans un emplacement du cluster de vecteurs qui représente des documents sur les hôtels. L’identification des vecteurs qui sont les plus similaires à la requête, en fonction d’une métrique de similarité, détermine les documents qui sont les plus pertinents.

Quand les champs vectoriels sont indexés pour un algorithme KNN exhaustif, la requête s’exécute sur « tous les voisins ». En ce qui concerne les champs indexés pour HNSW, le moteur de recherche utilise un graphe HNSW pour effectuer la recherche sur un sous-ensemble de nœuds au sein de l’index vectoriel.

Création du graphe HNSW

Pendant l’indexation, le service de recherche construit le graphique HNSW. L’objectif de l’indexation d’un nouveau vecteur dans un graphe HNSW est de l’ajouter à la structure de graphe de sorte à permettre une recherche efficace du plus proche voisin. Les étapes suivantes montrent la procédure à suivre :

  1. Initialisation : commencez par un graphe HNSW vide ou le graphe HNSW existant s’il ne s’agit pas d’un nouvel index.

  2. Point d’entrée : il s’agit du niveau supérieur du graphe hiérarchique qui sert de point de départ pour l’indexation.

  3. Ajout au graphe : les différents niveaux hiérarchiques représentent les diverses granularités du graphe, les niveaux supérieurs étant plus globaux et les niveaux inférieurs étant plus granulaires. Chaque nœud du graphe représente un point vectoriel.

    • Chaque nœud est connecté à m plus proches voisins au maximum. Il s’agit du paramètre m.

    • Le nombre de points de données considérés comme des connexions candidates est gouverné par le paramètre efConstruction. Cette liste dynamique forme l’ensemble de points les plus proches dans le graphe existant que l’algorithme doit prendre en compte. Les valeurs efConstruction supérieures entraînent la prise en compte d’autres nœuds, ce qui conduit souvent à des voisinages locaux plus denses pour chaque vecteur.

    • Ces connexions utilisent la similarité metric configurée pour déterminer la distance. Certaines connexions sont des connexions « longue distance » qui se connectent à divers niveaux hiérarchiques, créant dans le graphe des raccourcis qui améliorent l’efficacité de la recherche.

  4. Nettoyage et optimisation du graphe : cela peut se produire après l’indexation de tous les vecteurs et améliorent la navigabilité et l’efficacité du graphe HNSW.

Une requête vectorielle navigue dans la structure du graphique hiérarchique pour rechercher les correspondances. Voici un résumé des étapes du processus :

  1. Initialisation : l’algorithme lance la recherche au niveau supérieur du graphe hiérarchique. Ce point d’entrée contient le jeu de vecteurs qui sert de point de départ pour la recherche.

  2. Traversée : il traverse ensuite le graphe niveau par niveau, en commençant par le niveau supérieur puis les niveaux inférieurs, sélectionnant les nœuds candidats qui sont les plus proches du vecteur de requête en fonction de la métrique de distance configurée, telle que la similarité cosinus.

  3. Nettoyage : pour améliorer l’efficacité, l’algorithme nettoie l’espace de recherche en tenant compte uniquement des nœuds susceptibles de contenir les plus proches voisins. Pour ce faire, il maintient une file d’attente prioritaire des candidats possibles et la met à jour à mesure que la recherche progresse. La longueur de cette file d’attente est configurée par le paramètre efSearch.

  4. Affinement : quand l’algorithme passe aux niveaux inférieurs, plus granulaires, HNSW prend en compte d’autres voisins près de la requête, ce qui permet à l’ensemble candidat de vecteurs d’être affiné et d’améliorer l’exactitude.

  5. Achèvement : la recherche se termine quand le nombre souhaité de plus proches voisins a été identifié ou quand d’autres critères d’arrêt sont respectés. Ce nombre souhaité de plus proches voisins est régi par le paramètre k de durée de la requête.

Métriques de similarité utilisées pour mesurer la proximité

L’algorithme recherche des vecteurs candidats pour évaluer la similarité. Pour effectuer cette tâche, un calcul de métrique de similarité compare le vecteur candidat au vecteur de requête et mesure la similarité. L’algorithme garde un suivi de l’ensemble ordonné des vecteurs les plus similaires qu’il a trouvés, qui constitue le jeu de résultats classé quand l’algorithme a atteint l’achèvement.

Métrique Descriptif
cosine Cette métrique mesure l’angle entre deux vecteurs et n’est pas affectée par des longueurs de vecteurs différentes. Mathématiquement, elle calcule l’angle entre deux vecteurs. Le cosinus étant la métrique de similarité utilisée par les modèles incorporés Azure OpenAI, si vous utilisez Azure OpenAI, spécifiez cosine dans la configuration vectorielle.
dotProduct Cette métrique mesure à la fois la longueur de chaque paire de deux vecteurs et l’angle entre eux. Mathématiquement, elle calcule les produits des grandeurs des vecteurs et l’angle entre eux. Pour les vecteurs normalisés, la métrique est identique à la similarité cosine, mais légèrement plus performante.
euclidean (également appelée l2 norm) Cette métrique mesure la longueur de la différence vectorielle entre deux vecteurs. Mathématiquement, elle calcule la distance euclidienne entre deux vecteurs, qui est la norme l2 de la différence des deux vecteurs.

Remarque

Si vous exécutez deux requêtes vectorielles ou plus en parallèle, ou si vous effectuez une recherche hybride qui combine des requêtes vectorielles et textuelles dans la même requête, la fusion de classement réciproque (RRF) est utilisée pour évaluer les résultats de la recherche finale.

Scores dans les résultats d’une recherche vectorielle

Des scores sont calculés et affectés à chaque correspondance, celles qui ont les scores les plus élevés étant retournées en tant que k résultats. La propriété @search.score contient le score. Le tableau suivant montre la plage dans laquelle un score va se trouver.

Méthode de recherche Paramètre Métrique de scoring Plage
recherche vectorielle @search.score Cosinus 0,333 – 1,00

Pour la métrique cosine, il est important de noter que le @search.score calculé n’est pas la valeur du cosinus entre le vecteur de la requête et les vecteurs du document. Recherche Azure AI applique à la place des transformations pour que la fonction de score soit décroissante de façon monotone, ce qui signifie que les valeurs de score diminuent toujours en valeur quand la similarité augmente. Cette transformation veille à ce que les scores de recherche soient utilisables à des fins de classement.

Il existe certaines nuances avec les scores de similarité :

  • La similarité cosinus est définie comme le cosinus de l’angle entre deux vecteurs.
  • La distance cosinus est définie en tant que 1 - cosine_similarity.

Pour créer une fonction décroissante de façon monotone, le @search.score est défini comme 1 / (1 + cosine_distance).

Les développeurs qui ont besoin d’une valeur cosinus au lieu de la valeur synthétique peuvent utiliser une formule pour convertir le score de recherche en distance cosinus :

double ScoreToSimilarity(double score)
{
    double cosineDistance = (1 - score) / score;
    return  -cosineDistance + 1;
}

Avoir la valeur cosinus d’origine peut être utile dans des solutions personnalisées qui configurent des seuils pour réduire les résultats de qualité faible.

Conseils pour l’optimisation de la pertinence

Si vous n’obtenez pas de résultats pertinents, faites des essais avec des modifications de la configuration de la requête. Il n’existe pas de fonctionnalités d’optimisation spécifiques pour les requêtes vectorielles, comme un profil de scoring ou la mise en avant d’un champ ou d’un terme :

  • Faites des essais avec des tailles et des chevauchements de blocs. Essayez en augmentant la taille des blocs et en vérifiant qu’il existe un chevauchement suffisant pour préserver le contexte ou la continuité entre les blocs.

  • Pour HNSW, essayez différents niveaux de efConstruction pour changer la composition interne du graphique de proximité. La valeur par défaut est 400. La plage est comprise entre 100 et 1,000.

  • Augmentez les k résultats pour utiliser plus de résultats de recherche dans un modèle de conversation, si vous en utilisez un.

  • Essayez des requêtes hybrides avec un classement sémantique. Dans les tests de point de référence, cette combinaison a produit de façon cohérente les résultats les plus pertinents.

Étapes suivantes