v1.12.0: max-2-stelsel — enkele familie-hit kan nooit solo doorlaten
- Gewicht-3-tier vervallen: alle families wegen max 2; drempel blijft 3,
dus elke echte OV-bericht combineert met een tweede signaal (besluit
2026-09-12, gevalideerd op 205 productie-artikelen).
- 'hermes' uit vervoerders + whitelist -> eigen zwakke familie (achternaam
Ton Hermes, Margraten false positive 2026-09-12).
- Whitelist geen auto-pass meer: titel-hit = +2 titel-anker (onmiskenbare
termen behouden hun recall; samenvatting blijft inert).
- Completheids-audit (2026-09-12): +20 termen/frasen —
sterk: spoorsector, spoorbeheerder, spoornet, spoorvervoerder,
treinvertraging/hinder/uitval/verstoring, ertms, teso, rangeer/rangeren,
ice-<stad>/ice-trein, maaslijn/nedersaksenlijn/kamperlijn, ns international,
deutsche bahn, european sleeper, italo, nightjet;
zwak: busongeluk, busvervoer, spoor, staking, passagier(+reizigers),
vervoer, vervoersbedrijf, vervoerregio, ritten, bovenleiding, abonnement.
- validate_filter.py: invariant gewicht in {1,2}, 46 dubbelzinnige + 39
onmiskenbare termen, 52 regressie-cases groen.
This commit is contained in:
parent
4adfff5b2a
commit
7997d7572a
1 changed files with 223 additions and 145 deletions
|
|
@ -73,12 +73,16 @@ def check(cond: bool, msg: str):
|
|||
# --- Invariant 1: dubbelzinnige woorden mogen nooit sterk/medium of whitelist zijn
|
||||
AMBIGUOUS = [
|
||||
"trein", "bus", "station", "stations", "sprinter", "sprinters",
|
||||
"reiziger", "reizigers", "vervoerder", "vervoerders",
|
||||
"reiziger", "reizigers", "passagier", "passagiers", "vervoerder", "vervoerders",
|
||||
"inchecken", "uitchecken", "sein", "overweg", "overwegen", "breng",
|
||||
"kaartje", "opwaarderen", "rails", "dienstregeling", "chipkaart",
|
||||
"reisproduct", "vervoersbewijs", "vervoerbewijs",
|
||||
"pendelbus", "shuttlebus",
|
||||
"ontspor", "ontspoor", "ontspoord", "ontspoorde", "ontsporing",
|
||||
# audit 2026-09-12 (max-2-stelsel + completheids-audit)
|
||||
"hermes", "spoor", "staking", "stakingen", "vervoer", "vervoersbedrijf",
|
||||
"vervoerregio", "ritten", "bovenleiding", "abonnement",
|
||||
"busongeluk", "busongelukken", "busvervoer",
|
||||
]
|
||||
print(f"== invariant 1: {len(AMBIGUOUS)} dubbelzinnige woorden -> alleen zwak (1), nooit whitelist ==")
|
||||
for w in AMBIGUOUS:
|
||||
|
|
@ -93,6 +97,12 @@ UNAMBIGUOUS = [
|
|||
"conducteur", "ovpay", "ns", "prorail",
|
||||
"treinstoring", "halte", "openbaar vervoer", "intercity", "buurtbus",
|
||||
"veerdienst", "lijn 12", "ov-chipkaart", "spoorbrug",
|
||||
# audit 2026-09-12 (completheids-audit, max-2-stelsel)
|
||||
"spoorsector", "spoorbeheerder", "spoornet", "spoorvervoerder",
|
||||
"treinvertraging", "treinhinder", "treinuitval", "treinverstoring",
|
||||
"ertms", "teso", "rangeerterrein", "rangeren", "ice-berlijn",
|
||||
"maaslijn", "nedersaksenlijn", "kamperlijn",
|
||||
"ns international", "deutsche bahn", "european sleeper", "italo", "nightjet",
|
||||
]
|
||||
print(f"== invariant 2: {len(UNAMBIGUOUS)} onmiskenbare OV-termen -> sterk/medium of whitelist ==")
|
||||
for w in UNAMBIGUOUS:
|
||||
|
|
@ -100,10 +110,10 @@ for w in UNAMBIGUOUS:
|
|||
check(whitelisted(w) or any(g >= 2 for g in gew),
|
||||
f"{w!r} heeft whitelist of gewicht >= 2 (gewichten {sorted(gew)})")
|
||||
|
||||
# --- Invariant 3: patronen compileren en gewichten geldig
|
||||
print("== invariant 3: alle 24+ families compileren, gewicht in {1,2,3} ==")
|
||||
# --- Invariant 3: patronen compileren en gewichten geldig (max-2, besluit 2026-09-12)
|
||||
print("== invariant 3: alle families compileren, gewicht in {1,2} ==")
|
||||
for p, w in FAMILIES:
|
||||
check(w in (1, 2, 3), f"familie {p[:40]!r} heeft geldig gewicht {w}")
|
||||
check(w in (1, 2), f"familie {p[:40]!r} heeft geldig gewicht {w} (max-2-stelsel)")
|
||||
check(len(COMPILED) == len(FAMILIES), "alle families compileren")
|
||||
|
||||
# --- Regressie: gedrag van _filter_passes op bekende cases (precision-first)
|
||||
|
|
@ -183,6 +193,26 @@ GOLDEN = [
|
|||
("Lijn 12 rijdt vanaf maandag een andere route", "De route gaat via het centrum.", True),
|
||||
("Werkzaamheden aan perron", "Het perron wordt volgende maand opgeknapt.", True),
|
||||
("Reactie Nederlandse Spoorwegen", "De Nederlandse Spoorwegen zeggen meer in te zetten op punctualiteit.", True),
|
||||
# max-2-stelsel (besluit 2026-09-12): geproduceerd op 205 productie-artikelen
|
||||
# + LLM-audit. Geen enkele familie weegt meer dan 2 → één hit kan nooit solo
|
||||
# doorlaten; whitelist-term in de titel telt +2 (titel-anker).
|
||||
("Veel animo voor 'adopteren' graf op Amerikaanse begraafplaats Margraten",
|
||||
"…'Het voelde echt alsof je in de rij stond voor festivaltickets'… 'Ik ben bang dat mensen met de slaapzak voor de laptop gaan liggen', zei Ton Hermes eerder.", False),
|
||||
# ^ echte false positive 2026-09-12: 'hermes' (achternaam) scoorde vroeger 3 via de vervoerdersfamilie
|
||||
("TESO onderzoekt komst derde veerboot tussen Texel en Den Oever",
|
||||
"Veerdienst TESO onderzoekt of het haalbaar is om een derde veerboot in te zetten tussen Oudeschild en Den Oever.", True), # teso(2) + veerboot(2) = 4
|
||||
("Vrouw buschauffeur Rob zwaar aangeslagen na dodelijk ongeval",
|
||||
"Bij het dodelijke busongeluk in Zwitserland zat de politicus achter het stuur.", True), # buschauffeur(2) + busongeluk(1) = 3
|
||||
("Vakbonden noemen stakingsdag in het OV 'een geslaagde dag'",
|
||||
"Gisteren was de landelijke stakingsdag in het OV; medewerkers legden in de spoorsector 24 uur het werk neer.", True), # ov(2) + staking(1) + spoorsector(2)
|
||||
("Dodental veerbootbrand Filipijnen loopt verder op", "Zeker 76 mensen kwamen om bij de brand op de veerboot.", False), # één veerboot-hit (2) = geen NL-OV
|
||||
("ICE Berlijn voegt na Hamburg vanaf december ook stop in Bremen toe",
|
||||
"De ICE Berlijn gaat vanaf december via Bremen en Hamburg Hauptbahnhof naar Berlijn rijden. Dat meldt NS International.", True), # ice-berlijn(2) + ns(2) = 4
|
||||
("Laatste noot voor vernielde stationspiano Eindhoven",
|
||||
"De piano in het station was jarenlang een begrip reizigers produceerden er filmpjes.", False), # cultuurstukje; 'station'/'reizigers' zwak-alleen zonder titel-anker
|
||||
("Meerdere doden na busongeluk in Zwitserland", "Het busongeluk gebeurde naast de snelweg bij een afrit.", False), # busongeluk(1) alleen = zwak-alleen
|
||||
("Antwerpen ontvangt eerste ICE", "De eerste ICE van Deutsche Bahn rijdt vanaf volgende maand naar Antwerpen.", False), # bewust geweerd: 'ice van' is NIET opgenomen (ijs-botsing); deutsche bahn(2) alleen < 3 — was vóór de wijziging óók al geweerd
|
||||
("NS verlengt noodregeling tot volgend jaar", "De vervoerder kampt met personeelstekorten.", True), # ns(2) + vervoerder(1) = 3
|
||||
]
|
||||
print(f"== regressie: {len(GOLDEN)} cases (precision-first) ==")
|
||||
for t, s, want in GOLDEN:
|
||||
|
|
|
|||
Loading…
Reference in a new issue