v1.10.0: whitelist alleen titel-anker; medium+zwak uitsluitend in samenvatting geweerd

This commit is contained in:
Eddy de Vink 2026-09-12 09:11:45 +02:00
commit f5dec54165
3 changed files with 57 additions and 12 deletions

View file

@ -89,13 +89,17 @@ rss_change_level = EventType.find("xyz.maubot.rss", t_class=EventType.Class.STAT
# een niet-OV-bericht te veel doorgelaten (gebruikersbesluit, 2026-09-10). # een niet-OV-bericht te veel doorgelaten (gebruikersbesluit, 2026-09-10).
# #
# Drie lagen, elk met een eigen regel: # Drie lagen, elk met een eigen regel:
# 1. WHITELIST -> ALTIJD door. Alleen termen die in élke context OV # 1. WHITELIST -> ALTIJD door BIJ EEN HIT IN DE TITEL. Alleen termen die
# betekenen (merken: NS/ProRail/Arriva; onmiskenbaar jargon: spoorstoring, # in élke context OV betekenen (merken: NS/ProRail/Arriva; onmiskenbaar jargon:
# perron, bushalte, conducteur, ovpay; multi-woord termen). # spoorstoring, perron, bushalte, conducteur, ovpay; multi-woord termen).
# REGEL: twijfel je of de term ook buiten het OV kan voorkomen -> NIET hier. # REGEL: twijfel je of de term ook buiten het OV kan voorkomen -> NIET hier.
# NIET: station-samenstellingen (busstation/metrostation) — een bericht over # NIET: station-samenstellingen (busstation/metrostation) — een bericht over
# een pand 'naast het busstation' is geen OV-nieuws (besluit 2026-09-11); # een pand 'naast het busstation' is geen OV-nieuws (besluit 2026-09-11);
# die wegen mee via de gewogen families (medium). # die wegen mee via de gewogen families (medium).
# Een whitelist-term ALLEEN in de SAMENVATTING laat NIET onvoorwaardelijk
# door: een bijzin als 'de zakelijke bezoeker is ook nodig voor het openbaar
# vervoer' in een economiebericht is geen OV-nieuws (besluit 2026-09-12).
# Zo'n hit scoort via de gewogen families (dezelfde termen staan daar ook in).
# 2. GEWOGEN FAMILIES -> score = som van unieke OV-families over het hele artikel # 2. GEWOGEN FAMILIES -> score = som van unieke OV-families over het hele artikel
# (titel + samenvatting; per familie 1× per artikel — herhaling of beide velden # (titel + samenvatting; per familie 1× per artikel — herhaling of beide velden
# tellen niet dubbel, besluit 2026-09-11) >= drempel (3). # tellen niet dubbel, besluit 2026-09-11) >= drempel (3).
@ -107,6 +111,12 @@ rss_change_level = EventType.find("xyz.maubot.rss", t_class=EventType.Class.STAT
# in titel óf samenvatting, is onvoldoende — de titel weegt # in titel óf samenvatting, is onvoldoende — de titel weegt
# niet extra ('restaurant naast busstation' in de titel is # niet extra ('restaurant naast busstation' in de titel is
# geen OV-bericht, besluit 2026-09-11). # geen OV-bericht, besluit 2026-09-11).
# EXTRA (besluit 2026-09-12): een medium + zwak-combinatie
# UITSLUITEND in de samenvatting (geen enkele hit in de
# titel) is geen OV-bewijs — 'openbaar vervoer' + 'zakelijke
# reizigers' in een economiebericht telt dan toch op tot de
# drempel. Sterke (3) families blijven in de samenvatting
# gewoon tellen.
# - zwak (1): DUBBELZINNIGHEID. Woorden die (ook) buiten het OV # - zwak (1): DUBBELZINNIGHEID. Woorden die (ook) buiten het OV
# voorkomen. REGEL: elk dubbelzinnig woord krijgt een EIGEN # voorkomen. REGEL: elk dubbelzinnig woord krijgt een EIGEN
# familie (niet samengevoegd), zodat twee verschillende # familie (niet samengevoegd), zodat twee verschillende
@ -199,10 +209,15 @@ MATCH_FILTER_BLACKLIST: frozenset[str] = frozenset({
}) })
# MATCH_FILTER_WHITELIST: termen die een bericht per definitie OV maken. Eén enkele # MATCH_FILTER_WHITELIST: termen die een bericht per definitie OV maken. Eén enkele
# hit in titel óf samenvatting laat ALTIJD door (geen familiescore nodig) — dit is het # hit in de TITEL laat ALTIJD door (geen familiescore nodig) — dit is het expliciete
# expliciete "onmiskenbaar OV"-signaal, zodat we voor deze termen niet op de gewogen # "onmiskenbaar OV"-signaal, zodat we voor deze termen niet op de gewogen
# heuristiek hoeven te leunen. Vergelijking is case-insensitive, dus ook 'nederlandse # heuristiek hoeven te leunen. Vergelijking is case-insensitive, dus ook 'nederlandse
# spoorwegen', 'prorail' en 'NS' in all-caps titels tellen mee. # spoorwegen', 'prorail' en 'NS' in all-caps titels tellen mee.
# Een whitelist-hit ALLEEN in de samenvatting is géén onvoorwaardelijk signaal
# (besluit 2026-09-12: 'openbaar vervoer' als bijzin in een economiebericht is geen
# OV-nieuws); die term scoort dan via de gewogen families — voor whitelist-termen
# die geen eigen familie hebben (bv. 'treinstel': alleen zwak via \w*trein\w*) is
# een samenvatting-alleen hit dus zwak.
# Termen MOETEN in elke context OV betekenen. Niet hierop (algemeen/dubbelzinnig): # Termen MOETEN in elke context OV betekenen. Niet hierop (algemeen/dubbelzinnig):
# los 'trein', 'bus', 'metro', 'tram', 'station', 'lijn', 'ov', 'reiziger', # los 'trein', 'bus', 'metro', 'tram', 'station', 'lijn', 'ov', 'reiziger',
# 'vervoerder', 'sprinter', # 'vervoerder', 'sprinter',
@ -407,7 +422,12 @@ class RSSBot(Plugin):
Zwakke woorden (losse 'bus', 'breng', 'overweg', 'overwegen', 'sein', Zwakke woorden (losse 'bus', 'breng', 'overweg', 'overwegen', 'sein',
'opwaarderen', 'kaartje', 'rails', 'pendelbus') moeten combineren met een 'opwaarderen', 'kaartje', 'rails', 'pendelbus') moeten combineren met een
ander OV-woord én minstens één zwak woord moet in de titel staan; dezelfde ander OV-woord én minstens één zwak woord moet in de titel staan; dezelfde
zwakke familie in titel én samenvatting is géén combinatie. Weert oa zwakke familie in titel én samenvatting is géén combinatie. Whitelist-termen
(NS, perron, bushalte, openbaar vervoer, ...) laten alleen onvoorwaardelijk
door BIJ EEN HIT IN DE TITEL; in de samenvatting wegen ze mee als gewogen
familie. Een medium + zwak-combinatie UITSLUITEND in de samenvatting (geen
enkele hit in de titel) is geen OV-bewijs ('openbaar vervoer' + 'zakelijke
reizigers' in een economiebericht, besluit 2026-09-12). Weert oa
'VW-bus' (bus matcht niet ná een koppelteken), 'schoolbus', 'bussen rijden 'VW-bus' (bus matcht niet ná een koppelteken), 'schoolbus', 'bussen rijden
om' in een woningbrand-lead, het werkwoord 'brengen', het idioom 'goed met om' in een woningbrand-lead, het werkwoord 'brengen', het idioom 'goed met
elkaar overweg kunnen', 'een wijk opwaarderen', brandweerjargon elkaar overweg kunnen', 'een wijk opwaarderen', brandweerjargon
@ -415,8 +435,12 @@ class RSSBot(Plugin):
waarin de samenvatting 'station' + 'pendelbus' + 'bus' noemt. waarin de samenvatting 'station' + 'pendelbus' + 'bus' noemt.
Bewust doorgelaten: krant 'De Metro'/café 'De Tram' (medium) en atleet- Bewust doorgelaten: krant 'De Metro'/café 'De Tram' (medium) en atleet-
'sprinter' in combinatie met ander OV-woord.""" 'sprinter' in combinatie met ander OV-woord."""
# Whitelist: één onmiskenbare OV-term (titel óf samenvatting) laat altijd door. # Whitelist: een onmiskenbare OV-term in de TITEL laat altijd door (het
if RSSBot._whitelist_hit(title) or RSSBot._whitelist_hit(summary): # artikel kondigt het onderwerp aan: 'NS verlengt noodregeling'). Een
# whitelist-term ALLEEN in de samenvatting is geen OV-bewijs ('openbaar
# vervoer' als bijzin in een economiebericht, besluit 2026-09-12) en
# scoort via de gewogen families hieronder.
if RSSBot._whitelist_hit(title):
return True return True
t_hits = RSSBot._fam_hits(title) t_hits = RSSBot._fam_hits(title)
s_hits = RSSBot._fam_hits(summary) s_hits = RSSBot._fam_hits(summary)
@ -433,6 +457,11 @@ class RSSBot(Plugin):
# 'bus' in een golfverslag telt anders op tot de drempel). # 'bus' in een golfverslag telt anders op tot de drempel).
if not t_hits or len(combined) < 2: if not t_hits or len(combined) < 2:
return False return False
elif not t_hits and 1 in combined.values():
# Medium + zwak uitsluitend in de samenvatting, niets in de titel: geen
# OV-bewijs. 'openbaar vervoer' + 'zakelijke reizigers' in een
# economiebericht telt anders op tot de drempel (besluit 2026-09-12).
return False
return True return True
@staticmethod @staticmethod
@ -444,13 +473,15 @@ class RSSBot(Plugin):
"samenstellingen als bushalte/buslijn/bushokje/busbaan/busverkeer, treinstoring/treinverkeer/treinstaking, " "samenstellingen als bushalte/buslijn/bushokje/busbaan/busverkeer, treinstoring/treinverkeer/treinstaking, "
"intercity/streekvervoer/veerdienst/buurtbus/belbus, 'lijn 12'\n" "intercity/streekvervoer/veerdienst/buurtbus/belbus, 'lijn 12'\n"
"- Medium (2): tram, metro, openbaar vervoer, lightrail, halte, pont, ov-chipkaart/ovpay, ov-staking, conducteur, " "- Medium (2): tram, metro, openbaar vervoer, lightrail, halte, pont, ov-chipkaart/ovpay, ov-staking, conducteur, "
"trein-/bus-/metrostation — één medium-hit volstaat niet, moet combineren met een andere OV-familie\n" "trein-/bus-/metrostation — één medium-hit volstaat niet, moet combineren met een andere OV-familie; "
"medium + zwak uitsluitend in de samenvatting (geen hit in de titel) telt niet\n"
"- Zwak (1): losse 'bus' (niet ná een koppelteken), 'pendelbus'/'shuttlebus', 'trein', 'station(s)', 'breng', 'overweg', 'overwegen', " "- Zwak (1): losse 'bus' (niet ná een koppelteken), 'pendelbus'/'shuttlebus', 'trein', 'station(s)', 'breng', 'overweg', 'overwegen', "
"'sein', 'kaartje', 'opwaarderen', 'rails', 'inchecken'/'uitchecken', 'dienstregeling', 'chipkaart', 'reisproduct', 'vervoersbewijs', " "'sein', 'kaartje', 'opwaarderen', 'rails', 'inchecken'/'uitchecken', 'dienstregeling', 'chipkaart', 'reisproduct', 'vervoersbewijs', "
"'ontsporen', 'reiziger', 'vervoerder', 'sprinter' — moet combineren met een ander OV-woord, met minstens één zwak woord in de titel\n\n" "'ontsporen', 'reiziger', 'vervoerder', 'sprinter' — moet combineren met een ander OV-woord, met minstens één zwak woord in de titel\n\n"
"**Whitelist (altijd door):** één onmiskenbare OV-term in titel óf samenvatting is genoeg " "**Whitelist (altijd door bij een hit in de TITEL):** een onmisbare OV-term in de titel is genoeg "
"(NS, ProRail, Nederlandse Spoorwegen, spoorstoring, perron, bushalte, conducteur, " "(NS, ProRail, Nederlandse Spoorwegen, spoorstoring, perron, bushalte, conducteur, "
"ov-chipkaart, ovpay, openbaar vervoer, ...)\n\n" "ov-chipkaart, ovpay, openbaar vervoer, ...); in de samenvatting alleen weegt zo'n term mee "
"als gewogen familie (medium/sterk)\n\n"
"Uitgesloten (blacklist): woorden die wél matchen maar geen OV-waarde hebben, " "Uitgesloten (blacklist): woorden die wél matchen maar geen OV-waarde hebben, "
"o.a. straatnamen rond stations ('stationsstraat', 'stationsweg', ...) en niet-OV-vormen als 'stationcar' en 'stationair'\n\n" "o.a. straatnamen rond stations ('stationsstraat', 'stationsweg', ...) en niet-OV-vormen als 'stationcar' en 'stationair'\n\n"
"Doorlaten: som van unieke OV-families ≥ 3 — één familie telt 1× per artikel " "Doorlaten: som van unieke OV-families ≥ 3 — één familie telt 1× per artikel "

View file

@ -1,5 +1,5 @@
id: nl.eddydevink.rss id: nl.eddydevink.rss
version: 1.9.9 version: 1.10.0
modules: modules:
- buzzrss - buzzrss
main_class: RSSBot main_class: RSSBot

View file

@ -150,6 +150,20 @@ GOLDEN = [
("Restaurant naast busstation wil uitbreiden", "De eigenaar wil uitbreiden naar het naastgelegen pand.", False), # zelfde regel, letterlijk gebruikersvoorbeeld ("Restaurant naast busstation wil uitbreiden", "De eigenaar wil uitbreiden naar het naastgelegen pand.", False), # zelfde regel, letterlijk gebruikersvoorbeeld
("Busstation wordt verbouwd", "De verbouwing duurt tot het voorjaar.", False), # herhaling/één woord = 1 signaal: 2 < 3 ('busstation' 60× weegt ook 1×) ("Busstation wordt verbouwd", "De verbouwing duurt tot het voorjaar.", False), # herhaling/één woord = 1 signaal: 2 < 3 ('busstation' 60× weegt ook 1×)
("Metro rijdt niet", "De halte is tijdelijk gesloten.", True), # medium-combinatie over twee families: metro(2)+halte(2)=4 ("Metro rijdt niet", "De halte is tijdelijk gesloten.", True), # medium-combinatie over twee families: metro(2)+halte(2)=4
# fix 2026-09-12: whitelist-term alleen in de SAMENVATTING is geen OV-bewijs
# (valt terug op gewogen families); medium+zwak uitsluitend in de samenvatting
# (geen hit in de titel) wordt geweerd. Echte cases 11-09-2026:
# AT5-economiebericht ('openbaar vervoer' + 'zakelijke reizigers' als bijzin)
# en Telegraaf-overstroming Japan ('openbaar vervoer ontregeld' in de tekst).
("Economische groei van de stad niet meer vanzelfsprekend: ondernemersclubs waarschuwen",
"Volgens Evers is de zakelijke bezoeker ook nodig voor het openbaar vervoer, de culturele sector en musea. "
"Het aantal zakelijke reizigers in de stad daalt.", False),
("Straat in Japan verandert in rivier door hevige regen",
"Het verkeer ligt plat en ook het openbaar vervoer is ontregeld in de getroffen regio.", False),
# recall-bewaakt: 'openbaar vervoer' in de TITEL blijft onvoorwaardelijk door
# (whitelist-titel-anker; Havenloods 11-09-2026, 'einde aan gratis ov').
("Er komt echt een einde aan gratis openbaar vervoer voor ouderen",
"De gemeente stopt vanaf januari met de gratis reizen voor 65-plussers.", True),
# busstation mag niet dubbel meetellen via 'bus' én 'station' (was 2×3=6→nu 1×2) # busstation mag niet dubbel meetellen via 'bus' én 'station' (was 2×3=6→nu 1×2)
("Metrostation Centraal tijdelijk gesloten", "De metro's rijden niet.", True), ("Metrostation Centraal tijdelijk gesloten", "De metro's rijden niet.", True),
("NS verlengt noodregeling op traject Zwolle", "Reizigers moeten rekening houden met minder treinen.", True), ("NS verlengt noodregeling op traject Zwolle", "Reizigers moeten rekening houden met minder treinen.", True),