De la recherche vectorielle aux puissantes API REST, Elasticsearch offre aux développeurs la boîte à outils de recherche la plus complète. Explorez nos notebooks d’exemples sur GitHub pour tester de nouveaux cas d’usage. Vous pouvez également démarrer votre essai gratuit ou exécuter Elasticsearch en local dès aujourd’hui.
Depuis ses débuts en tant que moteur de recherche de recettes, Elasticsearch a été conçu pour fournir une recherche plein texte rapide et puissante. Compte tenu de ces racines, l'amélioration de la recherche de texte a été une motivation importante pour nos travaux en cours sur les vecteurs. Dans Elasticsearch 7.0, nous avons introduit des types de champs expérimentaux pour les vecteurs à haute dimension, et maintenant la version 7.3 apporte la prise en charge de l'utilisation de ces vecteurs dans l'évaluation des documents.
Ce billet se concentre sur une technique particulière appelée recherche par similarité de texte. Dans ce type de recherche, l'utilisateur saisit une courte requête en texte libre et les documents sont classés en fonction de leur similarité avec la requête. La similarité des textes peut être utile dans divers cas d'utilisation :
- Réponse aux questions : À partir d'une collection de questions fréquemment posées, trouver des questions similaires à celle que l'utilisateur a saisie.
- Recherche d'articles : Dans une collection d'articles de recherche, renvoyer les articles dont le titre est étroitement lié à la requête de l'utilisateur.
- Recherche d'images : Dans un ensemble de données d'images légendées, trouver les images dont la légende est similaire à la description de l'utilisateur.
Une approche simple de la recherche par similarité consisterait à classer les documents en fonction du nombre de mots qu'ils partagent avec la requête. Mais un document peut être similaire à la requête même s'ils n'ont que très peu de mots en commun - une notion plus robuste de similarité prendrait également en compte son contenu syntaxique et sémantique.
La communauté du traitement du langage naturel (NLP) a mis au point une technique appelée "text embedding" qui code les mots et les phrases sous forme de vecteurs numériques. Ces représentations vectorielles sont conçues pour capturer le contenu linguistique du texte et peuvent être utilisées pour évaluer la similarité entre une requête et un document.
Ce billet explore comment les text embeddings et le type dense_vector d'Elasticsearch pourraient être utilisés pour soutenir la recherche de similarité. Nous donnerons d'abord un aperçu des techniques d'intégration, puis nous présenterons un prototype simple de recherche par similarité à l'aide d'Elasticsearch.
Remarque : l'utilisation des enchâssements de texte dans la recherche est un domaine complexe et en pleine évolution. Ce blog n'est pas une recommandation pour une architecture ou une mise en œuvre particulière. Commencez ici pour découvrir comment vous pouvez améliorer votre expérience de recherche grâce à la puissance de la recherche vectorielle.
Qu'est-ce qu'un encartage de texte ?
Examinons de plus près les différents types d'enchâssement de texte et leur comparaison avec les méthodes de recherche traditionnelles.
Les enchâssements de mots
Un modèle d'intégration de mots représente un mot sous la forme d'un vecteur numérique dense. Ces vecteurs visent à capturer les propriétés sémantiques du mot - les mots dont les vecteurs sont proches les uns des autres devraient être similaires en termes de signification sémantique. Dans une bonne intégration, les directions dans l'espace vectoriel sont liées à différents aspects de la signification du mot. Par exemple, le vecteur pour "Canada" peut être proche de "France" dans une direction, et proche de "Toronto" dans une autre.
Les communautés de recherche et de traitement de texte s'intéressent depuis longtemps aux représentations vectorielles des mots. L'intégration de mots a connu un regain d'intérêt au cours des dernières années, lorsque de nombreuses tâches traditionnelles ont été revues à l'aide de réseaux neuronaux. Certains algorithmes d'intégration de mots ont été développés avec succès, notamment word2vec et GloVe. Ces approches utilisent de grandes collections de textes et examinent le contexte dans lequel chaque mot apparaît pour déterminer sa représentation vectorielle :
- Le modèle word2vec Skip-gram entraîne un réseau neuronal à prédire les mots du contexte autour d'un mot dans une phrase. Les poids internes du réseau donnent l'enchâssement des mots.
- Dans GloVe, la similarité des mots dépend de leur fréquence d'apparition avec d'autres mots du contexte. L'algorithme entraîne un modèle linéaire simple sur les comptes de cooccurrence des mots.
De nombreux groupes de recherche distribuent des modèles qui ont été pré-entraînés sur de grands corpus de textes tels que Wikipedia ou Common Crawl, ce qui permet de les télécharger et de les intégrer dans des tâches en aval. Bien que des versions pré-entraînées soient parfois utilisées directement, il peut être utile d'adapter le modèle à l'ensemble de données et à la tâche spécifiques. Cela se fait souvent en exécutant une étape de "réglage fin" sur le modèle pré-entraîné.
Les mots intégrés se sont révélés très robustes et efficaces, et il est désormais courant d'utiliser les mots intégrés à la place des mots individuels dans les tâches de TAL telles que la traduction automatique et la classification des sentiments.
Enchâssement de phrases
Plus récemment, les chercheurs ont commencé à s'intéresser aux techniques d'intégration qui représentent non seulement des mots, mais aussi des sections de texte plus longues. La plupart des approches actuelles sont basées sur des architectures de réseaux neuronaux complexes et intègrent parfois des données étiquetées lors de la formation afin de faciliter la capture des informations sémantiques.
Une fois entraînés, les modèles sont capables de prendre une phrase et de produire un vecteur pour chaque mot dans son contexte, ainsi qu'un vecteur pour la phrase entière. Comme pour l'intégration de mots, des versions pré-entraînées de nombreux modèles sont disponibles, ce qui permet aux utilisateurs d'éviter le processus d'entraînement coûteux. Alors que le processus d'apprentissage peut être très gourmand en ressources, l'utilisation du modèle est beaucoup plus légère - les modèles d'intégration de phrases sont généralement assez rapides pour être utilisés dans le cadre d'applications en temps réel.
Parmi les techniques courantes d'intégration de phrases, on peut citer InferSent, Universal Sentence Encoder, ELMo et BERT. L'amélioration de l'intégration des mots et des phrases est un domaine de recherche actif, et il est probable que d'autres modèles forts seront introduits.
Comparaison avec les méthodes de recherche traditionnelles
Dans la recherche d'informations traditionnelle, une façon courante de représenter un texte sous forme de vecteur numérique consiste à attribuer une dimension à chaque mot du vocabulaire. Le vecteur d'un texte est alors basé sur le nombre d'occurrences de chaque terme du vocabulaire. Cette façon de représenter un texte est souvent appelée "bag of words," parce que nous comptons simplement les occurrences de mots sans tenir compte de la structure de la phrase.
Les text embeddings diffèrent des représentations vectorielles traditionnelles sur certains points importants :
- Les vecteurs encodés sont denses et relativement peu dimensionnés, avec souvent entre 100 et 1 000 dimensions. En revanche, les vecteurs de sacs de mots sont peu nombreux et peuvent comporter plus de 50 000 dimensions. Les algorithmes d'intégration codent le texte dans un espace de dimension inférieure dans le cadre de la modélisation de sa signification sémantique. Idéalement, les mots et expressions synonymes se retrouvent avec une représentation similaire dans le nouvel espace vectoriel.
- Les encastrements de phrases peuvent prendre en compte l'ordre des mots lors de la détermination de la représentation vectorielle. Par exemple, la phrase "tune in" peut être représentée par un vecteur très différent de "in tune".
- Dans la pratique, les enchâssements de phrases ne s'appliquent pas toujours bien à de grandes parties de texte. Ils ne sont pas couramment utilisés pour représenter un texte plus long qu'un court paragraphe.
Utilisation des embeddings pour la recherche de similitudes
Supposons que nous disposions d'une vaste collection de questions et de réponses. Un utilisateur peut poser une question et nous voulons retrouver la question la plus similaire dans notre collection pour l'aider à trouver une réponse.
Nous pourrions utiliser des enchâssements de texte pour permettre de retrouver des questions similaires :
- Lors de l'indexation, chaque question est traitée par un modèle d'intégration de phrases afin de produire un vecteur numérique.
- Lorsqu'un utilisateur saisit une requête, celle-ci est traitée par le même modèle d'intégration de phrases pour produire un vecteur. Pour classer les réponses, nous calculons la similarité vectorielle entre chaque question et le vecteur de la requête. Pour comparer les vecteurs d'intégration, il est courant d'utiliser la similitude cosinus.
Ce dépôt donne un exemple simple de la façon dont cela pourrait être réalisé dans Elasticsearch. Le script principal indexe environ 20 000 questions de l'ensemble de données StackOverflow, puis permet à l'utilisateur de saisir des requêtes en texte libre dans l'ensemble de données.
Nous verrons bientôt chaque partie du script en détail, mais voyons d'abord quelques exemples de résultats. Dans de nombreux cas, la méthode est capable de capturer la similarité même lorsqu'il n'y a pas de fort chevauchement de mots entre la requête et la question indexée :
- "zippage des fichiers" retours "Compression / décompression des dossiers & Fichiers"
- "déterminer si quelque chose est une IP" renvoie "Comment déterminer si une chaîne de caractères est une IP ou un nom d'hôte ?"
- "traduire des octets en doubles" returns "Convertir des octets en nombres à virgule flottante en Python"
Détails de la mise en œuvre
Le script commence par télécharger et créer le modèle d'intégration dans TensorFlow. Nous avons choisi l'encodeur universel de phrases de Google, mais il est possible d'utiliser de nombreuses autres méthodes d'intégration. Le script utilise le modèle d'intégration tel quel, sans aucune formation ou mise au point supplémentaire.
Ensuite, nous créons l'index Elasticsearch, qui comprend des correspondances pour le titre de la question, les balises et le titre de la question encodé sous forme de vecteur :
Dans le mapping pour dense_vector, nous devons spécifier le nombre de dimensions que les vecteurs contiendront. Lors de l'indexation d'un champ title_vector, Elasticsearch vérifiera qu'il possède le même nombre de dimensions que celui spécifié dans le mapping.
Pour indexer les documents, nous faisons passer le titre de la question par le modèle d'intégration afin d'obtenir un tableau numérique. Ce tableau est ajouté au document dans le champ title_vector.
Lorsqu'un utilisateur saisit une requête, le texte passe d'abord par le même modèle d'intégration et est stocké dans le paramètre query_vector. Depuis la version 7.3, Elasticsearch propose une fonction cosineSimilarity dans son langage de script natif. Pour classer les questions en fonction de leur similitude avec la requête de l'utilisateur, nous utilisons donc une requête script_score :
Nous veillons à transmettre le vecteur de requête en tant que paramètre de script afin d'éviter de recompiler le script() à chaque nouvelle requête. Elasticsearch n'autorisant pas les scores négatifs, il est nécessaire d'en ajouter un à la similarité cosinus.
| Note : ce billet de blog utilisait à l'origine une syntaxe différente pour les fonctions vectorielles qui était disponible dans Elasticsearch 7.3, mais qui a été supprimée dans la version 7.6.
|
Limites importantes
La requête script_score est conçue pour envelopper une requête restrictive et modifier les scores des documents qu'elle renvoie. Cependant, nous avons fourni une requête match_all, ce qui signifie que le script sera exécuté sur tous les documents de l'index. Il s'agit d'une limitation actuelle de la similarité vectorielle dans Elasticsearch - les vecteurs peuvent être utilisés pour évaluer les documents, mais pas dans l'étape de recherche initiale. L'aide à la recherche basée sur la similarité des vecteurs est un domaine important des travaux en cours.
Pour éviter de parcourir tous les documents et maintenir des performances élevées, la requête match_all peut être remplacée par une requête plus sélective. La bonne requête à utiliser pour la recherche dépend probablement du cas d'utilisation spécifique.
Bien que nous ayons vu quelques exemples encourageants ci-dessus, il est important de noter que les résultats peuvent également être bruyants et non intuitifs. Par exemple, "zippant les fichiers" attribue également des scores élevés à "Partiel .csproj Fichiers" et "Comment éviter .pyc fichiers ?". Et lorsque la méthode renvoie des résultats surprenants, il n'est pas toujours évident de déboguer le problème - la signification de chaque composante du vecteur est souvent opaque et ne correspond pas à un concept interprétable. Avec les techniques de notation traditionnelles basées sur le chevauchement des mots, il est souvent plus facile de répondre à la question suivante : "pourquoi ce document est-il bien classé ?"
Comme indiqué précédemment, ce prototype est conçu comme un exemple de la manière dont les modèles d'intégration peuvent être utilisés avec les champs vectoriels, et non comme une solution prête à l'emploi. Lors de l'élaboration d'une nouvelle stratégie de recherche, il est essentiel de tester les performances de l'approche sur vos propres données, en veillant à les comparer à une base de référence solide telle qu'une requête de correspondance. Il peut s'avérer nécessaire d'apporter des modifications majeures à la stratégie avant qu'elle n'obtienne des résultats solides, notamment en affinant le modèle d'intégration pour l'ensemble de données cible ou en essayant différentes manières d'intégrer les intégrations, telles que l'expansion des requêtes au niveau des mots.
Conclusions
Les techniques d'intégration constituent un moyen puissant de capturer le contenu linguistique d'un texte. En indexant les enchâssements et en attribuant des notes basées sur la distance vectorielle, nous pouvons comparer les documents en utilisant une notion de similarité qui va au-delà de leur chevauchement au niveau des mots.
Nous sommes impatients d'introduire davantage de fonctionnalités basées sur le type de champ vectoriel. L'utilisation des vecteurs pour la recherche est un domaine nuancé et en développement - comme toujours, nous serions ravis de connaître vos cas d'utilisation et vos expériences sur Github et les forums de discussion!
Questions fréquentes
Qu'est-ce que la recherche par similarité de texte ?
La recherche par similarité de texte est un type de recherche dans lequel l'utilisateur saisit une courte requête en texte libre, et les documents sont classés en fonction de leur similarité avec la requête. Il peut être utile dans divers cas d'utilisation, tels que la réponse à des questions, la recherche d'articles et la recherche d'images.




