Berechnen der Levenshtein-Entfernung schnell

24

Suchen Sie aus einer riesigen Datenbank mit zulässigen Wörtern (alphabetisch sortiert) und einem Wort das Wort aus der Datenbank, das dem angegebenen Wort in Bezug auf die Levenshtein-Entfernung am nächsten liegt.

Der naive Ansatz besteht natürlich darin, einfach den Abstand zwischen dem angegebenen Wort und allen Wörtern im Wörterbuch zu berechnen (wir können eine binäre Suche in der Datenbank durchführen, bevor wir die Abstände tatsächlich berechnen).

Ich frage mich, ob es eine effizientere Lösung für dieses Problem gibt. Vielleicht eine Heuristik, mit der wir die Anzahl der zu durchsuchenden Wörter reduzieren können, oder Optimierungen des Abstandsalgorithmus.

Links zu Beiträgen zum Thema sind willkommen.

Joshua Herman
quelle

Antworten:

16

Was Sie fragen, ist das Problem der Suche in der Nähe des Nachbarn unter der Bearbeitungsentfernung. Sie haben nicht erwähnt, ob Sie an theoretischen Ergebnissen oder an Heuristiken interessiert sind, deshalb beantworte ich erstere.

Die Bearbeitungsentfernung ist für die Erstellung von Suchstrukturen in der Nähe von Nachbarn etwas unangenehm. Das Hauptproblem ist, dass sich eine Metrik wie andere bekannte schlechte Metriken wie um die Dimensionalität zu reduzieren und zu approximieren. Zu diesem Thema gibt es ziemlich viel zu lesen, und Ihre beste Quelle ist die Reihe von Artikeln von Alex Andoni : Wenn Sie den Rückwärtszeigern folgen (zum Beispiel aus seinem FOCS 2010-Artikel), erhalten Sie eine gute Reihe von Quellen.1

Suresh Venkat
quelle
1
Alles, was ich über metrische Räume weiß, stammt aus der Semantik, also eine Frage: Gibt es anständige (für jeden Wert anständige) Einbettungen der Levenshtein-Metrik in eine Ultrametrik? In Kürze könnte dies zu einem Algorithmus mit binären Bäumen führen.
Neel Krishnaswami
Ich bin mir nicht ganz sicher. Ich vermute, die Antwort ist im Allgemeinen nein, aber ich habe nichts, auf das ich hinweisen kann.
Suresh Venkat
Die zweite Veröffentlichung auf boytsov.info/pubs bietet einen guten Überblick über mögliche Lösungen für die Suche in der Nähe von Nachbarn unter der Bearbeitungsentfernung Levenshtein und Damereau-Levenshtein.
a3nm
@NeelKrishnaswami Eine Einbettung in eine Ultrametrie würde eine Verzerrung von mindestens wobei die Stringlänge ist. Dies ergibt sich aus einer Verzerrungsuntergrenze für die Einbettung in aufgrund von Krauthgamer und Rabani , da die Ultrametrie isometrisch in den euklidischen Raum einbettet, der isometrisch in einbettet . d L 1 L 1Ω(Logd)dL1L1
Sasho Nikolov
5

Wenn Sie eine kleine Anzahl von Fehlbearbeitungen tolerieren, können Sie versuchen, einen gepunkteten Suffixbaum zu verwenden . Haftungsausschluss: Ich habe dieses Papier geschrieben, aber es löst, was Sie wollen: Es hat hohe Speicherplatzkosten, aber die Abfragen sind sehr schnell.

Im Allgemeinen ist es besser, es anders herum zu betrachten: Sie haben einen Index aller Wörter im Wörterbuch. Stoppen Sie nun für ein eingegebenes Wort w, falls es sich im Wörterbuch befindet. Andernfalls generieren Sie alle Variationen im Abstand 1 und suchen Sie nach diesen. Wenn sie nicht da sind, suchen Sie nach Variationen in Abstand 2 und so weiter ...

An dieser Grundidee gibt es mehrere Verbesserungen.

Luispedro
quelle
1
Sie sollten einen Link zu Ihrem reproduzierbaren Forschungsarchiv für das Papier enthalten haben .
Dan D.
4

O(mk+1σk)mσk

Jouni Sirén
quelle
4

Ich habe eine Antwort auf eine sehr ähnliche Frage unter cs.stackexchange.com ( /cs//a/2096/1490 ) geschrieben und dann diese Frage gefunden. Dort lautet die Antwort für eine ungefähre Suche nach einem nahen Nachbarn in der Bearbeitungsentfernung (dh der Algorithmus gibt eine Zeichenfolge aus, die ungefähr so ​​nah an der Abfragezeichenfolge liegt wie der nächste Nachbar der Abfragezeichenfolge). Ich poste hier, da ich in den hier gegebenen Antworten keine der Referenzen finde, die ich dort angegeben habe.

Sasho Nikolov
quelle
3

Ich denke, was Sie wollen, ist der Wagner-Fischer-Algorithmus: https://en.wikipedia.org/wiki/Wagner%E2%80%93Fischer_algorithm Die wichtigste Erkenntnis ist, dass das Wörterbuch, das Sie durchlaufen, zwei aufeinanderfolgende Wörter enthält haben sehr wahrscheinlich ein langes Präfix, sodass Sie nicht die gesamte Matrix für jede Entfernungsberechnung aktualisieren müssen.

Björn Lindqvist
quelle
2

Sie können verwenden, Meinten Sie?

Suchen Sie dann den Levenshtein-Abstand zwischen der Antwort, die von "Meinten Sie" zurückgegeben wurde, und der Eingabezeichenfolge mithilfe der dynamischen Programmierung.

Pratik Deoghare
quelle
Ich verstehe diese Antwort nicht. Die Frage ist, wie man effizient ein Wort in einem großen Wörterbuch mit geringer Levenshtein-Entfernung zu einer bestimmten Eingabe finden kann, nicht wie man die Levenshtein-Entfernung berechnet oder wie man die Ausgabe einer Blackbox-Rechtschreibprüfung vergleicht ...
Huck Bennett
@Huck Bennett: Ich dachte, @Grigory Javadyan baut ein Did you mean?Feature. Außerdem wird Did you mean?das Wort zurückgegeben, das der angegebenen Eingabe sehr nahe kommt und diese sehr effizient ausführt. :)
Pratik Deoghare
Ich denke, deine Ideen sind gut, aber es scheint, dass Grigory nach etwas Tieferem und Spezifischerem fragt.
Huck Bennett
@Huck Bennett: Ja du hast recht! :)
Pratik Deoghare
-1

Eine Möglichkeit besteht darin, ein maschinelles Lernmodell zu trainieren, um die Wörter auf Vektoren abzubilden und die Levenshtein-Distanz auf die euklidische Distanz abzubilden. Dann können Sie einen KDTree aus den Vektoren für das Wörterbuch erstellen, das Sie verwenden möchten. Ich habe hier ein Jupyter-Notizbuch erstellt: https://gist.github.com/MichaelSnowden/9b8b1e662c98c514d571f4d5c20c3a03

Wie laut DW's Kommentare:

  1. Trainingsablauf = stochastischer Gefälleabstieg mit adaptiven Gefällen
  2. Verlustfunktion = mittlerer quadratischer Fehler zwischen wahrer Editierentfernung und euklidischer Entfernung
  3. Trainingsdaten = zufällige Zeichenfolgen mit einer Länge zwischen 1 und 32 Zeichen (könnte durch Daten verbessert werden, die einer tatsächlichen Verteilung der gängigen Tippfehler entsprechen)
  4. Quantitative Ergebnisse: Nach dem Training für ungefähr 150 Epochen mit einer Stapelgröße von 2048 (Wandzeit = ungefähr eine Minute) unter Verwendung von Worteinbettungen von 512 Dimensionen mit einer verborgenen Schicht der durchschnittliche absolute Fehler zwischen der tatsächlichen Bearbeitungsentfernung und der vorhergesagten Bearbeitungsentfernung liegt bei etwa 0,75, was bedeutet, dass die vorhergesagte Bearbeitungsentfernung ungefähr ein Zeichen abweicht

Zusammenfassung der Modellstruktur:

  1. Erstellen Sie eine gelernte Einbettung für jedes Zeichen, einschließlich des Nullzeichens (wird später verwendet, um Text unter der Zeichenbeschränkung nach rechts zu füllen).
  2. Fülle die rechte Seite des Textes mit dem Null-Zeichen auf, bis das Zeichenlimit erreicht ist (32)
  3. Verketten Sie diese Einbettungen
  4. Führen Sie die Einbettungen durch ein Feed-Forward-neuronales Netz, um eine niederdimensionale Worteinbettung (512-dimensional) zu erzeugen.
  5. Tun Sie dies für beide Wörter
  6. Finden Sie den euklidischen Abstand zwischen den Vektoren
  7. Stellen Sie den Verlust als mittleren quadratischen Fehler zwischen der tatsächlichen Levenshtein-Distanz und der euklidischen Distanz ein

Meine Trainingsdaten sind nur zufällige Zeichenfolgen, aber ich denke, die Ergebnisse könnten sich wirklich verbessern, wenn die Trainingsdaten (Tippfehler / korrektes Wort) Paare wären. Am Ende habe ich nur verwendet, /usr/share/dict/wordsweil es allgemein verfügbar ist.

Michaelsnowden
quelle
2
Wie trainiert man ein ML-Modell, damit Wörter, die in Levenshtein in der Nähe sind, auf ähnliche Vektoren abgebildet werden? Welches Trainingsverfahren und welche Verlustfunktion verwenden Sie dafür? Können Sie die Methode in Ihrer Antwort zusammenfassen, sodass die Antwort auch dann noch nützlich ist, wenn der Link nicht mehr funktioniert und wir nicht in Ihrem Notizbuch nachschlagen müssen, um die von Ihnen verwendete Methode zu verstehen? Können Sie auch beurteilen, wie gut es auf quantitative Weise funktioniert? Ist das besser als die Alternativen?
DW
So wie es aussieht, ist dies (glaube ich) eine schlechte Passform für CSTheory. Das heißt, keine Vorstellung davon, was speziell vorgeschlagen wird, und keine theoretische Rechtfertigung dafür.
Clement C.
@DW Entschuldigung - ich habe eine ziemlich umfangreiche Bearbeitung vorgenommen, die umfassend sein sollte, falls der Link ausfällt (oder falls Sie nicht durch das Notizbuch stöbern möchten). Obwohl dies keine wirkliche CS-Theorie ist, weil es keine Forschung ist, halte ich es für einen praktischen Ansatz, da es sowohl für das Training als auch für die Schlussfolgerung schnell und einfach ist.
Michaelsnowden
1
Du trainierst auf zufälligen Saiten. Der erwartete Levenshtein-Abstand zwischen zwei solchen Saiten entspricht ungefähr der Länge der längeren Saite. Daher ist es sehr einfach, diesen Abstand auf zufälligen Zeichenfolgen zu schätzen, aber dies ist für den Umgang mit Daten aus der realen Welt nicht hilfreich. Ich vermute, Ihre Einbettungen kodieren möglicherweise nur die Länge der Zeichenfolge, und daher haben Sie möglicherweise eine ausgefallene Methode entwickelt, um etwas Triviales und Nutzloses zu tun. Dies ist ein Problem bei der Verwendung von ML. Es ist sehr empfindlich auf die Verlustfunktion, die Sie verwenden.
DW
@DW Wenn Sie sich die Ergebnisse im Notizbuch ansehen, ergab der Abruf anständige Ergebnisse - nicht nur Zeichenfolgen mit derselben Länge. Ich würde Sie wirklich ermutigen, es zu überfliegen. Ich würde es nicht trivial und nutzlos nennen.
Michaelsnowden