Los transductores Levenshtein aceptan un término de consulta y devuelven todos los términos de un diccionario que se encuentran dentro de n errores ortográficos. Constituyen una clase de correctores ortográficos altamente eficientes (en espacio y tiempo) que funcionan muy bien cuando no necesitas contexto al hacer sugerencias. Olvídese de realizar un escaneo lineal en su diccionario para encontrar todos los términos que estén lo suficientemente cerca de la consulta del usuario, utilizando una implementación cuadrática de la distancia de Levenshtein o distancia Damerau-Levenshtein, estos bebés encuentran todos los términos de su diccionario en tiempo lineal en la longitud del término de consulta (no del tamaño del diccionario, sino de la longitud del término de consulta).
Si necesita contexto, tome los candidatos generados por el transductor como punto de partida y conéctelos a cualquier modelo que esté utilizando para el contexto (por ejemplo, seleccionando la secuencia de términos que tienen la mayor probabilidad de aparecer juntos).
Para una demostración rápida, visite la página de Github, aquí. También hay una interfaz de línea de comandos, blevenshtein-java-cli. Consulte README.md para obtener información sobre adquisición y uso.
Actualmente, la biblioteca está escrita en Java, CoffeeScript y JavaScript, pero pronto la trasladaré a otros lenguajes. Si tiene un idioma específico en el que le gustaría verlo o un sistema de administración de paquetes en el que le gustaría implementarlo, hágamelo saber.
Rama | Descripción |
---|---|
maestro | Última fuente de desarrollo. |
liberar | Lo último, fuente de lanzamiento |
lanzamiento-3.x | Fuente de lanzamiento más reciente para la versión 3.x |
lanzamiento-2.x | Fuente de lanzamiento más reciente para la versión 2.x |
Los problemas se gestionan en waffle.io. A continuación encontrará un gráfico sobre el ritmo al que los he estado cerrando.
Visite Bountysource para prometer su apoyo en los problemas actuales.
En cuanto a la documentación, tienes varias opciones:
wiki
javadoc
Código fuente
blevenshtein ha sido desarrollado contra Java ≥ 1.8. No funcionará con versiones anteriores.
Agregue una dependencia de Maven en Artifactory. Por ejemplo, en un proyecto Gradle, modificarías tus repositories
de la siguiente manera:
repositorios { experto { URL 'https://oss.jfrog.org/artifactory/oss-release-local' } }
Agregue una dependencia de Maven en uno de los siguientes:
Central Maven
JCentro
Bintray
<dependencia> <groupId>com.github.universal-automata</groupId> <artifactId>liblevenshtein</artifactId> <versión>3.0.0</versión> </dependencia>
'com.github.universal-automata:biblevenshtein:jar:3.0.0'
<dependency org="com.github.universal-automata" name="liblevenshtein" rev="3.0.0" />
@Uvas( @Grab(grupo='com.github.universal-automata', módulo='liblevenshtein', versión='3.0.0') )
compilar 'com.github.universal-automata:biblevenshtein:3.0.0'
bibliotecaDependencies += "com.github.universal-automata" % "liblevenshtein" % "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
Supongamos que tiene el siguiente contenido en un archivo de texto sin formato llamado top-20-most-common-english-words.txt (tenga en cuenta que el archivo tiene un término por línea):
the be to of and a in that have I it for not on with he as you do at
A continuación se proporciona una forma de consultar su contenido:
importar java.io.InputStream; importar java.io.OutputStream; importar java.nio.file.Files; importar java.nio.file.Path; importar java.nio.file.Paths; importar com.github.liblevenshtein.collection. diccionario.SortedDawg;importar com.github.liblevenshtein.serialization.PlainTextSerializer;importar com.github.liblevenshtein.serialization.ProtobufSerializer;importar com.github.liblevenshtein.serialization.Serializer;importar com.github.liblevenshtein.transducer.Algorithm;importar com.github.liblevenshtein.transducer.Candidate;importar com.github.liblevenshtein.transducer.ITransducer;importar com.github.liblevenshtein.transducer.factory.TransducerBuilder;// ...final Diccionario SortedDawg;final Ruta diccionarioPath = Paths.get("/path/to/top-20- palabras-en-inglés-más-comunes.txt");try (flujo de entrada final = Files.newInputStream(dictionaryPath)) { // El constructor PlainTextSerializer acepta una especificación booleana opcional // si el diccionario ya está ordenado lexicográficamente, en orden ascendente // orden. Si está ordenado, pasar verdadero optimizará la construcción. // del diccionario; puede pasar false ya sea que el diccionario esté ordenado o // no (este es el comportamiento predeterminado y más seguro si no sabes si el // el diccionario está ordenado). serializador final Serializador = nuevo PlainTextSerializer (falso); diccionario = serializer.deserialize(SortedDawg.class, flujo); }final ITransducer<Candidato> transductor = nuevo TransducerBuilder() .diccionario(diccionario) .algoritmo(Algoritmo.TRANSPOSICIÓN) .defaultMaxDistance(2) .includeDistance (verdadero) .build();for (final String queryTerm : new String[] {"foo", "bar"}) { System.out.println("+---------------- -------------------------------------------------- -------------"); System.out.printf("| Candidatos de ortografía para el término de consulta: "%s"%n", queryTerm); System.out.println("+------------------------------------------ -------------------------------"); for (candidato candidato final: transducer.transduce(queryTerm)) {System.out.printf("| d("%s", "%s") = [%d]%n", queryTerm, candidato.term() , candidato.distancia()); } }// +---------------------------------------------- ---------------------------------// | Candidatos de ortografía para el término de consulta: "foo"// +-------------------------------------- -----------------------------------------// | d("foo", "hacer") = [2]// | d("foo", "de") = [2]// | d("foo", "on") = [2]// | d("foo", "a") = [2]// | d("foo", "para") = [1]// | d("foo", "no") = [2]// | d("foo", "tú") = [2]// +--------------------------------- ----------------------------------------------// | Candidatos de ortografía para el término de consulta: "bar"// +-------------------------------------- -----------------------------------------// | d("barra", "a") = [2]// | d("barra", "como") = [2]// | d("barra", "en") = [2]// | d("barra", "ser") = [2]// | d("barra", "para") = [2]// ...
Si desea serializar su diccionario en un formato que sea fácil de leer más adelante, haga lo siguiente:
Ruta final serializedDictionaryPath = Paths.get("/path/to/top-20-most-common-english-words.protobuf.bytes");try (final OutputStream stream = Files.newOutputStream(serializedDictionaryPath)) { final Serializer serializer = nuevo ProtobufSerializer(); serializer.serialize(diccionario, secuencia); }
Luego, podrás leer el diccionario más tarde, de la misma manera que lees la versión de texto plano:
final SortedDawg deserializedDictionary;try (final InputStream stream = Files.newInputStream(serializedDictionaryPath)) { final Serializer serializer = new ProtobufSerializer(); deserializedDictionary = serializer.deserialize(SortedDawg.class, flujo); }
La serialización no se limita a diccionarios; también puede (des)serializar transductores.
Consulte la wiki para obtener más detalles.
Esta biblioteca se basa en gran medida en el trabajo de Stoyan Mihov, Klaus Schulz y Petar Nikolaev Mitankin: Fast String Correction with Levenshtein-Automata. Para obtener más información, consulte la wiki.
blevenshtein-java es mantenido por@dylon ([email protected])