Tutorial

Expert-Chatbot Aileen – Part 3 – Robustheit gegenüber Synonymen und Schreibfehlern

Nachdem wir im letzten Post Aileen nun beigebracht haben, dass sie nur auf die wichtigsten Wörter in einem Satz reagieren soll, wollen wir einen Schritt weiter gehen und auch Synonyme und leicht falsch geschriebene Wörter als passende Wörter erkennen. Es passiert sehr oft, dass eine Person aus Versehen zwei zwei Buchstaben im Wort vertauscht oder einen Buchstaben weglässt/vergisst, weil sie zu schnell geschrieben hat. Ein Beispiel dafür ist etwa “Licht” und “Lihct”. Aktuell kann Aileen mit solchen kleinen Rechtschreibfehlern nicht umgehen und wird nur Wörter erkennen, die 100% richtig geschrieben sind.

Eine andere Herausforderung für Aileen ist die Tatsache, dass sie keine Art von Synonymen kennt und wir dadurch jede Frage extra in der Datenbank ablegen müssten. Wobei Synonyme einfach behoben werden kann, indem man alternative Wörter in der Datenbank definiert, ist die Rechtschreibfehler-Resistenz deutlich schwieriger zu erreichen. Deswegen werden wir uns dieses Problem vertieft anschauen.

Die erste Idee, um ein derartiges Problem zu lösen, ist das Hinzufügen eines Wörterbuchs, das alle Wörter auf richtige Schreibung prüft. Wir sind aber nicht daran interessiert alle möglichen Wörter zu korrigieren. Uns reicht es nur die Schlüsselwörter zu korrigieren, auf die Aileen auch reagieren soll.

Wir erreichen das, indem wir nicht mehr nach genauen Übereinstimmungen suchen, sondern indem wir die Wörter nach “Ähnlichkeit” zu unserem original Wort bewerten und dann das Wort mit der Ähnlichkeit, die einen gewissen Wert überschreitet, als “gefunden” anerkennen.

In Pseudo-Code könnten wir den Ansatz so ausdrücken:

Zuerst iterieren wir über jedes Wort und checken auf korrekte Rechtschreibung. Wenn das Wort einen vorgegebene Ähnlichkeit überschreitet, ersetzen wir das alte Word mit dem Neuem. Auf diese Art, sind wir in der Lage Fehler zu minimieren. Wir könnten den Algorithmus weiter verbessern, indem wir das “falsch geschriebene” Wort mit dem ähnlichsten Wort ersetzen lassen. Diese Verbesserungen lassen wir aber für euch offen. Anschließend mappen wir jedes Synonym auf das gemeinsame Wort, damit wir danach unsere einfache Suche, wie in Teil zwei erklärt, durchführen können.

Die restlichen Code-Stücke sollten klar sein. Aber ein großes Fragezeichen bleibt: “Wie berechnet man die Ähnlichkeit von zwei Wörtern?”

Das bringt uns endlich zu dem interessantesten teil. Wie sieht die Funktion “calculateSimilarity” genau aus? Der genaueste Ansatz ist die Levenshtein Distanz zu nehmen, welche Wikipedia definiert als:

Die Levenshtein-Distanz (auch Editierdistanz) zwischen zwei Zeichenketten ist die minimale Anzahl von Einfüge-, Lösch- und Ersetz-Operationen, um die erste Zeichenkette in die zweite umzuwandeln.

Wenn das Prinzip nicht sofort klar wird, keine Sorge, wir werden es uns sowieso nicht näher anschauen. Die Levenshtein Distanz ist zwar sehr exakt, um die Ähnlichkeit von zwei Worten zu messen, aber gleichzeitig von der Performanz her, sehr schwergewichtig. Deswegen berechnen wir die Ähnlichkeit zweier Wörter mit Hilfe von n-Grammen.

Die Grundidee ist, dass wir unsere zwei zu vergleichenden Wörter in Bigramme zerlegen. Bigramme sind genau zwei Zeichen kombiniert in einem “Platz”. Zum Beispiel sieht die Zerlegung des Wortes “Hallo” in Bigramme wie folgt aus: “Ha”, “ll”, “o”. Im nächsten Schritt zählen wir wie oft welches Bigramm vorkommt (sowohl für unser original Wort als auch unser Referenzwort). Je mehr Bigramme diese Worte gemeinsam haben, desto ähnlicher sind sie. Schauen wir uns das einmal an einem kleinen Beispiel an:

Bigrams “favorite”:

  • fa: 1
  • vo: 1
  • ri: 1
  • te: 1

Bigrams “faforite”:

  • fa: 1
  • fo: 1
  • ri: 1
  • te: 1

Nachdem wir jetzt die Bigramme gezählt haben, subtrahieren wir die alle Bigramme voneinander (bezüglich den zwei Worten) und addieren am Ende alle Differenzen auf:

  • fa: 1-1 = 0
  • vo: 1-0 = 1
  • fo: 1-0 = 1
  • ri: 1-1 = 0
  • te: 1-1 = 0

Das resultiert in einer Bigramm-Differenz von 2. In prozent ausgedrückt damit:

1-2/8 = 75%

Das heißt unsere Worte sind zu 75% ähnlich. In an Javascript angelehnten Pseudo-Code ausgedrückt sähe der Algorithmus so aus:

Wenn wir jetzt alles zusammensetzen, erhalten wir den nachfolgenden Chatbot, welcher einfache Verschreiber korrigieren kann und ein paar Synonyme kennt:

Open in new window

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.