Regel auf Deutsch formulieren (z. B. „Personen werden nicht
älter als 90 Jahre" oder „Ein gleicher Geburtsort soll stärker zählen").
Das LLM übersetzt sie in Parameter der Matching-Engine; erst nach dem
Übernehmen wirkt sie auf /api/reconcile.
lade …
Ziel: für eine Kandidatenperson (aus einer externen Quelle, z. B. dem Arbeitsblatt in test.docx) anhand aller vorhandenen Informationen entscheiden, ob sie im FactGrid-Auszug bereits vorhanden ist — und wenn ja, als welches Item.
Dieser Katalog ist die fachliche Spezifikation. Die ausführbare Umsetzung steht in app/server.py (reconcile(), Endpoint POST /api/reconcile); die Tabellenfelder liefert build/enrich_index.py.
---
Eine Kandidatenperson wird über die Spalten des Arbeitsblatts beschrieben. Jede Spalte mappt auf ein oder mehrere FactGrid-Merkmale:
| Arbeitsblatt-Spalte | FactGrid-Merkmal | Feld im Index |
|---|---|---|
| Name | Label / Vor- + Nachname | persons.label_de, family_q, given_q |
| Geburtsdatum und -ort | P77 / P82 | birth_year/birth_date, qref birthplace |
| (Sterbedatum) | P38 | death_year/death_date |
| Beruf | P165 | qref profession (+ P3-Expansion) |
| wohnhaft | P83 / P208 | qref residence |
| Datum der Erwähnung | — | Plausibilitätsfenster gegen Lebenszeit |
| Religion | P172 | qref religion |
| Geschlecht (falls bekannt) | P154 | persons.sex_q |
| Eltern (falls bekannt) | P141 / P142 | qref father / mother |
| externe ID (GND/VIAF…) | external-id | person_extid |
| Bemerkung | — (frei) | — |
---
Gemessen am Bestand (666.301 Personen, stark mittelalterlich- portugiesisch geprägt). „Dup-Quote" = Anteil der Personen, die sich einen Schlüssel mit mindestens einer anderen Person teilen:
| Schlüssel | Dup-Quote | Folgerung |
|---|---|---|
| Name allein | 16,5 % | nie hinreichend (z. B. „João Afonso" ×290) |
| Name + Geburtsjahr | 0,8 % | starke Identität |
| Name + Geburts- + Sterbejahr | 0,4 % | praktisch eindeutig |
| Familienname-Q + Vornamen-Q | 12,5 % | allein zu schwach |
| Familie + Vornamen + Geburtsjahr | 0,9 % | stark |
Zusätzlich ist die Feldabdeckung ungleich: Geburtsjahr 55 %, Sterbejahr 21 %, Geschlecht ~100 %, ≥1 externe ID ~30 %. Konsequenz: Es gibt selten ein Merkmal, das immer entscheidet. Daher wird in Stufen gearbeitet — erst deterministisch, dann harte Ausschlüsse, dann starke Treffer, zuletzt gewichtetes Scoring. Die erste zutreffende Stufe entscheidet.
---
Vor jedem Namensvergleich:
remove_diacritics 2 — „Gonçalo" → „goncalo").W.) als Präfix-Match auf volle Token behandeln.Vergleichsarten: exakt (Token-Mengen gleich) · Teilmenge (alle Kandidaten-Token im Item enthalten oder umgekehrt) · fuzzy (Überlappungs- anteil über Schwelle).
---
person_extid): identisch. Externe IDs sind global eindeutig; ein Treffer sticht jeden Namens-/Datumszweifel. ~30 % der Personen haben ≥1 solche ID.Greifen trotz Namensgleichheit. Sie verhindern die häufigste Fehlerquelle (gleicher Name, verschiedene Person).
regel.txt: „Vater und Sohn sind nicht identisch.")regel.txt.)Summe der zutreffenden Gewichte; entscheidet zwischen identisch / mehrdeutig / verschieden. Gewichte und Schwellen sind in app/server.py oben einstellbar (Stil wie BERUF_P3_UP) — und zur Laufzeit durch eigene Regeln überschreibbar: Auf /regeln lassen sich natürlichsprachlich formulierte Regeln (z. B. „Personen werden nicht älter als 90 Jahre") LLM-gestützt in Parameteränderungen übersetzen und aktivieren (POST /api/rules/translate, POST /api/rules; Katalog REC_PARAMS). Das betrifft neben den Gewichten und Schwellen dieses Tiers auch die harten Grenzen aus Tier 1 (REC_MAX_GEN_GAP, REC_MAX_LIFESPAN).
| Merkmal | Bedingung | Gewicht |
|---|---|---|
| Name | exakte Token-Menge | +5 |
| Name | Teilmenge | +3 |
| Name | fuzzy-Überlappung | +2 |
| Geburtsjahr | identisch | +4 |
| Geburtsjahr | ±2 Jahre | +2 |
| Geburtsort | gleich (P82) | +3 |
| Geburtsort | beidseitig bekannt, aber verschieden | −3 |
| Wohnort | gleich (P83/P208) | +2 |
| Beruf | gleich (inkl. P3-Expansion ±2) | +2 |
| Eltern | gleicher Vater/Mutter | +4 |
| Organisation | gleich (P91) | +2 |
| Religion | gleich (P172) | +1 |
| Erwähnung | liegt in Lebenszeit | +1 |
Schwellen (Vorschlag): Score ≥ 8 ⇒ identisch · 4–7 ⇒ mehrdeutig (manuelle Prüfung) · < 4 ⇒ verschieden.
---
build/bericht.html §6)---
---
build/find_duplicates.py)Der Katalog oben prüft eine externe Kandidatenperson. Für die Dubletten-Suche innerhalb des Bestands läuft derselbe Regelkatalog item-gegen-item über alle per Blocking gebildeten Paare (geteilte externe ID · Name+Geburtsjahr · Familienname+Vorname+Jahr · gleicher Name ≤ 12 Mitglieder). „identisch"-Kanten werden per Union-Find zu Clustern verschmolzen. Ausgabe: dup_pairs, dup_clusters, dup_cluster_members, name_collisions, dup_meta.
Acht Verschärfungen gegenüber der Einzelfall-Reconciliation — alle nötig, weil im Bestand selbst (anders als beim sauber gepflegten externen Kandidaten) gleichnamige Verwandte, Namensumkehrungen und konfligierende Normdaten massenhaft vorkommen:
extid_konflikt (Review). Der Dump enthält Haushalts-/ Werk-IDs, die Ehepaare oder Generationen verbinden, und konflierte Normdaten (eine GND auf zwei reale Personen).Cluster-Kohärenz. Union-Find über „identisch"-Kanten kann zwei paarweise unvereinbare Records transitiv verschmelzen (A~B~C, aber A/C widersprüchlich). Solche Cluster werden als incoherent markiert (Mitglied nach Tod eines anderen geboren, oder Geburtsjahr-Spanne > 2 J.) und sind im Report filterbar.
Gemessene Präzision (adversariale Stichproben-Verifikation gegen Live-FactGrid, build/verification.json). Zwei Runden hoben die „identisch"-Gesamtpräzision von 0,42 auf 0,70. Je Tier: extid ~0,91 und fam_given_byear ~0,91 (verlässlich für Auto-Merge), name_byear ~0,77 (grenzwertig: geschätzte Jahre, Allerweltsnamen), reiner score ~0,4 (Prüf-Kandidat). Die Review-Routen sind sauber kalibriert (extid_konflikt ~0,88, score-„mehrdeutig" ~1,0). Der Report führt die Tiers nach Vertrauensstufe (hoch/mittel/niedrig) getrennt. Die Stichprobe misst nur Präzision, keinen Recall (nur Kandidatenpaare enthalten).