Tippfehler - ärgerlich, aber in Zeiten des Smartphones omnipräsent und somit auch eine Herausforderung für Suchmaschinen. Es gibt unterschiedliche Strategien, mit Tippfehlern in einer Suchmaschine umzugehen. Man kann Vorschläge an den Anwender zurückliefern, was gemeint sein könnte, damit der Anwender die Wahl hat - oder man wählt automatisch die wahrscheinlichere Alternative. Alternativ versucht man, eine Suche fuzzy zu gestalten. Entweder indem man nach ähnlichen Termen sucht, die sich nur durch einen Buchstaben unterscheiden. So findet Maas
auch Maus
.
Eine weitere Möglichkeit ist die phonetische Suche. Die Idee ist eine Suche nach ähnlich klingenden Wörter und Lauten in der jeweiligen Sprache. Das heißt, wenn die phonetische Repräsentation eines Wortes ähnlich ist, gelten sie als gleich - unabhängig davon wie anders die beiden Terme geschrieben sind. Ein phonetischer Encoder ist letztlich nichts anderes als ein Hashverfahren mit bestimmten Locality-Eigenschaften.
Aus Sicht der Suchmaschine liegt der Trick in einer unterschiedlichen Speicherung der Terme, basierend auf Algorithmen wie Soundex, Metaphone oder Kölner Phonetik. Anhand von ein paar Beispielen und der Analyze API lässt sich dies für die unterschiedlichen Algorithmen darstellen.
Bevor es allerdings losgeht, muss das phoneticPlugin installiert werden. Bei einer lokalen Installation via
sudo bin/elasticsearch-plugin install analysis-phonetic
In Elastic Cloud kann das phonetic
Plugin über eine Checkbox aktiviert werden. Zeit sich mal genauer mit der Kibana Dev-Tools Console anzuschauen, wie die einzelnen phonetischen Implementierungen Terme im invertierten Index speichern
GET _analyze?filter_path=**.token
{
"text": "Michael Jordan",
"tokenizer": "standard",
"filter": [
{
"type": "phonetic",
"encoder": "metaphone"
}
]
}
Liefert folgendes zurück
{
"tokens" : [
{
"token" : "MXL"
},
{
"token" : "JRTN"
}
]
}
Beiden Terme wurden augenscheinlich stark verändert Aus Michael wird MXL
und aus Jordan
wird JRTN
. Wenn ich als text
in einem zweiten Versuch Micheal Jordon
verwende, bleiben diese beiden daraus erstellten Terme gleich, so dass bei einer Suche mit Typos dieses Dokument noch gefunden wird.
Anstatt des metaphone
Encoders nun ein Test mit dem soundex
Encoder
GET _analyze?filter_path=**.token
{
"text": "Michael Jordan",
"tokenizer": "standard",
"filter": [
{
"type": "phonetic",
"encoder": "soundex"
}
]
}
Zeigt
{
"tokens" : [
{
"token" : "M240"
},
{
"token" : "J635"
}
]
}
Hier sieht man eindeutig, dass sich die unterschiedlichen phonetischen Implementierungen nicht miteinander vergleichen lassen, da sie stark unterschiedliche Terme zurückgeben - im Fall von soundex
eine Kombination aus Buchstaben und Zahlen. Wer sich für die Implementierung interessiert: die Soundex Wikipedia Seite gibt einen guten Überblick. Auch im Fall von Soundex wird man mit einem abgewandelten Term wie Micheal Jordon
die selben Terme zurückbekommen. Das ist allerdings eher ein Zufall, weil soundex Vokale ignoriert, und in diesem Beispiel nur diese modifiziert wurden.
Ein für die deutsche Sprache abgestimmtes Verfahren ist die Kölner Phonetik, indem es im Vergleich zu Soundex einige extra Regeln einführt.
Das folgende Beispiel vergleich zwei ähnlich klingende Namen
GET _analyze?filter_path=**.token
{
"text": "Alexander Aleksander Oleksandr",
"tokenizer": "standard",
"filter": [
{
"type": "phonetic",
"encoder": "koelnerphonetik"
}
]
}
Alle drei zurück gegebenden Token haben den Wert 0548627
. Ein weiteres Beispiel ist der Nachname Meier und seine ähnlichen Varianten.
GET _analyze?filter_path=**.token
{
"text": "Meyer Maier Meier Mayr Meier Mair",
"tokenizer": "standard",
"filter": [
{
"type": "phonetic",
"encoder": "koelnerphonetik"
}
]
}
Auch in diesem Fall wird ein Token zurückgegeben, so dass alle unterschiedlichen Arten von Meyer gefunden werden.
Wie eingangs erwähnt, gibt es noch ein paar Alternativen zur phonetischen Suche, die meistens auch bekannter sind. Neben einer fuzzy Suche kann man angeben ob man nur eine gewisse Anzahl in Termen der Suchabfrage benötigt, damit ein Dokument gefunden wird. Dies funktioniert zum Beispiel über den minimum_should_match
Mechanismus innerhalb des bool
oder match
Queries. Dies macht Sinn für längere Suchanfragen (wie eine Google Suche), aber nicht wenn man nach ähnlichen einzelnen Termen sucht. Ein weiterer Ansatz ist die Verwendung von ngrams oder edge_ngrams. In beiden Fällen werden auch Teile eines Terms im invertierten Index gespeichert und somit suchbar gemacht. Der Nachteil dieser Lösung ist ein weitaus höherer Speicherbedarf. Im Falle von ngram
würde ein Name mit Meier als [M, Me, e, ei, i, ie, e, er, r]
im invertierten Index gespeichert werden.
Für welchen Anwendungsfall ist solch ein phonetische Suche geeignet? Ein
Shop ist weniger ein Anwendungsfall für solch eine phonetische Suche,
aber Unterstützung bei der Eingabe von Vor- und Familiennamen, Adressen
(besonders Straßennamen), Rechtschreibungprüfung, Reduktion von Ambivalenz
bei Speech to Text Konversionen.
Das phonetic
Plugin von Elasticsearch bietet außerdem noch einige weitere
Implementierungen, die man mit eigenen Daten testen kann.
Wer sich tiefergehend informieren möchte, dem liefert diese Arbeit über Aspekte der Kodierung phonetischer Ähnlichkeiten in deutschen Eigennamen einen guten Überblick über das gesamte Thema.