web-dev-qa-db-fra.com

Bibliothèque de recherche de chaînes floues dans Java

Je recherche une bibliothèque haute performance Java pour la recherche de chaînes floues.

Il existe de nombreux algorithmes pour trouver des chaînes similaires, la distance de Levenshtein, le Soundex de Daitch-Mokotoff, les n-grammes, etc.

Quelles sont les implémentations Java Java? Avantages et inconvénients pour elles? Je connais Lucene, toute autre solution ou Lucene est la meilleure?

Je les ai trouvés, est-ce que quelqu'un en a l'expérience?

67
dario

Commons Lang a une implémentation de distance Levenshtein .

Le codec commun a une implémentation de soundex et metaphone .

36
JodaStephen

Vous pouvez utiliser Apache Lucene, mais selon le cas d'utilisation, cela peut être un poids trop lourd. Pour les recherches floues très simples, il peut être un peu complexe à utiliser et (corrigez-moi si je me trompe), vous devez créer un index.

Si vous avez besoin d'un simple algorithme en ligne (= ne pas maintenir d'index), vous pouvez utiliser le flou algorithme Bitap . J'ai trouvé une implémentation dans Java ici . Son code tient dans une seule méthode relativement courte avec une signature presque explicite:

public static List<Integer> find(String doc, String pattern, int k)

Apache Commons StringUtils a une implémentation de l'algorithme Levenshtein pour la correspondance de chaîne floue. Il peut être vu comme la version floue de String.equals, Bitap est comme la version floue de String.indexOf et utilise toujours la mesure de distance Levenshtein. Il est généralement plus efficace que naïvement d'utiliser Levenshtein pour comparer le modèle de recherche avec chaque sous-chaîne qui pourrait éventuellement correspondre.

Remarques :

  • L'algorithme Bitap semble être surtout utile pour des alphabets relativement petits, par ex. ASCII simple. En fait, la version de Simon Watiau que j'ai liée jette un ArrayIndexOutOfBoundsException sur des caractères non ASCII (> = 128), vous devrez donc les filtrer.
  • J'ai essayé d'utiliser Bimap dans une application pour rechercher une liste de personnes en mémoire par nom. J'ai trouvé qu'une distance de Levenhstein de 2 donne trop de faux positifs. Une distance de Levenhstein de 1 fonctionne mieux, mais elle ne peut pas détecter une faute de frappe où vous échangez deux lettres, par ex. "William" et "Willaim". Je peux penser à quelques façons de résoudre ce problème, par exemple.

    1. faire une recherche floue uniquement lorsqu'une recherche exacte ne trouve aucune correspondance (et afficher un message à l'utilisateur à ce sujet)
    2. ajustez Bitap pour utiliser la distance Damerau-Levenshtein où un échange a une distance 1 au lieu de 2. Selon wikipedia , cela est possible, mais je n'ai pas pu trouver une implémentation existante en Java.
    3. au lieu de "contient", faites un "démarre avec". Le outils de recherche floue contient une version préfixe de Damerau-Levenshtein, mais il m'a donné un ArrayIndexOutOfBoundsException
    4. ajuster l'algorithme pour introduire le classement des résultats de recherche où les correspondances exactes obtiennent un score plus élevé

    Si vous allez en faire 2 ou 4, il peut être préférable d'utiliser de toute façon une bibliothèque de recherche en texte intégral appropriée comme Lucene.

  • Plus d'informations sur la recherche floue peuvent être trouvées sur ce blog . Son auteur a également créé une implémentation en Java appelée BitapOnlineSearcher, mais vous oblige à utiliser Java.io.Reader avec un cours d'alphabet. C'est Javadoc est écrit en russe.
11
Henno Vermeulen

Si vous comparez principalement des chaînes courtes et que vous voulez quelque chose de portable et léger, vous pouvez utiliser l'algorithme bien connu python fuzzywuzzy porté sur Java .

Vous pouvez en savoir plus ici

11

SimMetrics est probablement ce dont vous avez besoin: http://sourceforge.net/projects/simmetrics/

Il dispose de plusieurs algorithmes pour calculer différentes saveurs de distance d'édition.

Lucene est un moteur de recherche en texte intégral très puissant, mais la recherche FT n'est pas exactement la même chose que la correspondance de chaîne floue (par exemple, étant donné une liste de chaînes, trouvez-moi celle qui ressemble le plus à une chaîne candidate).

8
Darren
3
Mond Raymond

Vous pouvez essayer la bibliothèque Complètement , elle s'appuie sur le prétraitement du texte pour créer un index en mémoire pour répondre efficacement aux recherches (floues) dans de grands ensembles de données. Contrairement à Lucene et à d'autres bibliothèques de recherche de texte complètes, l'API est petite et facile à démarrer.

2

Vous pouvez essayer le bitap. Je jouais avec un bitap écrit en ANSI C et c'était assez rapide il y a Java implémentation dans http://www.crosswire.org .

1
Mojo Risin

Apache Lucene est le seul moyen, je pense. Je ne connais pas de meilleure bibliothèque de recherche.

Apache Lucene (TM) est une bibliothèque de moteur de recherche de texte hautes performances et complète, entièrement écrite en Java. Il s'agit d'une technologie adaptée à presque toutes les applications qui nécessitent une recherche en texte intégral, en particulier multiplateforme.

0
Vugluskr