Landtage und Regierungen im Lexikon, Rang als Gleichstandsregel
Drei neue Spiegelabfragen schliessen die gemessene Luecke im
Akteurslexikon: landtage (1539), regierung (2003), sondergesandte (5).
Lexikon 5540 -> 8856 Akteure, Aufloesung 21,1 % -> 23,2 % ueber 5018
Items. Der Gewinn steckt in wenigen Personen - Siegmund 123, Witkoff
102, Kushner 93, Lawrow 21.
Drei Abfragen, weil Wikidata drei Wege verlangt:
landtage P31/P279*, nicht P279* - "Mitglied des Landtag
Sachsen-Anhalt" ist eine Instanz von Q1939559, keine
Unterklasse. Dazu ein schaerferer Datumsfilter: von
11464 je gewaehlten Personen tragen 9700 keinerlei
Zeitangabe, ein blosses "kein Ende gesetzt" liesse die
Weimarer Republik herein.
regierung P1308, Amt -> derzeitiger Inhaber. Ueber die Amtszeit
der Person faellt Lawrow (amtiert seit 2004) aus jedem
Datumsfenster, ohne Fenster kommen Tausende Minister
herein, deren Amtszeit nie zu Ende gepflegt wurde.
sondergesandte Der andere Weg, fuer Witkoff - sein Amt traegt kein
P1308. Beide Wege in einer Abfrage laufen in die
Zeitgrenze der WDQS.
Kushner steht in hand.json: sein Amt endete 2021, seine Rolle nicht.
Die Erweiterung hat zuerst Schaden angerichtet. Mit den Landtagen kamen
Janine und Heiner Merz ins Lexikon, "Merz" wurde mehrdeutig, und 125
Nennungen des Bundeskanzlers fielen aus. Aus jedem "Hamburg" wurde eine
Kultusministerin (22-mal), aus "KI" ein Nachname (16-mal). Daher sieben
neue Sperreintraege und eine dritte Regel in waehle(): traegt genau ein
Kandidat den niedrigsten Rang, gewinnt er. Der Rang kommt aus der
Spiegelabfrage, Staatsfuehrung vor Bundestag vor Landtag - keine
Wichtigkeitsordnung, sondern eine Erwartung darueber, wen eine deutsche
Schlagzeile mit blossem Nachnamen meint. Abschlag 0,15, Grund steht in
der Nutzlast. Die Amtstabelle bekommt den schlechtesten Rang: sie reicht
bis 1794 zurueck, mit Rang 0 wurde aus "Teufel" ein
Ministerpraesident a. D.
Dabei fiel ein Loch im Fingerabdruck auf: NACHNAMEN_SPERRE stand nicht
in EINSTELLUNGEN_FEST. Ein Eintrag mehr aenderte das Ergebnis von 4868
auf 4820 aufgeloeste Nennungen unter derselben coder_version - genau
der Fehler, den die Version verhindern soll. Sperrliste und Rangordnung
gehen jetzt als Hash ein.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
a2e62a7d5e
commit
3a9c000a0e
+68
-4
@@ -87,6 +87,17 @@ NACHNAMEN_SPERRE = {
|
||||
"zeit",
|
||||
"spiegel",
|
||||
"focus",
|
||||
# Staedtenamen, die zugleich Nachnamen von Abgeordneten sind. Erst mit
|
||||
# den Landtagen kamen sie ins Lexikon, und sofort wurde aus jedem
|
||||
# "Hamburg" eine niedersaechsische Kultusministerin - 22-mal im Korpus
|
||||
# vom 08.09.2026.
|
||||
"hamburg", # Julia Willie Hamburg, MdL Niedersachsen
|
||||
"rostock", # Clemens Rostock, MdL Brandenburg
|
||||
"oldenburg", # Simone Oldenburg, MdL Mecklenburg-Vorpommern
|
||||
"ki", # Ki-hong Nam - in deutschen Schlagzeilen die KI
|
||||
"nothing", # Volker Nothing, MdL - sonst das englische Wort
|
||||
"andrew", # Stuart Andrew, MP - sonst ein Vorname
|
||||
"champagne", # Francois-Philippe Champagne - sonst das Getraenk
|
||||
}
|
||||
|
||||
# Aliase, die Wikidata fuehrt, die in Schlagzeilen aber regelmaessig etwas
|
||||
@@ -99,6 +110,37 @@ FORMEN_SPERRE = {
|
||||
# entscheiden, und beide Lesarten sind haeufig.
|
||||
}
|
||||
|
||||
# Rangordnung der Spiegelabfragen fuer den Gleichstandsfall. Sie ist eine
|
||||
# Aussage darueber, wen eine deutsche Schlagzeile mit blossem Nachnamen
|
||||
# meint, nicht darueber, wer wichtiger ist. Der Anlass ist messbar: mit den
|
||||
# Landtagen kamen Janine und Heiner Merz ins Lexikon, und "Merz" war
|
||||
# schlagartig mehrdeutig - 125 Nennungen des Bundeskanzlers fielen aus.
|
||||
#
|
||||
# Ein Rang entscheidet nur, wenn genau ein Kandidat den niedrigsten traegt.
|
||||
# Bei Gleichstand innerhalb eines Rangs bleibt es beim Muenzwurfverbot.
|
||||
RANG = {
|
||||
"hand": 0,
|
||||
"staatsfuehrung": 1,
|
||||
"regierung": 1,
|
||||
"sondergesandte": 1,
|
||||
"bundestag": 2,
|
||||
"landtage": 3,
|
||||
# Die Amtstabelle reicht bis 1794 zurueck und besteht ueberwiegend aus
|
||||
# Verstorbenen. Sie darf einen Gleichstand nicht gewinnen: sonst wird
|
||||
# aus "Teufel" ein Ministerpraesident a.D. und aus "Otto" ein Bremer
|
||||
# Buergermeister des 18. Jahrhunderts. Wer heute im Amt ist, steht
|
||||
# ohnehin in einer der Personenabfragen.
|
||||
"aemter": 5,
|
||||
}
|
||||
RANG_SONST = 4
|
||||
|
||||
|
||||
def rang(quelle):
|
||||
"""'wikidata:landtage@2026-09-08' -> 3."""
|
||||
name = (quelle or "").split(":")[-1].split("@")[0]
|
||||
return RANG.get(name, RANG_SONST)
|
||||
|
||||
|
||||
EINSTELLUNGEN_FEST = {
|
||||
"ner_modell": NER_MODELL,
|
||||
"basis": "titel+teaser",
|
||||
@@ -106,7 +148,16 @@ EINSTELLUNGEN_FEST = {
|
||||
"ner_typen": list(TYPEN),
|
||||
"typ_aus": "lexikon",
|
||||
"fuzzy": "editierdistanz_nach_laenge",
|
||||
"nachnamen": "eindeutig_oder_kontext",
|
||||
"nachnamen": "eindeutig_kontext_rang",
|
||||
"rang": "|".join(f"{k}={v}" for k, v in sorted(RANG.items())),
|
||||
# Die Sperrliste gehoert in die Version, nicht nur in den Quelltext.
|
||||
# Sie aendert das Ergebnis - ein Eintrag mehr, und aus 22 Nennungen
|
||||
# der Hansestadt wird keine Ministerin mehr. Ohne sie im Fingerabdruck
|
||||
# traegt dieselbe coder_version zwei verschiedene Auszaehlungen, und
|
||||
# genau das soll die Version verhindern.
|
||||
"nachnamen_sperre": hashlib.blake2b(
|
||||
"|".join(sorted(NACHNAMEN_SPERRE)).encode(), digest_size=8
|
||||
).hexdigest(),
|
||||
}
|
||||
|
||||
_UMLAUTE = str.maketrans({"ä": "ae", "ö": "oe", "ü": "ue", "ß": "ss"})
|
||||
@@ -238,10 +289,10 @@ class Lexikon:
|
||||
|
||||
def lade_lexikon(conn):
|
||||
with conn.cursor() as k:
|
||||
k.execute("select id, typ, name, aliase, land, rolle from akteure")
|
||||
k.execute("select id, typ, name, aliase, land, rolle, quelle from akteure")
|
||||
akteure = [
|
||||
{"id": r[0], "typ": r[1], "name": r[2], "aliase": r[3],
|
||||
"land": r[4], "rolle": r[5]}
|
||||
"land": r[4], "rolle": r[5], "rang": rang(r[6])}
|
||||
for r in k.fetchall()
|
||||
]
|
||||
k.execute("select amt_id, person_id, von, bis from amtsinhaber")
|
||||
@@ -260,7 +311,8 @@ def waehle(lexikon, ids, kontext):
|
||||
|
||||
1. Ist genau einer gemeint, ist die Sache erledigt.
|
||||
2. Wird die Partei eines Kandidaten im selben Item genannt, gewinnt er.
|
||||
3. Sonst bleibt die Nennung unaufgeloest. Ein Muenzwurf waere hier der
|
||||
3. Traegt genau einer den niedrigsten Rang, gewinnt er - siehe RANG.
|
||||
4. Sonst bleibt die Nennung unaufgeloest. Ein Muenzwurf waere hier der
|
||||
schlimmere Fehler, weil er in der Zeitreihe nicht auffaellt.
|
||||
"""
|
||||
if len(ids) == 1:
|
||||
@@ -270,6 +322,11 @@ def waehle(lexikon, ids, kontext):
|
||||
vergleichsform(lexikon.akteure[i]["notiz"]) in kontext]
|
||||
if len(mit_partei) == 1:
|
||||
return mit_partei[0], "kontext_partei"
|
||||
beste = min(lexikon.akteure[i].get("rang", RANG_SONST) for i in ids)
|
||||
vorn = [i for i in ids
|
||||
if lexikon.akteure[i].get("rang", RANG_SONST) == beste]
|
||||
if len(vorn) == 1:
|
||||
return vorn[0], "rang"
|
||||
return None, "mehrdeutig"
|
||||
|
||||
|
||||
@@ -319,10 +376,17 @@ def aufloesen(lexikon, spannen, datum):
|
||||
a = lexikon.akteure[gewaehlt]
|
||||
konfidenz = {"alias": 0.95, "alias_ohne_anrede": 0.9,
|
||||
"nachname": 0.8, "fuzzy": 0.6}[methode]
|
||||
# Abschlaege fuer die Gleichstandsregeln. Der Rang ist die
|
||||
# schwaechere der beiden: die Partei steht im Text, der Rang ist
|
||||
# nur eine Erwartung darueber, wer gemeint sein duerfte.
|
||||
if grund == "kontext_partei":
|
||||
konfidenz -= 0.1
|
||||
elif grund == "rang":
|
||||
konfidenz -= 0.15
|
||||
eintrag.update({"id": gewaehlt, "typ": a["typ"], "rolle": a["rolle"],
|
||||
"methode": methode, "konfidenz": round(konfidenz, 2)})
|
||||
if grund != "eindeutig":
|
||||
eintrag["grund"] = grund
|
||||
|
||||
# Aemter gegen das Datum des Items aufloesen. Das Amt bleibt stehen,
|
||||
# die Person kommt daneben - beides ist eine Aussage ueber den Text.
|
||||
|
||||
Reference in New Issue
Block a user