Seite 1 von 1

Kölner Phonetik

Verfasst: Montag 22. Dezember 2008, 20:13
von roschi
hallo!

ich habe hier einmal die 'Kölner Phonetik' implementiert.

feedback zum code nehme ich gern entgegen!

Code: Alles auswählen

# -*- coding: iso-8859-15 -*-

"""
Dieses Modul stellt eine Implementation
der 'Kölner Phonetik' dar.

Beispiele zur Verwendung:
>>> encode("Moritz Müller")
'678657'
>>> encode("Moriz Müler")
'678657'
>>> encode("Laura Mayer")
'5767'
>>> encode("Laura Meier")
'5767'
"""

import re

RULETABLE = {re.compile(r".[A|E|I|J|O|U|Y|Ä|Ö|Ü].", re.I):     "0",
             re.compile(r".[B].", re.I):                       "1",
             re.compile(r".[P][^H]", re.I):                    "1",
             re.compile(r".[D|T][^C|S|Z]", re.I):              "2",
             re.compile(r".[F|V|W].", re.I):                   "3",
             re.compile(r"[P][H].", re.I):                     "3",
             re.compile(r".[G|K|Q].", re.I):                   "4",
             re.compile(r"[\b][C][A|H|K|L|O|Q]", re.I):        "4",
             re.compile(r"[^S|Z][C][A|H|K|O|Q|U|X]", re.I):    "4",
             re.compile(r"[^C|K|Q][X].", re.I):                "48",
             re.compile(r".[L].", re.I):                       "5",
             re.compile(r".[M|N].", re.I):                     "6",
             re.compile(r".[R].", re.I):                       "7",
             re.compile(r".[S|Z|ß].", re.I):                   "8",
             re.compile(r"[S|Z][C].", re.I):                   "8",
             re.compile(r"\b[C][^A|H|K|L|O|Q|R|U|X]", re.I):   "8",
             re.compile(r".[C][^A|H|K|O|Q|U|X]", re.I):        "8",
             re.compile(r".[D|T][C|S|Z]", re.I):               "8",
             re.compile(r"[C|K|Q][X].", re.I):                 "8"
            }

def encode(inputstring):
    """
    encode(string) -> string
      Gibt den phonetischen Code des übergebenen Strings zurück.
    """

    encoded = ""
    for i in xrange(len(inputstring)):
        part = inputstring[i - 1:i + 2]
        if len(inputstring) == 1:
          part = " %s " % inputstring[0]
        elif i == 0:
            part = " %s" % inputstring[:2]
        elif i == len(inputstring) - 1:
            part = "%s " % inputstring[i - 1:]
        for rule, code in RULETABLE.iteritems():
            if rule.match(part):
                encoded += code
                break

    while [v for v in RULETABLE.itervalues() if encoded.find(v * 2) != -1]:
        for v in RULETABLE.itervalues():
            encoded = encoded.replace(v * 2, v)

    if encoded:
        encoded = encoded[0] + encoded[1:].replace("0", "")

    return encoded
lg
roschi

Vielen Dank

Verfasst: Freitag 13. März 2009, 12:02
von zwobot
Wollte diese selbst grad implementieren, da hab das hier gefunden. Du hast mir einiges an Arbeit erspart ;) Ich versuche gerade einen Fehlertolerantes Matching von Namen aus 2 Datenquellen zu implemetieren. Erst hab ich es nur mit der Levenshtein-Distanz versucht, jetzt versuche ich die Kölner Phonetik mit dieser zu kombinieren. Also die Levenshtein-Distanz nach Umwandlung in Kölner Phonetik. Die Ergebnisse sind noch nicht wirklich besser. Vielleicht ne Idee das besser zu bewerten?

Gruss
Zwobot

Verfasst: Dienstag 16. Juni 2009, 14:58
von roschi
hallo!

was genau ist denn deni problem? ist es dir nicht tolerant genug?

nenne doch mal ein beispiel, das bei dir nicht funktioniert.

lg
roschi

Re: Kölner Phonetik

Verfasst: Samstag 19. November 2011, 16:49
von nezzcarth
Mir ist klar, dass der letzte Beitrag über zwei Jahre her ist. Allerdings versuche ich mich gerade ebenfalls an einer Implementation.
Was ich mich Frage: Ist das Umschreiben in reguläre Ausdrücke hier tatsächlich der beste Wege?
Ich hatte zunächst begonnen, diese Regeln mit einem dicken If - Elif Block zu verpacken (eine Lösung per Dictionary fiel mir nicht ein).
Welche der beiden Lösungen wäre da performanter? Gibt es noch einen anderen Weg?

Re: Kölner Phonetik

Verfasst: Samstag 19. November 2011, 17:08
von snafu
@nezzcarth: Ein langer If-Elif-Block ist ziemlich hässlich und zudem wenig performant, da ja jeder Ausdruck der Reihe nach ausgewertet werden muss. Bei einem Zugriff auf die Schlüssel eines Wörterbuchs hast du unabhängig von den Auswahlmöglichkeiten immer eine konstante und auch schnelle Zugriffszeit.

Re: Kölner Phonetik

Verfasst: Samstag 19. November 2011, 17:27
von nezzcarth
Ja, das mit dem Dictionary stimmt natürlich, doch wüsste ich nicht, wie ich das Regelwerk darin (wesentlich) anders abbilden sollte, als er, oder als alle 26^3 3er Tupel aufzunehmen. Fraglich ist für mich vorallem, ob die vielen regulären Ausdrücke hier nicht nur leserlicher, sondern auch schneller sind, als eine Schleife, die den String in 3er Gruppen durchgeht und diese dann durch einen Abfrage-Block jagt.

Re: Kölner Phonetik

Verfasst: Samstag 3. Dezember 2011, 19:34
von microkernel

Code: Alles auswählen

>>> encode("Leben")
'516'
>>> encode("Lübyien")
'516'
>>> encode("Lybien")
'516'
Naja "Leben" und "Lybien" klingt jetzt nicht wirklich gleich...

Re: Kölner Phonetik

Verfasst: Samstag 3. Dezember 2011, 19:54
von microkernel
Ok... Ich hab mal geschaut: Nach Soundex und Metaphone sind "Leben" und "Lybien" auch gleich :/

Re: Kölner Phonetik

Verfasst: Samstag 3. Dezember 2011, 23:18
von /me
microkernel hat geschrieben:Naja "Leben" und "Lybien" klingt jetzt nicht wirklich gleich...
Du hast noch nie an einer Kundenhotline gearbeitet, oder?

Re: Kölner Phonetik

Verfasst: Sonntag 4. Dezember 2011, 13:25
von nezzcarth
microkernel hat geschrieben:

Code: Alles auswählen

>>> encode("Leben")
'516'
>>> encode("Lübyien")
'516'
>>> encode("Lybien")
'516'
Naja "Leben" und "Lybien" klingt jetzt nicht wirklich gleich...
Der Algorithmus ignoriert Vokale (mit einigen Ausnahmen), weil diese laut des Autors des ursprünglichen Artikels zu starken Schwankungen unterliegen. Und die Konsonanten, die dann übrig bleiben, sind ja gleich.
Die Idee ist auch nicht ganz verkehrt; die vorkommenden Vokale werden in diesem Fall tatsächlich sehr ähnlich produziert.

Leider laufen die Beispiele aus dem Paper mit Roschis Script nicht vollständig durch (wenn ich beim Abtippen der Beispiele und dem Konvertieren des Scripts nach Python3 keinen Fehler gemacht habe):

Code: Alles auswählen

**********************************************************************
File "colphon_reg.py", line 82, in __main__.colphon
Failed example:
    colphon('CRESZEW')
Expected:
    '4783'
Got:
    '8783'
**********************************************************************
1 items had failures:
   1 of  32 in __main__.colphon
***Test Failed*** 1 failures.
282
Dazu kommen noch ein paar Weitere, die aus Beispielen für Sonderregeln entstammen, die der Wikipediaartikel nicht erwähnt.

Re: Kölner Phonetik

Verfasst: Montag 5. Dezember 2011, 17:23
von microkernel
/me hat geschrieben:
microkernel hat geschrieben:Naja "Leben" und "Lybien" klingt jetzt nicht wirklich gleich...
Du hast noch nie an einer Kundenhotline gearbeitet, oder?
Sollte ich?

Re: Kölner Phonetik

Verfasst: Montag 5. Dezember 2011, 18:15
von /me
microkernel hat geschrieben:
/me hat geschrieben:Du hast noch nie an einer Kundenhotline gearbeitet, oder?
Sollte ich?
Nein. Hättest du das allerdings getan, dann wüsstest du, wie identisch Kunden unterschiedliche Wörter aussprechen können.

Re: Kölner Phonetik

Verfasst: Dienstag 6. Dezember 2011, 13:11
von nezzcarth
/me hat geschrieben: Nein. Hättest du das allerdings getan, dann wüsstest du, wie identisch Kunden unterschiedliche Wörter aussprechen können.
Abgesehen davon darf auch nicht vergessen werden, dass dieser Algorithmus (wie auch SoundEx und weitere) nicht dafür gedacht ist, lautliche Ähnlichkeiten zwischen beliebigen Wörtern abzubilden. Es geht um Nachnamen. 'Die Kölner Phonetik' wurde dafür entwickelt, ähnlich geschriebene Nachnamen in Datenbanken zu finden. Und da gelten teilweise andere Regeln. Außerdem muss man berücksichtigen, dass diese Verfahren alle eine Vermischung zwischen Schrift und Aussprache vornehmen, sodass zwangsläufig manchmal auch grenzwertige Resultate entstehen. Um bessere Resultate erzielen zu können, müsste man die Eingabe erst in eine lautliche Repräsentation überführen. Weil das recht aufwändig ist, behilft man sich dann eben mit solchen Verfahren, und nimmt dann zugunsten des Tempos auch mal kleinere Fehler hin.