Recherche de similarité, Partie 2 Quantification de Produit

Similarity Search, Part 2 Product Quantification

Découvrez une technique puissante pour compresser efficacement de grandes quantités de données

La recherche de similarité est un problème où, étant donné une requête, l’objectif est de trouver les documents les plus similaires parmi tous les documents de la base de données.

Introduction

En science des données, la recherche de similarité apparaît souvent dans le domaine du traitement du langage naturel, des moteurs de recherche ou des systèmes de recommandation où les documents ou les éléments les plus pertinents doivent être récupérés pour une requête. Normalement, les documents ou les éléments sont représentés sous forme de textes ou d’images. Cependant, les algorithmes d’apprentissage automatique ne peuvent pas travailler directement avec des textes ou des images brutes, c’est pourquoi les documents et les éléments sont généralement prétraités et stockés sous forme de vecteurs de nombres.

Parfois, chaque composant d’un vecteur peut stocker une signification sémantique. Dans ce cas, ces représentations sont également appelées incorporations. De telles incorporations peuvent avoir des centaines de dimensions et leur quantité peut atteindre des millions ! En raison de ces nombres énormes, tout système de recherche d’informations doit être capable de détecter rapidement les documents pertinents.

En apprentissage automatique, un vecteur est également appelé un objet ou un point.

Index

Pour accélérer les performances de recherche, une structure de données spéciale est construite sur les incorporations de l’ensemble de données. Une telle structure de données est appelée index. Il y a eu beaucoup de recherches dans ce domaine et de nombreux types d’index ont évolué. Avant de choisir un index à appliquer pour une tâche spécifique, il est nécessaire de comprendre comment il fonctionne sous le capot, car chaque index sert un but différent et vient avec ses propres avantages et inconvénients.

Dans la première partie de cette série d’articles, nous avons examiné la structure d’index de kNN et de fichier inversé pour effectuer une recherche de similarité. Les deux méthodes n’utilisent pas de techniques de compression de données, ce qui peut entraîner des problèmes de mémoire, en particulier dans les cas de grands ensembles de données et de RAM limitée. Dans cet article, nous essaierons de résoudre ce problème en examinant une autre méthode appelée Quantification de Produit.

Recherche de similarité, Partie 1 : kNN & Index de Fichier Inversé

towardsdatascience.com

Définition

La quantification de produit est le processus où chaque vecteur de données est converti en une représentation courte et efficace en mémoire (appelée code PQ). Au lieu de conserver entièrement tous les vecteurs, leurs représentations courtes sont stockées. En même temps, la quantification de produit est une méthode de compression avec perte qui entraîne une précision de prédiction plus faible mais qui fonctionne très bien en pratique.

En général, la quantification est le processus de mappage de valeurs infinies en valeurs discrètes.

Entraînement

Tout d’abord, l’algorithme divise chaque vecteur en plusieurs parties égales – les sous-vecteurs. Chacune des parties respectives de tous les vecteurs de l’ensemble de données forme des sous-espaces indépendants et est traitée séparément. Ensuite, un algorithme de regroupement est exécuté pour chaque sous-espace de vecteurs. Ainsi, plusieurs centroïdes sont créés dans chaque sous-espace. Chaque sous-vecteur est encodé avec l’ID du centroïde auquel il appartient. De plus, les coordonnées de tous les centroïdes sont stockées pour une utilisation ultérieure.

Les centroïdes de sous-espace sont également appelés vecteurs quantifiés.

Dans la quantification de produit, un ID de cluster est souvent appelé une valeur de reproduction.

Remarque. Dans les figures ci-dessous, un rectangle représente un vecteur contenant plusieurs valeurs, tandis qu’un carré indique un seul nombre.

Encodage à l'aide de la quantification

En conséquence, si un vecteur d’origine est divisé en n parties, il peut être encodé par n nombres – les ID des centroïdes respectifs pour chacun de ses sous-vecteurs. En général, le nombre de centroïdes créés k est choisi comme une puissance de 2 pour une utilisation plus efficace de la mémoire. De cette façon, la mémoire requise pour stocker un vecteur encodé est de n * log(k) bits.

L’ensemble de tous les centroids à l’intérieur d’un sous-espace est appelé un dictionnaire de codes. L’exécution de n algorithmes de clustering pour tous les sous-espaces produit n dictionnaires de codes distincts.

Exemple de compression

Imaginons un vecteur original de taille 1024 qui stocke des nombres flottants (32 bits) divisé en n = 8 sous-vecteurs où chaque sous-vecteur est encodé par l’un des k = 256 clusters. Par conséquent, l’encodage de l’ID d’un seul cluster nécessiterait log(256) = 8 bits. Comparons les tailles de mémoire pour la représentation des vecteurs dans les deux cas :

  • Vecteur original : 1024 * 32 bits = 4096 octets.
  • Vecteur encodé : 8 * 8 bits = 8 octets.

La compression finale est de 512 fois ! C’est le véritable pouvoir de la quantification de produit.

Exemple de quantification. Les nombres dans les vecteurs montrent combien de nombres ils stockent.

Voici quelques notes importantes :

  • L’algorithme peut être entraîné sur un sous-ensemble de vecteurs (par exemple, pour créer des clusters) et être utilisé pour un autre : une fois que l’algorithme est entraîné, un autre ensemble de données de vecteurs est passé où de nouveaux vecteurs sont encodés en utilisant les centroids déjà construits pour chaque sous-espace.
  • Typiquement, k-means est choisi comme algorithme de clustering. L’un de ses avantages est que le nombre de clusters k est un hyperparamètre qui peut être défini manuellement, selon les exigences d’utilisation de la mémoire.

Inférence

Pour mieux comprendre, examinons d’abord plusieurs approches naïves et découvrons leurs inconvénients. Cela nous aidera également à réaliser pourquoi elles ne devraient normalement pas être utilisées.

Approches naïves

La première approche naïve consiste à décompresser tous les vecteurs en concaténant les centroids correspondants de chaque vecteur. Après cela, la distance L2 (ou une autre métrique) peut être calculée à partir d’un vecteur de requête vers tous les vecteurs de l’ensemble de données. Évidemment, cette méthode fonctionne mais elle est très chronophage car la recherche par force brute est effectuée et le calcul de distance est effectué sur des vecteurs décompressés à haute dimension.

Une autre façon possible est de diviser un vecteur de requête en sous-vecteurs et de calculer une somme de distances de chaque sous-vecteur de requête aux vecteurs quantifiés respectifs d’un vecteur de base, en fonction de son code PQ. En conséquence, la technique de recherche par force brute est utilisée à nouveau et le calcul de distance ici nécessite toujours un temps linéaire de la dimensionnalité des vecteurs d’origine, comme dans le cas précédent.

Calcul d'une distance approximative en utilisant une approche naïve. L'exemple est montré pour la distance euclidienne comme métrique.

Une autre méthode possible consiste à encoder le vecteur de requête dans un code PQ. Ensuite, ce code PQ est directement utilisé pour calculer des distances à tous les autres codes PQ. Le vecteur de l’ensemble de données avec le code PQ correspondant qui a la plus courte distance est alors considéré comme le voisin le plus proche de la requête. Cette approche est plus rapide que les deux premières car la distance est toujours calculée entre des codes PQ de faible dimension. Cependant, les codes PQ sont composés d’IDs de cluster qui n’ont pas beaucoup de sens sémantique et peuvent être considérés comme une variable catégorielle utilisée explicitement comme une variable réelle. Clairement, c’est une mauvaise pratique et cette méthode peut conduire à une mauvaise qualité de prédiction.

Approche optimisée

Un vecteur de requête est divisé en sous-vecteurs. Pour chacun de ses sous-vecteurs, les distances à tous les centroids de l’espace correspondant sont calculées. En fin de compte, cette information est stockée dans la table d.

Obtention d'une table d stockant des distances partielles entre les sous-vecteurs de requête et les centroids

Les distances partielles calculées entre les sous-vecteurs et les centroids sont souvent appelées distances partielles.

En utilisant cette table de distance entre sous-vecteurs et centroïdes d, la distance approximative entre la requête et tout vecteur de la base de données peut être facilement obtenue par ses codes PQ:

  1. Pour chacun des sous-vecteurs d’un vecteur de la base de données, le centroïde le plus proche j est trouvé (en utilisant les valeurs de mappage des codes PQ) et la distance partielle d[i][j] de ce centroïde au sous-vecteur i de la requête (en utilisant la matrice calculée d) est prise.
  2. Toutes les distances partielles sont au carré et additionnées. En prenant la racine carrée de cette valeur, la distance euclidienne approximative est obtenue. Si vous souhaitez savoir comment obtenir des résultats approximatifs pour d’autres métriques également, accédez à la section ci-dessous “Approximation des autres métriques de distance”.
Calcul de la distance entre une requête et un vecteur de base de données en utilisant le code PQ et la table de distance

L’utilisation de cette méthode de calcul de distances approximatives suppose que les distances partielles d sont très proches des distances réelles a entre les sous-vecteurs de la requête et de la base de données.

Néanmoins, cette condition peut ne pas être satisfaite, surtout lorsque la distance c entre le sous-vecteur de la base de données et son centroïde est grande. Dans de tels cas, les calculs donnent une précision moindre.

L'exemple de gauche montre un bon cas d'approximation lorsque la distance réelle est très proche de la distance partielle (c est petit). À droite, on peut observer un mauvais scénario car la distance partielle est beaucoup plus longue que la distance réelle (c est grand).

Après avoir obtenu des distances approximatives pour toutes les lignes de la base de données, nous recherchons les vecteurs ayant les plus petites valeurs. Ces vecteurs seront les voisins les plus proches de la requête.

Approximation des autres métriques de distance

Jusqu’à présent, nous avons examiné comment approximer la distance euclidienne en utilisant des distances partielles. Généralisons maintenant la règle pour d’autres métriques également.

Imaginons que nous voulions calculer une métrique de distance entre une paire de vecteurs. Si nous connaissons la formule de la métrique, nous pouvons l’appliquer directement pour obtenir le résultat. Mais parfois, nous pouvons le faire par parties de la manière suivante:

  • Les deux vecteurs sont divisés en n sous-vecteurs.
  • Pour chaque paire de sous-vecteurs respectifs, la métrique de distance est calculée.
  • Les métriques n calculées sont ensuite combinées pour produire la distance réelle entre les vecteurs d’origine.
La figure montre deux façons de calculer une métrique. À gauche, la formule de la métrique est directement appliquée aux deux vecteurs. À droite, des distances partielles sont calculées pour chaque paire de sous-vecteurs respectifs. Ensuite, elles sont combinées en utilisant les fonctions d'agrégation h, g et f.

La distance euclidienne est un exemple de métrique qui peut être calculée par parties. En se basant sur la figure ci-dessus, nous pouvons choisir les fonctions d’agrégation d’être h(z) = z², g(z₀, z₁, …, zₙ) = sum(z₀, z₁, …, zₙ) et f(z) = √z.

La distance euclidienne peut être calculée par parties

Le produit intérieur est un autre exemple de métrique avec des fonctions d’agrégation h(z) = z, g(z₀, z₁, …, zₙ) = somme(z₀, z₁, …, zₙ) et f(z) = z.

Dans le contexte de la quantification de produit, il s’agit d’une propriété très importante car lors de l’inférence, l’algorithme calcule les distances par parties. Cela signifie qu’il serait beaucoup plus problématique d’utiliser des métriques pour la quantification de produit qui n’ont pas cette propriété. La distance cosinus est un exemple de telle métrique.

S’il est encore nécessaire d’utiliser une métrique sans cette propriété, des heuristiques supplémentaires doivent être appliquées pour agréger les distances partielles avec une certaine erreur.

Performance

Le principal avantage de la quantification de produit est une compression massive des vecteurs de base de données qui sont stockés sous forme de codes PQ courts. Pour certaines applications, ce taux de compression peut être encore plus élevé que 95%! Cependant, en plus des codes PQ, la matrice d de taille k x n contenant des vecteurs quantifiés de chaque sous-espace doit être stockée.

La quantification de produit est une méthode de compression avec perte, plus la compression est élevée, plus il est probable que la précision de la prédiction diminuera.

La construction d’un système de représentation efficace nécessite la formation de plusieurs algorithmes de regroupement. En plus de cela, lors de l’inférence, k * n distances partielles doivent être calculées de manière brute et ajoutées pour chacun des vecteurs de base de données, ce qui peut prendre du temps.

Performance de la quantification de produit

Implémentation de Faiss

Faiss (Facebook AI Search Similarity) est une bibliothèque Python écrite en C++ utilisée pour une recherche de similarité optimisée. Cette bibliothèque présente différents types d’index qui sont des structures de données utilisées pour stocker efficacement les données et effectuer des requêtes.

Sur la base des informations de la documentation de Faiss, nous verrons comment la quantification de produit est utilisée.

La quantification de produit est implémentée dans la classe IndexPQ. Pour l’initialisation, nous devons lui fournir 3 paramètres:

  • d : nombre de dimensions dans les données.
  • M : nombre de divisions pour chaque vecteur (le même paramètre que n utilisé ci-dessus).
  • nbits : nombre de bits nécessaires pour coder un seul ID de cluster. Cela signifie que le nombre total de clusters dans un seul sous-espace sera égal à k = 2^nbits.

Pour une division de dimensions d’espace égales, le paramètre dim doit être divisible par M.

Le nombre total d’octets requis pour stocker un seul vecteur est égal à:

Comme nous pouvons le voir dans la formule ci-dessus, pour une utilisation plus efficace de la mémoire, la valeur de M * nbits doit être divisible par 8.

Implémentation de Faiss de IndexPQ

Conclusion

Nous avons examiné un algorithme très populaire dans les systèmes de récupération d’informations qui compresse efficacement de grands volumes de données. Son principal inconvénient est une vitesse d’inférence lente. Malgré ce fait, l’algorithme est largement utilisé dans les applications modernes de Big data, en particulier en combinaison avec d’autres techniques de recherche de similarité.

Dans la première partie de la série d’articles, nous avons décrit le flux de travail de l’index de fichier inversé. En fait, nous pouvons fusionner ces deux algorithmes en un seul plus efficace qui possédera les avantages des deux! C’est exactement ce que nous allons faire dans la prochaine partie de cette série.

Recherche de similarité, partie 3: Fusion de l’index de fichier inversé et de la quantification de produit

Dans les deux premières parties de cette série, nous avons discuté de deux algorithmes fondamentaux dans la récupération d’informations: l’inversion …

IPGirl.com

Ressources

  • Quantification de produits pour la recherche des plus proches voisins
  • Documentation de Faiss
  • Dépôt de Faiss
  • Résumé des index Faiss

Toutes les images, sauf indication contraire, sont de l’auteur.

We will continue to update IPGirl; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

AI

Inscription KYC désormais simplifiée grâce à l'IA

Les acteurs du marché financier peuvent désormais dire adieu aux processus d’enregistrement KYC longs et fastid...

AI

Complétion de nuage de points avec des modèles de diffusion pré-entraînés texte-vers-image

Avez-vous déjà entendu parler du terme nuage de points ? Il s’agit d’une représentation fondamentale des ...

AI

Outils de prévision analytique les plus performants pour les ventes et le marketing (2023)

Appliquée au marketing, l’analyse prédictive consiste à examiner des données historiques et actuelles pour préd...

AI

Meer Pyrus Base une nouvelle plate-forme open-source basée sur Python pour la simulation bidimensionnelle (2D) du RoboCup Soccer

La robotique, la branche entièrement dédiée au domaine de l’électronique et du génie informatique, est désormai...

AI

Une plongée profonde dans les bases de données relationnelles et leurs applications

De nos jours, la nécessité de stocker d’énormes quantités de données dans différentes catégories souvent sans l...