16 votes

Synonymes en utilisant Lucene

Quel est le meilleur moyen de gérer les synonymes (phrases) en utilisant Lucene? Surtout, quand j'ai besoin d'exécuter des requêtes comme: a OU b OU c PAS d

Et si on ajoutait un nouveau champ appelé "synonymes" à chaque document lors de l'indexation? La valeur de ce champ aurait une liste de tous les synonymes. Il serait ajouté à un document uniquement lorsque ce document contient l'un des synonymes.

Je pourrais ensuite exécuter une requête de recherche "OU" qui rechercherait le mot-clé de recherche dans ce champ ainsi que dans d'autres champs.

Cette approche pourrait-elle bien fonctionner pour tout type de requête?

Pour information, Les synonymes dans mon application sont totalement personnalisés et non issus d'un dictionnaire anglais... c'est-à-dire "Leader mondial en finance" pourrait également signifier "Meilleure banque d'investissement" ou "Société financière Fortune 500" etc. etc.

Veuillez suggérer.

Merci.

14voto

Adam Paynter Points 22056

Il existe une contribution au projet Lucene appelée "wordnet". Selon sa documentation:

Ce package utilise des synonymes définis par WordNet pour construire un index Lucene les stockant, qui peuvent ensuite être utilisés pour l'expansion de requête. Vous exécutez normalement Syns2Index une fois pour construire l'index de requête/"base de données", puis appelez SynExpand.expand(...) pour étendre une requête.

Il inclut un exemple de ce qu'il fait:

Si vous passez la requête "gros chien" alors cela affiche:

Requête: gros adulte^0.9 mauvais^0.9 généreux^0.9 vaniteux^0.9 flagorneur^0.9 prodigue^0.9 généreux^0.9 narcissique^0.9 arrogant^0.9 fier^0.9 largement^0.9 magnanime^0.9 important^0.9 généreux^0.9 distinct^0.9 enflé^0.9 vain^0.9 vaniteux^0.9 chien âtre^0.9 mauvais garçon^0.9 fripouille^0.9 imbécile^0.9 chasser^0.9 clic^0.9 cliquer^0.9 dent^0.9 dentelé^0.9 chien de garde^0.9 franc^0.9 saucisse^0.9 quidam^0.9 talon^0.9 hot-dog^0.9 chien^0.9 battant^0.9 poussoir^0.9 étiquette^0.9 queue^0.9 piste^0.9 saucisse^0.9 saucisse^0.9

Vous remarquez que les mots originaux ("gros" et "chien") n'ont pas de pondération attachée. En revanche, les synonymes ont une pondération (0.9) que vous pouvez configurer vous-même.

Il est livré avec la distribution standard de Lucene, dans le répertoire "contrib".

1voto

Shashikant Kore Points 3419

Vous pouvez obtenir l'objet Query après avoir analysé la chaîne de requête d'entrée avec QueryParser.parse().

Dans la plupart des cas, la requête de niveau supérieur est une requête booléenne avec des sous-requêtes comme ses enfants. Vous pouvez itérer de manière récursive sur l'objet de requête. Lorsque vous atteignez un objet TermQuery ou PhraseQuery, vous pouvez obtenir la (sous-)requête, et remplacer cet objet de requête par un objet de requête booléen composé de ses synonymes, le cas échéant.

Essentiellement, vous transformez votre requête originale

a OU b ET c 

à

(a OU synA) OU (b OU synB1 OU synB2) ET c

En opérant sur l'objet de requête, vous assurez simplement que vous remplacez les nœuds feuilles de la requête par de nouvelles requêtes et ne manipulez pas une hiérarchie de requêtes arbitrairement complexe.

0voto

Andrew Siemer Points 7226

Je préfère effectuer une recherche en utilisant toute la phrase saisie et donner plus de poids à tout ce qui est retourné par rapport à la série de recherches suivante. Ensuite, j'aime itérer à travers chaque mot de la phrase et effectuer une recherche avec ces résultats en leur attribuant un score plus faible. Ensuite, j'agrége les scores de tous les éléments retournés plus d'une fois et trie les résultats en conséquence. Ce n'est peut-être pas la meilleure façon de faire cela à 100% ... mais cela a très bien fonctionné pour moi par le passé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X