Wall·E: Automatische Korrektur allgemeiner Tagging-Tippfehler?

Mahlzeit. Nach einigen Monaten relativer Ruhe habe ich noch einmal einen möglichen Vorschlag für eine Korrektur durch Wall·E, und zwar die Korrektur falsch geschriebener Tagschlüssel und -werte, also Dinge wie maxspeeed->maxspeed.
xybot hat seinerzeit ähnliche Bearbeitungen durchgeführt. Bei dem Meinungsbild vor knapp einem Jahr hatte ich diese Korrekturgruppe nicht aufgeführt; insofern stellt sich als erstes die Frage, ob derlei überhaupt wünschenswert ist. Ein gewisses Aufkommen falsch geschriebener Tags ist jedenfalls nicht zu verneinen, wenn man etwa mittels der /browse/changesets-Seite verfolgt, in welchem Umfang entsprechende Korrekturen händisch durchgeführt werden. Eine gewisse Entlastung scheint mir schon sinnvoll, eingeschränkt natürlich auf Fälle, die nach menschlichem Ermessen eindeutig sind.

Angenommen, es gibt ein positives Votum: wie sollen die Korrekturprozesse strukturiert werden? In einem der anderen Fäden zu Wall·E ist mal der Vorschlag angeklungen, man könnte die Korrekturen gleich anhand unscharfer Übereinstimmung mit dem Zielwert vornehmen: also etwa alles, was beispielsweise eine Editierdistanz von 1 zu building hat, durch building ersetzen. Ich bin da zurückhaltend und würde lieber mit einer expliziten Liste zu ersetzender Zeichenketten arbeiten, um unliebsamen Überraschungen zu entgehen. Nachteil: was nicht auf der Liste steht, wird auch nicht korrigiert. Die Liste müßte also kontinuierlich erweitert werden.

Es gibt eine Liste von xybot. Die möchte ich aber lieber nicht benutzen, weil sie auch einige Reinterpretationen enthält. Stattdessen würde ich basierend auf dem tatsächlichen, aktuellen Aufkommen eine komplett neue Liste aufsetzen (erste Kandidaten dafür siehe unten).

Ferner wäre zu klären, wie der Regelsatz aufgestellt und diskutiert werden soll. Die Liste der Ersetzungsregeln wird sukzessive wachsen; muß jede Neuaufnahme vorgestellt und diskutiert werden? Oder reicht es, das grundsätzliche Einverständnis des Forums einzuholen, und Ergänzugen nur in größeren Abständen in größeren Paketen vorzustellen? Oder Neuerungen einfach ohne Diskussion/Vorstellung einpflegen, solange sie sich in das Muster der bereits vorhandenen einfügen? Die aktuell verwendete Liste müßte natürlich in jedem Fall offenliegen.

Um dem ganzen etwas Substanz zu verleihen, einige Beispiele. Falsche Schreibweisen gibt es sowohl in Schlüssel als auch in Werten. Ich habe mir als ersten Schritt die in DE vorkommenden Schlüssel angesehen und nach Paaren von Schlüsseln gesucht, die eine Levenshtein-Distanz von 1 aufweisen und von denen einer mindestens 500mal häufiger vorkommt als der andere. Dieses Kriterium dient nur der Suche und muß noch ein wenig verfeinert werden, liefert aber bereits einige interessante Kandidaten.

Die meisten der folgenden aus dem Feld der Adresstags scheinen mir ziemlich eindeutig (in Klammern jeweils die Häufigkeit im Geofabrik-Extrakt):

key add:city (72) might be a misspelling of key addr:city (3887819)
key adddr:city (35) might be a misspelling of key addr:city (3887819)
key adde:city (138) might be a misspelling of key addr:city (3887819)
key addr.city (38) might be a misspelling of key addr:city (3887819)
key addr::city (3) might be a misspelling of key addr:city (3887819)
key addr:ciry (2) might be a misspelling of key addr:city (3887819)
key addr:ciy (2) might be a misspelling of key addr:city (3887819)
key addr:dity (1) might be a misspelling of key addr:city (3887819)
key addr:sity (5) might be a misspelling of key addr:city (3887819)
key addr;city (2) might be a misspelling of key addr:city (3887819)
key addr_city (16) might be a misspelling of key addr:city (3887819)
key adr:city (16) might be a misspelling of key addr:city (3887819)
key add:country (57) might be a misspelling of key addr:country (3398437)
key addr.country (63) might be a misspelling of key addr:country (3398437)
key addr:counry (1) might be a misspelling of key addr:country (3398437)
key addr:county (50) might be a misspelling of key addr:country (3398437)
key addr:coutry (7) might be a misspelling of key addr:country (3398437)
key addr:ountry (1) might be a misspelling of key addr:country (3398437)
key addr_country (7) might be a misspelling of key addr:country (3398437)
key adr:country (1) might be a misspelling of key addr:country (3398437)
key add:housename (1) might be a misspelling of key addr:housename (30914)
key addr:housenumber2 (1) might be a misspelling of key addr:housenumber (4554402)
key addr:housenumberf (2) might be a misspelling of key addr:housenumber (4554402)
key add:postcode (4) might be a misspelling of key addr:postcode (3963213)
key add:street (3) might be a misspelling of key addr:street (4497705)
key addr::street (1) might be a misspelling of key addr:street (4497705)
key addr:street2 (1) might be a misspelling of key addr:street (4497705)
key add:suburb (277) might be a misspelling of key addr:suburb (292765)
key addR:suburb (1) might be a misspelling of key addr:suburb (292765)
key addr_suburb (13) might be a misspelling of key addr:suburb (292765)

Auch bei Gebäuden, insbesondere den neumodischen 3D-Tags, gibt es einige recht klare Fälle:

key Building (1) might be a misspelling of key building (11592169)
key bulding (2) might be a misspelling of key building (11592169)
key building:coulor (2) might be a misspelling of key building:color (3474)
key building_color (1) might be a misspelling of key building:color (3474)
key building;colour (1) might be a misspelling of key building:colour (28846)
key building_height (1) might be a misspelling of key building:height (30333)
key building;levels (1) might be a misspelling of key building:levels (118554)
key building_levels (2) might be a misspelling of key building:levels (118554)
key builging:levels (1) might be a misspelling of key building:levels (118554)
key bulding:material (10) might be a misspelling of key building:material (22029)
key building_part (3) might be a misspelling of key building:part (15636)
key building_type (3) might be a misspelling of key building:type (26642)
key building_type:de (1) might be a misspelling of key building:type:de (993)

Gegenbeispiele: Bei Sprachzusätzen (:XX) versagt das Suchkriterium völlig.

key name:dv (11) might be a misspelling of key name:de (5837)
key name:dz (11) might be a misspelling of key name:de (5837)
key name:sn (1) might be a misspelling of key name:en (2887)

In anderen Fällen müßte man mal näher hinsehen, Beispiele:

key marking (12) might be a misspelling of key parking (113651)
key tower (156) might be a misspelling of key power (545828)

Oder man findet zwar ein falsches Tag, aber die Zuordnung durch den Algorithmus muß nicht notwendigerweise stimmen (das auch als Argument, warum ich keine Änderung allein anhand der Editierdistanz vornehmen möchte):

key biking (2) might be a misspelling of key hiking (39475)

Da wir British English verwenden, sollte es wohl eher colour heißen. Ansonsten bin ich dafür.

Generell sinnvoll.
Ich weiß nicht, ob es einen Vorteil brächte, wenigstens ein paar reguläre Ausdrücke zu verwenden, um die Liste zu verkleinern.
Beispiel: Schlüssel addrcity ( aus :: ; _ u.ä).
Levenshtein allein halte ich auch für zu gefährlich (für einen Bot).

building:colour ist mit 28846 gelistet, color (3474) liegt aber näher an coulor, Handarbeit ist also nicht zu vermeiden.

Zusatz: Es sei denn, man schaltet in diesem Fall einen Durchgang building:color → building:colour vor.
Über mehrere konsekutive Durchläufe ließe sich die Liste vermutlich verkürzen.

Sinnvoll ist das meiner Meinung nach auf jeden Fall und von meiner Seite auch erwünscht.

Explizite Liste dürfte besser sein (denken wir nur an Gleis-trasse versus Glei-straße).

In der Fixbot-Liste sind in der Tat einige eigenwillige Zuordnungen wie amenity=Parkplatz → amenity=parking (fiktives Beispiel).

Für den Anfang sollten neue Regeln erst einmal diskutiert werden. Wenn sich das Verfahren stabilisiert hat, reicht vielleicht eine Ankündigung.
Man sollte für jede Änderung eine Testphase einbauen, in der die Treffer zwar gelistet, jedoch noch nicht geändert werden. So hat man die Chance falsche Treffer vor Änderung zu finden. Dabei würde kleine Änderungen ein kurze Testphase und umfangreichere Änderungen eine ausführlichere Testpase bedeuten.

Dein Kriterium zur Suche einer Kandidaten-Liste scheint mir durchaus geeignet.
Ob nun genau 1:500 die Schwelle sein muss, darüber kann man diskutieren. Fürs Erste würde ich das so lassen. Man kann das später immer noch auf 1:400 oder weniger reduzieren.

Da hast du ja bereits so einige problematische / nicht zwingend eindeutige Fälle gefunden. EIn klarer Hinweis

Für Schlüsseln die als <Hauptschlüssel><Unterschlüssel> aufgebaut sind (wie addr:= oder building:=), würde ich ein mehrstufiges Vorgehen vorschlagen:

  • Testen auf die Struktur
  • Übernahme/Korrektur Hauptschlüssel
  • Übernahme/Korrektur Trennzeichen
  • Übernahme/Korrektur Unterschlüssel

Bei Adressen gibt es ja einen Fall, der schwierg zu lösen sein wird: addr:country (Land) und addr:county (Kreis) liegen sehr nahe beieinander. Da der erste aber nur formale Werte (ISO-Ländercodes) enthalten soll und der zweite im Wesentlichen Freitext enthält, kann man da gegebenenfalls doch etwas retten. Solange du nur Deutschland behandelst, entfällt addr:county, da Kreise in DE nicht für die Adresse verwendet werden.

PS: Wie bisher wäre eine Liste mit Fällen, die der Algorythmus nicht lösen kann, hilfreich für händische Korrekturen (z.B. addr:xyz=*).

Edbert (EvanE)

Hallo,

mir ist aufgefallen, dass z.B. in Deutschland auch häufig fälschlicherweise das Komma als Dezimaltrenner verwendet wird - bei width=* habe ich das sehr oft bemerkt. Da könnte der Bot ja auch in der ersten Zeit (z.B. einige Wochen) alle Vorkommen eines Kommas im Value sammeln, um dann von Hand zu entscheiden, welche Werte für den Key verwendet werden sollen, in denen er bei gefundenem Komma dieses durch Punkt ersetzt werden soll (width, height, …).

Franz

@Oli-Wan.
Ich finde das eine super Idee.
Denk bitte auch an den ganzen turn:lanes-Bereich. Keys wie “turn:lanes:backward” oder values wie “left|slight_left|through|through;right” sind nicht nur aufgrund der vielfältigen Kombinationsmöglichkeiten sehr fehleranfällig, wie ich aus eigener Erfahrung weiß.

Oli-Wan, bezüglich der Sprachzusätze in den Tags wäre ein denkbarer Ansatz (der sich auch in einen regulären Ausdruck gießen lassen sollte), dass vor der Levenshtein-Distanz-Überprüfung zunächst sichergestellt wird, dass Bestandteile vor/nach Doppelpunkten aus mehr als zwei (Parameter) Zeichen bestehen.

Ein Tag “turn:lanes:backward” würde in die drei Bestandteile “turn”, “lanes”, “backward” zerlegt werden. Jeder dieser Bestandteile kann einzeln der Levenshtein-Distanz-Überprüfung unterzogen werden, da er jeweils aus mehr als zwei (Parameter) Zeichen besteht.

Gegenbeispiel: Ein Tag “namee:dk” wird zunächst in die Bestandteile “namee” und “dk” zerlegt. Der Bestandteil “namee” ist lang genug und wird überprüft und auf “name” korrigiert. Der Bestandteil “dk” ist zu kurz und wird folglich nicht modifiziert.

Ich halte das für eine sehr gute Idee.

Auf jeden Fall ist klar ersichtlich, dass es eine feste Liste braucht, eine vollautomatische Korrektur scheidet aus, wie man an verschiedenen Beispielen sieht. Außerdem würde es das sonst völlig unmöglich machen, neue Tags einzuführen, die etablierten sehr ähnlich sind.

Grundsätzlich scheint mir aber dein Ansatz zur Generierung von Kandidaten nicht schlecht, auch wenn wahrscheinlich ein Verhältnis < 500 und eine Levenshtein-Distanz von 2 noch einige gute Kandidaten bringen könnte - aber natürlich auch wesentlich mehr falsch-positive, die man aussortieren muss.

Da muss man aber aufpassen, dass man z.B. addr:country=Deutschland nicht in addr:county=Deutschland ändert, weil der Wert ja kein Ländercode ist.

An dem Algorithmus für die Suche nach möglichen Vertippern (der, wie gesagt, nur Kandidaten für die anschließend noch manuell zu prüfende Liste liefern soll) bastle ich noch; die angegebenen Parameter waren der allererste Versuch (abgesehen von Testläufen auf kleineren Extrakten). Zum einen war das Programm noch zu langsam, was aber mittlerweile halbwegs unter Kontrolle ist (gestern etwa 2 Stunden für DE, heute 5 Minuten).
zum anderen müssen die Kriterien und Parameter noch verbessert werden. Als ersten Schritt bin ich von Levenshtein auf Damerau-Levenshtein umgestiegen, sodaß nun auch die wichtige Klasse der Nachbartranspositionen als nur ein Schritt zählt. Übereinstimmung bis auf Groß-/Kleinschreibung etwa wäre auch noch interessant, oder “Abkürzungen” (mit bui könnte eher building als bus gemeint gewesen sein). Ob die dann letztendlich in der Korrekturliste landen oder nur helfen, Ambiguitäten zu finden (konkret: die Ersetzung bui->bus auszuschließen), ist eine andere Frage. Ein Abfallprodukt könnte in der Tat, wie von EvanE skizziert, eine Sammlung nicht automatisch korrigierbarer Fehler sein, auf daß Mapper sich gezielt darum kümmern können.

Edit: Beispiele. Vertauschungen:


key caapcity (1) might be a misspelling of key capacity (8450)
key cosntruction (2) might be a misspelling of key construction (1839)
key shpo (1) might be a misspelling of key shop (45652)

“Abkürzungen”; der Algorithmus liefert natürlich alle, nicht nur die naheliegendsten - was aber auch kein Nachteil ist, sondern gerade die Mehrdeutigkeit aufzeigt.


key bui (8) might be a misspelling/shortcut of key building (2409980)
key bui (8) might be a misspelling/shortcut of key building:colour (13175)
key bui (8) might be a misspelling/shortcut of key building:levels (35453)
key bui (8) might be a misspelling/shortcut of key building:material (9846)
key bui (8) might be a misspelling/shortcut of key building:roof (5353)
key bui (8) might be a misspelling/shortcut of key building:roof:shape (4901)
key bui (8) might be a misspelling/shortcut of key building:type (6072)
key bui (8) might be a misspelling/shortcut of key building:use (11707)
key bui (8) might be a misspelling of key bus (20048)

@PeterPablo: die Idee der Trennung in Subtags werde ich mal im Hinterkopf behalten, danke dafür. Für den Moment schaue ich nur auf die kompletten Schlüssel. Aber letztlich müssen gar nicht alle Tippfehler gefunden werden; die zu erstellende Liste von Korrekturregeln kann ja jederzeit manuell erweitert werden.

In Deutschland und vermutlich den meisten Ländern in Mitteleuropa ist das wie gesagt kein reales Problem, da die Kreise anders als z.B. in den USA nicht für Adressen verwendet werden.

Unabhängig davon, bleibt festzuhalten, dass eine Korrektur von addr:country nach addr:county nicht sinnvoll wäre. Die Adress-Korrekturen beheben ja zum Glück eine Vielzahl von addr:country-Fehlern, dort wo diese ausgeführt werden.

Die Frage bleibt, ob es sinvoll wäre addr:county=DE/UK/FR/… zu addr:country=* zu korrigieren. Na ja, das gehört wohl eher zu den Adress-Korrekturen.

Edbert (EvanE)

Es ist ja nicht nur country<->county. Was würde denn ein automatisches System aus add:count=Deutschland machen? Distanz zu addr:county ist 1, zu addr:country 2 und der Inhalt ist offensichtlich kein Ländercode. Also im Umfeld dieser beiden Tags wäre ich vorsichtig. Höchstens wenn wirklich ein Ländercode im Wert steht, könnte man auf addr:country schließen - aber auch da ist die Frage, ob es nicht Kürzel für Landkreise gibt, die wie Ländercodes aussehen.

Ich denke, es kommt auf den ursprünglichen Schlüssel an. Bei add:country, addr_country und ähnlichen kommt meines Erachtens nur addr:country als Ersetzungsziel in Frage. addr:count bleibt dagegen wegen der Ambiguität country/county außen vor (wobei country OSM-weit laut Taginfo sogar noch 100-mal häufiger ist als county, in Geofabrik-DE gar 68k-mal, sodaß die Fehlerquote bei Ersetzung durch country vermutlich minimal wäre).
Auf eine Kontrolle des Wertes (hier: Ländercode oder nicht) würde ich in diesem Zusammenhang lieber verzichten, da dies den Algorithmus enorm verkomplizieren würde. Ohne solche Sonderfälle kann einfach der vorhandene Tagschlüssel gegen eine Liste abgeglichen und ggf. die Ersetzung vorgenommen werden. Der Algorithmus ist klein (bereits implementiert: inklusive rudimentärer Dokumentation, Buchhaltung und Output 22 Zeilen Emacs Lisp), groß wird nur die Liste der Ersetzungsregeln. Mit allerlei Sonderfällen wird auch der Algorithmus groß und die Programmierung fehleranfällig. Vor diesem Hintergrund überlasse ich addr:count und ähnliche Beispiele lieber einem stärker spezialisierten Werkzeug oder gleich menschlichen Mappern.

Grundsätzlich halte ich die automatische Korrektur insbesondere in Schlüsseln und Werten von Festwert-Tags für sehr sinnvoll, da es dort sehr viel mehr sichere Korrekturmöglichkeiten als bei Straßennamen etc. geben dürfte.

Einige Ideen dazu:

  • Es ist nicht nur die Wahrscheinlichkeit des Tippfehlers, sondern auch die Wahrscheinlichkeit relevant, dass dieser nicht erkannt wurde. Zur Beurteilung einer unscharfen Übereinstimmung sollte man daher wohl nicht nur die Editierdistanz, sondern auch die optische Ähnlichkeit berücksichtigen.
    Beispielsweise soll eine Abweichung beim ersten und letzten Buchstaben besonders auffällig sein.

  • Bei der Beurteilung der unscharfen Übereinstimmung von Schlüsseln sollte man auch die Unscharfe übereinstimmung mit aus Festwerten gebildeten Tags einbeziehen. Beispielsweise könnte für ein surface=gravel das surface durch Tippfehler schon arg verunstaltet sein und immer noch sicher erkannt werden.

  • Könnte der Bot das Wiki nach gültigen Schlüsseln und Tags absuchen? Dies könnte z.B. als Sicherheitsmechanismus eingesetzt werden.

  • Wieviel verschiedene Schlüssel haben wir überhaupt in der Datenbank? Dies könnte eine ungefähre Abschätzung ergeben, wie lang die Ersetzungsliste sein muss, da man wohl davon ausgehen kann, dass die meisten Schlüssel Tippfehler sind.

Ich stimme errt und dir zu, addr:count(r)y sollte man einfach nicht bearbeiten, damit passieren zu leicht Fehler (addr:contry → addr:country mag noch gehen).

Ebenso stimme ich dir zu, dass die Berücksichtigung von Werten für Schlüssel-Korrekturen in der Regel zu aufwändig wären. Fürs Erste das also außen vor lassen. Auf Dauer vielleicht bei speziellen Fällen.

Wenn es an die Korrektur von Werten geht, sollte man die Schlüssel natürlich berücksichtigen (tootway → footway, nur wenn der Schlüssel highway ist. Sonst wäre das Ergebnis oft unklar. Bei etwas anderem als highway (z.B. name als Schlüssel), könnte auch Toothway gemeint sein. Aber auch Schlüssel/Wert-Paare können mitsamt der Korrektur in einer Liste erfasst werden. Mit einer Schlüssel/Wert-Liste wäre dann auch eine Korrektur addr:county=DE/DK/FR/… zu addr:country=DE/DK/FR/… möglich. Wenn der Wert auch Probleme hat, dann unterbleibt eben die Korrektur.

Noch eine Überlegung: Sowohl KeepRight als auch der Validator von JOSM prüfen auf falsche/unbekannte Schlüssel und Werte. Dort kann man sich noch einige Anregungen für die Kandidaten-Liste holen. Man muss ja nicht alles übernehmen.

PS: Schönes Beispiel aus den letzten Tagen: service=gravel.
Gemeint war wahrscheinlich surface=gravel (falsche Vervollständigung).

Edbert (EvanE)

Moins,

Daumenwert: dreißigtausend.

Gruß Wolf

Ich gehe davon aus, daß die meisten Fehler mit ähnlich hoher Wahrscheinlichkeit unbemerkt bleiben, sodaß sich keine Hierarchie bilden läßt. Lediglich jene, die unmittelbare Auswirkungen aufs (Mapnik-)Rendering haben, haben eine größere Chance, entdeckt zu werden. Etwa Adresstags werden in der Regel einmal eingetragen und nie wieder angesehen. Gerendert wird nur addr:housenumber; Fehler in den übrigen Schlüsseln und Werten fallen - außer evtl. spezialisierten Mappern, die mit entsprechenden QS-Werkzeugen gezielt danach suchen - nie auf. Aber auch veihcle, food oder masxpeed auf Straßen schlagen sich nicht im Rendering nieder (auch dann nicht, wenn sie richtig geschrieben sind).

Edit/Nachtrag: für diese Sichtweise spricht insbesondere, daß es kaum falsche Schreibweisen von addr:housenumber zu geben scheint (2 Mal addr:housenumberf, 1 Mal addr:housenumber2 - vermutlich Absicht), kein Vergleich zu country und city.

Wie schon mehrfach gesagt ist die automatische Suche anhand von Editierdistanz und Verhältnis der Häufigkeiten nur ein erster Schritt. Danach kommt neben der Eindeutigkeit natürlich die Frage, ob die Entstehung etwa von zracktype aus tracktype tatsächlich plausibel ist (ja, denn t und z liegen auf QWERTZ direkt nebeneinander).

Möglicherweise in einem späteren Schritt. Ich hatte oben schon begründet, warum ich Werte erst einmal heraushalten möchte. Fehlerhafte Schlüssel, die ohne Untersuchung der Werte (oder gar der übrigen Tags eines Objektes) keinem korrekten Schlüssel eindeutig zugeordnet werden können, bleiben halt unkorrigiert.

Eher nicht. Die Prüfung, ob etwa “webside” oder “tunnerl” (AT?) doch als “richtige” Schlüssel vorkommen können, muß vorher erfolgen.

Geofabrik-DE: 12571, weltweit siehe Taginfo.

Mal ein Beispiel, wie der Korrektuprozeß aussehen könnte. Folgendes ist das Log eines Testlaufs ohne Hochladen mit einem sehr beschränkten Regelsatz, ausgeführt auf zuvor aus germany.osm.pbf ausgefilterten Daten (ebenfalls mit einem sehr beschränkten Tagfilter).

osm-mechedit-fix-misspell run Wed Oct  9 14:39:04 2013
editing node 1323451144: http://www.openstreetmap.org/browse/node/1323451144
	replacing misspelt tag key "add:city" -> "addr:city"
editing node 2250017114: http://www.openstreetmap.org/browse/node/2250017114
	replacing misspelt tag key "add:postcode" -> "addr:postcode"
	replacing misspelt tag key "add:street" -> "addr:street"
editing node 2320100082: http://www.openstreetmap.org/browse/node/2320100082
	replacing misspelt tag key "add:city" -> "addr:city"
editing node 2433660679: http://www.openstreetmap.org/browse/node/2433660679
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 109622780: http://www.openstreetmap.org/browse/way/109622780
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 109622883: http://www.openstreetmap.org/browse/way/109622883
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 109622895: http://www.openstreetmap.org/browse/way/109622895
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 109623001: http://www.openstreetmap.org/browse/way/109623001
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 109623213: http://www.openstreetmap.org/browse/way/109623213
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 109623359: http://www.openstreetmap.org/browse/way/109623359
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 109623773: http://www.openstreetmap.org/browse/way/109623773
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 109623806: http://www.openstreetmap.org/browse/way/109623806
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 109623839: http://www.openstreetmap.org/browse/way/109623839
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 109623933: http://www.openstreetmap.org/browse/way/109623933
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 109624224: http://www.openstreetmap.org/browse/way/109624224
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 109624293: http://www.openstreetmap.org/browse/way/109624293
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 109624356: http://www.openstreetmap.org/browse/way/109624356
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 109624365: http://www.openstreetmap.org/browse/way/109624365
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 109624439: http://www.openstreetmap.org/browse/way/109624439
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 132417216: http://www.openstreetmap.org/browse/way/132417216
	replacing misspelt tag key "addr:sity" -> "addr:city"
editing way 147334135: http://www.openstreetmap.org/browse/way/147334135
	replacing misspelt tag key "addr.country" -> "addr:country"
editing way 206806592: http://www.openstreetmap.org/browse/way/206806592
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 212616891: http://www.openstreetmap.org/browse/way/212616891
	replacing misspelt tag key "add:country" -> "addr:country"
editing way 212732786: http://www.openstreetmap.org/browse/way/212732786
	replacing misspelt tag key "add:country" -> "addr:country"
editing way 212732797: http://www.openstreetmap.org/browse/way/212732797
	replacing misspelt tag key "add:country" -> "addr:country"
editing way 212732801: http://www.openstreetmap.org/browse/way/212732801
	removing misspelt tag key "add:country" (tag "addr:country" present with identical value)
editing way 212732805: http://www.openstreetmap.org/browse/way/212732805
	removing misspelt tag key "add:country" (tag "addr:country" present with identical value)
editing way 212732807: http://www.openstreetmap.org/browse/way/212732807
	removing misspelt tag key "add:country" (tag "addr:country" present with identical value)
editing way 212732809: http://www.openstreetmap.org/browse/way/212732809
	removing misspelt tag key "add:country" (tag "addr:country" present with identical value)
editing way 212732812: http://www.openstreetmap.org/browse/way/212732812
	removing misspelt tag key "add:country" (tag "addr:country" present with identical value)
editing way 212732814: http://www.openstreetmap.org/browse/way/212732814
	removing misspelt tag key "add:country" (tag "addr:country" present with identical value)
editing way 212732815: http://www.openstreetmap.org/browse/way/212732815
	removing misspelt tag key "add:country" (tag "addr:country" present with identical value)
editing way 212732816: http://www.openstreetmap.org/browse/way/212732816
	removing misspelt tag key "add:country" (tag "addr:country" present with identical value)
editing way 212732821: http://www.openstreetmap.org/browse/way/212732821
	removing misspelt tag key "add:country" (tag "addr:country" present with identical value)
editing way 215610573: http://www.openstreetmap.org/browse/way/215610573
	replacing misspelt tag key "add:postcode" -> "addr:postcode"
	replacing misspelt tag key "add:street" -> "addr:street"
editing way 219480497: http://www.openstreetmap.org/browse/way/219480497
	replacing misspelt tag key "addr.city" -> "addr:city"
editing way 222045378: http://www.openstreetmap.org/browse/way/222045378
	replacing misspelt tag key "addr;city" -> "addr:city"
	replacing misspelt tag key "adr:country" -> "addr:country"
editing way 223428023: http://www.openstreetmap.org/browse/way/223428023
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 223428024: http://www.openstreetmap.org/browse/way/223428024
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 223428025: http://www.openstreetmap.org/browse/way/223428025
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 223428030: http://www.openstreetmap.org/browse/way/223428030
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 223428032: http://www.openstreetmap.org/browse/way/223428032
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 223428033: http://www.openstreetmap.org/browse/way/223428033
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 223428034: http://www.openstreetmap.org/browse/way/223428034
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 223428035: http://www.openstreetmap.org/browse/way/223428035
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 223428037: http://www.openstreetmap.org/browse/way/223428037
	replacing misspelt tag key "add:city" -> "addr:city"
editing way 237377780: http://www.openstreetmap.org/browse/way/237377780
	replacing misspelt tag key "addr:ciry" -> "addr:city"
editing way 237377781: http://www.openstreetmap.org/browse/way/237377781
	replacing misspelt tag key "addr:ciry" -> "addr:city"
editing way 240491850: http://www.openstreetmap.org/browse/way/240491850
	replacing misspelt tag key "addr:sity" -> "addr:city"
editing way 240491855: http://www.openstreetmap.org/browse/way/240491855
	replacing misspelt tag key "addr:sity" -> "addr:city"
editing way 240491860: http://www.openstreetmap.org/browse/way/240491860
	replacing misspelt tag key "addr:sity" -> "addr:city"
editing way 240491866: http://www.openstreetmap.org/browse/way/240491866
	replacing misspelt tag key "addr:sity" -> "addr:city"
editing way 240553355: http://www.openstreetmap.org/browse/way/240553355
	replacing misspelt tag key "addr:ountry" -> "addr:country"
total number of objects modified (not really): 53

Unterschieden werden drei Fälle, beispielhaft für den falschen Schlüssel adr:country: a) adr:country wird einfach durch addr:country ersetzt; b) wenn addr:country bereits vorhanden ist und der Wert mit dem von adr:country übereinstimmt, wird adr:country gelöscht. Sind c) beide Schlüssel vorhanden, aber ihre Werte stimmen nicht überein, unterbleibt eine Änderung. Der Spielzeug-Regelsatz für obigen Test war folgender:

(("addr:city"
  ("add:city" "adr:city" "adde:city" "addr.city" "addr::city" "addr:ciry"
   "addr:ciy" "addr:dity" "addr:sity" "addr;city" "addr_city" "adr:city"))
 ("addr:street"
  ("add:street" "addr::street"))
 ("addr:country"
   ("add:country" "addr.country" "addr_country" "addr:ountry"
    "addr:coutry" "adr:country"))
 ("addr:postcode"
   ("add:postcode")))

Aufgeführt ist jeweils das Ersetzungsziel mit allen Urbildern, d.h. add:city, adr:city, adde:city usw. werden durch addr:city ersetzt.

Schaut doch ganz passabel aus. Dann warten wir einfach mal auf den realen Test mit größerem Regelsatz.

Mit einem realen Testlauf werde ich mir noch etwas Zeit lassen (obwohl das Programm startklar wäre). Die Idee ist gerade mal zwei Tage in der Welt; vielleicht kommt ja noch der eine oder andere grundsätzliche - und möglicherweise durchaus berechtigte - Einwand.

Hier ist jedenfalls schon mal ein Entwurf für die erste Generation eines Regelsatzes mit der Bitte, einmal drüber zu schauen. Das Format ist das gleiche wie oben: erst das Ersetzungsziel, dann die Menge seiner Urbilder (allesamt dem Datenbestand entnommen). Wer nicht die ganze Liste durchackern will: lieber zwei bis drei der (etwa gleich großen, mehr oder weniger alphabetisch sortierten) Blöcke gründlich überprüfen als alles nur oberflächlich. Entweder zufällig welche herausgreifen (nicht jeder die ersten zwei) oder z.B. jene Blöcke, welche die ersten Buchstaben den eigenen Vornamens enthalten.

Die Urbilder enthalten überwiegend Tippfehler wie vertauschte Buchstaben, falsche Großbuchstaben oder durch abgerutschte Finger eingefügte Buchstaben. Zu kurz geratene Tags sind nur in Ausnamefällen (“landu” ist ziemlich eindeutig, “lan” nicht) dabei. Basis des Entwurfs war diese Auswertung des Geofabrik-DE-Extrakts, wobei ich nach einem Verhältnis der Häufigkeiten von mindestens 200 (statt 500) gesucht habe.

Dieser erste Entwurf wird in jedem Fall kontinuierlich erweitert werden müssen. Ich befürchte allerdings angesichts der bereits jetzt gefundenen Breite ein ziemlich schlechtes Konvergenzverhalten, d.h. bereits aufgetretene Fehler werden sich nur selten wiederholen und stattdessen wird es neue geben.

(("abandoned" ("abandonde" "abandones"))
 ("addr:city" ("add:city" "adr:city" "adde:city" "addr.city" "addr::city"
               "addr:ciry" "addr:ciy" "addr:dity" "addr:sity" "addr;city"
               "addr_city"))
 ("addr:country" ("add:country" "addr.country" "addr_country" "addr:ountry"
                  "addr:coutry" "adr:country"))
 ("addr:housenumber" ("addr:housenumberf"))
 ("addr:postcode" ("add:postcode"))
 ("addr:street" ("add:street" "addr::street"))
 ("addr:suburb" ("addr_suburb" "addr:subrub" "addR:suburb"))
 ("amenity" ("amenit"))

 ("bridge" ("brigde"))
 ("building" ("Building" "bulding"))
 ("building:colour" ("buidling:colour" "building;colour"))
 ("building:levels" ("buidling:levels"))
 ("building:use" ("buidling:use"))

 ("capacity" ("caapcity"))
 ("castle_type" ("castel_type" "castle_typ" "castle:type"))
 ("cemetery" ("cemetary"))
 ("construction" ("cosntruction" "Construction"))
 ("cuisine" ("cuosine"))

 ("denotation" ("denatation"))
 ("drinkable" ("dringable"))
 ("entrance" ("entramce"))
 ("fuel:cng" ("fuel:CNG"))
 ("fuel:e10" ("fuel:E10"))

 ("generator:method" ("generator_method"))
 ("generator:source" ("generator_source"))
 ("genus:de" ("genus:DE"))
 ("height" ("heigth" "heihgt" "hieght" "hright"))
 ("heritage" ("heirtage"))
 ("heritage:operator" ("heritgae:operator" "heritage_operator"))
 ("hgv" ("hgb"))
 ("highway" ("higwhay"))

 ("incline" ("inclien"))
 ("information" ("Information"))
 ("landuse" ("landu"))
 ("layer" ("LAYER" "Layer"))

 ("man_made" ("man made"))
 ("maxheight" ("maxheigth"))
 ("maxspeed:backward" ("maxspeed:backeard"))
 ("maxspeed:forward" ("maxspeed:forwad" "maxspeed.forward"))
 ("maxweight" ("maxweigth" "Maxweight"))
 ("memorial" ("menorial"))
 ("memorial:type" ("menorial_type"))
 ("motorroad" ("motorraod"))
 ("mtb:scale" ("MTB:Scale" "MTB:scale" "mtb_scale" "mtb.scale" "mtb:scael"))

 ("name" ("Name"))
 ("natural" ("Natural" "natrual" "naturan" "naturaql" "naturel"))
 ("network" ("Network" "networt"))
 ("noexit" ("NOEXIT" "moexit"))
 ("note" ("Note" "NOTE" "noet"))
 ("phone" ("phoen"))
 ("population" ("ppoulation"))
 ("public_transport" ("public_tranpsort"))

 ("ref" ("Ref"))
 ("reservoir_type" ("reservior_type"))
 ("roof:colour" ("roof_colour"))
 ("roof:material" ("roof_material" "roof:mateiral" "roof:materials"))
 ("roof:shape" ("roof:shade" "roof_shape" "rrof:shape" "coof:shape"))

 ("shop" ("shpo"))
 ("source" ("Source" "soruce" "suorce"))
 ("surface" ("surfacw" "surfcae"))
 ("tourism" ("tourisme"))
 ("tracktype" ("trakctype" "traxktype" "zracktype" "Tracktype" "tracktyp"
               "trackty" "tarcktype"))
 ("traffic_calming" ("traffic_claming"))
 ("tunnel" ("tunne" "tunnerl" "Tunnel"))
 ("turn:lanes" ("turn_lanes" "turn:lane" "turn|lanes"))

 ("vehicle" ("vehicles"))
 ("website" ("Website" "webside" "websi" "websit"))
 ("wheelchair" ("wheelshair"))
 ("width" ("widht" "widh"))
)

Mir ist nichts aufgefallen.
Eine Anregung für später: Wenn neue Items dazukommen, sollte das zu erkennen sein (vielleicht in einer zweiten Liste), denn die sind ja dann noch “unerprobt”.