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?
Commons Lang a une implémentation de distance Levenshtein .
Le codec commun a une implémentation de soundex et metaphone .
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 :
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.
ArrayIndexOutOfBoundsException
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.
BitapOnlineSearcher
, mais vous oblige à utiliser Java.io.Reader
avec un cours d'alphabet. C'est Javadoc est écrit en russe.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
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).
À Lucene, j'ajouterais SOLR http://wiki.Apache.org/solr/AnalyzersTokenizersTokenFilters
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.
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 .
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.