Les transducteurs Levenshtein acceptent un terme de requête et renvoient tous les termes d'un dictionnaire qui se trouvent à n erreurs d'orthographe de celui-ci. Ils constituent une classe de correcteurs orthographiques très efficaces (espace et temps) qui fonctionnent très bien lorsque vous n'avez pas besoin de contexte lors de vos suggestions. Oubliez d'effectuer une analyse linéaire de votre dictionnaire pour trouver tous les termes suffisamment proches de la requête de l'utilisateur, en utilisant une implémentation quadratique de la distance de Levenshtein ou de la distance Damerau-Levenshtein, ces bébés trouvent tous les termes de votre dictionnaire en temps linéaire sur la longueur du terme de requête (pas sur la taille du dictionnaire, sur la longueur du terme de requête).
Si vous avez besoin de contexte, prenez comme point de départ les candidats générés par le transducteur et branchez-les dans le modèle que vous utilisez pour le contexte (par exemple en sélectionnant la séquence de termes qui ont la plus grande probabilité d'apparaître ensemble).
Pour une démonstration rapide, veuillez visiter la page Github, ici. Il existe également une interface de ligne de commande, liblevenshtein-java-cli. Veuillez consulter son README.md pour les informations d'acquisition et d'utilisation.
La bibliothèque est actuellement écrite en Java, CoffeeScript et JavaScript, mais je la porterai bientôt dans d'autres langages. Si vous souhaitez le voir dans une langue spécifique ou dans un système de gestion de packages dans lequel vous souhaiteriez le déployer, faites-le moi savoir.
Bifurquer | Description |
---|---|
maître | Dernière source de développement |
libérer | Dernière source de version |
version-3.x | Dernière source de version pour la version 3.x |
version-2.x | Dernière source de version pour la version 2.x |
Les problèmes sont gérés sur waffle.io. Vous trouverez ci-dessous un graphique sur le taux auquel je les ai clôturés.
Veuillez visiter Bountysource pour promettre votre soutien aux problèmes en cours.
En matière de documentation, vous avez plusieurs options :
Wikia
Javadoc
Code source
liblevenshtein a été développé avec Java ≥ 1.8. Cela ne fonctionnera pas avec les versions antérieures.
Ajoutez une dépendance Maven sur Artifactory. Par exemple, dans un projet Gradle, vous modifieriez vos repositories
comme suit :
dépôts { maven { URL 'https://oss.jfrog.org/artifactory/oss-release-local' } }
Ajoutez une dépendance Maven sur l'un des éléments suivants :
Maven Central
JCentre
Bintray
<dépendance> <groupId>com.github.universal-automata</groupId> <artifactId>librevenshtein</artifactId> <version>3.0.0</version> </dépendance>
'com.github.universal-automata:libvenshtein:jar:3.0.0'
<dependency org="com.github.universal-automata" name="liblevenshtein" rev="3.0.0" />
@Raisins( @Grab(group='com.github.universal-automata', module='libvenshtein', version='3.0.0') )
compiler 'com.github.universal-automata:libvenshtein:3.0.0'
libraryDependencies += "com.github.universal-automata" % "libvenshtein" % "3.0.0"
[com.github.universal-automata/liblevenshtein "3.0.0"]
% git clone --progress [email protected]:universal-automata/liblevenshtein-java.git Cloning into 'liblevenshtein-java'... remote: Counting objects: 8117, done. remote: Compressing objects: 100% (472/472), done. remote: Total 8117 (delta 352), reused 0 (delta 0), pack-reused 7619 Receiving objects: 100% (8117/8117), 5.52 MiB | 289.00 KiB/s, done. Resolving deltas: 100% (5366/5366), done. Checking connectivity... done. % cd liblevenshtein-java % git pull --progress Already up-to-date. % git fetch --progress --tags % git checkout --progress 3.0.0 Note: checking out '3.0.0'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at 4f0f172... pushd and popd silently % git submodule init % git submodule update
Supposons que vous ayez le contenu suivant dans un fichier texte brut appelé top-20-most-common-english-words.txt (notez que le fichier contient un terme par ligne) :
the be to of and a in that have I it for not on with he as you do at
Ce qui suit vous permet d'interroger son contenu :
importer java.io.InputStream ; importer java.io.OutputStream ; importer java.nio.file.Files ; importer java.nio.file.Path ; importer java.nio.file.Paths ; importer com.github.liblevenshtein.collection. dictionnaire.SortedDawg; importer com.github.liblevenshtein.serialization.PlainTextSerializer; importer com.github.liblevenshtein.serialization.ProtobufSerializer; importer com.github.liblevenshtein.serialization.Serializer; importer com.github.liblevenshtein.transducer.Algorithm; importer com.github.liblevenshtein.transducer.Candidate; importer com.github.liblevenshtein. transducteur.ITransducteur;importation com.github.liblevenshtein.transducer.factory.TransducerBuilder;// ...dictionnaire final SortedDawg;dictionnaire de chemin finalPath = Paths.get("/path/to/top-20-most-common-english-words.txt") ;try (final InputStream stream = Files.newInputStream(dictionaryPath)) { // Le constructeur PlainTextSerializer accepte une spécification booléenne facultative // si le dictionnaire est déjà trié lexicographiquement, par ordre croissant // commande. S'il est trié, alors passer vrai optimisera la construction // du dictionnaire ; vous pouvez passer false si le dictionnaire est trié ou // non (c'est le comportement par défaut et le plus sûr si vous ne savez pas si le // le dictionnaire est trié). Sérialiseur final Serializer = new PlainTextSerializer (false); dictionnaire = serializer.deserialize(SortedDawg.class, stream); }final ITransducer<Candidate> transducer = new TransducerBuilder() .dictionnaire(dictionnaire) .algorithme(Algorithme.TRANSPOSITION) .defaultMaxDistance(2) .includeDistance (vrai) .build();for (final String queryTerm : new String[] {"foo", "bar"}) { System.out.println("+---------------- -------------------------------------------------- -------------"); System.out.printf("| Orthographe candidate pour le terme de requête : "%s"%n", queryTerm); System.out.println("+--------------------------------------------------------- -------------------------------------"); pour (candidat final : transducer.transduce(queryTerm)) {System.out.printf("| d("%s", "%s") = [%d]%n", queryTerm, candidate.term() , candidat.distance()); } }// +---------------------------------------------- ---------------------------------// | Candidats orthographiques pour le terme de requête : "foo"// +-------------------------------------- -----------------------------------------// | d("foo", "do") = [2]// | d("foo", "de") = [2]// | d("foo", "on") = [2]// | d("foo", "à") = [2]// | d("foo", "pour") = [1]// | d("foo", "pas") = [2]// | d("foo", "vous") = [2]// +--------------------------------- ----------------------------------------------// | Candidats orthographiques pour le terme de requête : "bar"// +-------------------------------------- ------------------------------------------// | d("barre", "a") = [2]// | d("barre", "comme") = [2]// | d("bar", "à") = [2]// | d("bar", "être") = [2]// | d("bar", "pour") = [2]// ...
Si vous souhaitez sérialiser votre dictionnaire dans un format facile à lire ultérieurement, procédez comme suit :
Chemin final serializedDictionaryPath = Paths.get("/path/to/top-20-most-common-english-words.protobuf.bytes");try (final OutputStream stream = Files.newOutputStream(serializedDictionaryPath)) { final Serializer Serializer = nouveau ProtobufSerializer(); serializer.serialize(dictionnaire, flux); }
Ensuite, vous pourrez lire le dictionnaire plus tard, de la même manière que vous lisez la version en texte brut :
final SortedDawg deserializedDictionary;try (final InputStream stream = Files.newInputStream(serializedDictionaryPath)) { final Serializer Serializer = new ProtobufSerializer(); deserializedDictionary = serializer.deserialize(SortedDawg.class, stream); }
La sérialisation ne se limite pas aux dictionnaires, vous pouvez également (dé)sérialiser les transducteurs.
Veuillez consulter le wiki pour plus de détails.
Cette bibliothèque est basée en grande partie sur les travaux de Stoyan Mihov, Klaus Schulz et Petar Nikolaev Mitankin : Fast String Correction with Levenshtein-Automata. Pour plus d’informations, veuillez consulter le wiki.
liblevenshtein-java est maintenu par@dylon ([email protected])