Wat telt het zwaarst?
Het filter beslist nu over elk bericht. Maar waarom beslist het wat het beslist? Elk woord draagt iets bij aan de score: zijn spam-telling erbij, en zijn gewone telling eraf.
Voorspel
spam = {"gratis": 2, "nu": 2}
gewoon = {"school": 2, "nu": 1}
score = 0
for woord in "gratis school".split():
if woord in spam:
score = score + spam[woord]
if woord in gewoon:
score = score - gewoon[woord]
print("score:", score)
Welke score krijgt "gratis school"? En is het bericht spam, als het filter
alleen bij een score boven 0 spam zegt?
Antwoord
score: 0
gratis geeft +2 en school geeft -2. Het filter beslist bij 0 op geen
spam, want de score is niet groter dan 0. Twijfelt het filter, dan laat het
het bericht dus door.
Zo werkt het
De bijdrage van een woord is zijn spam-telling min zijn gewone telling. Een woord dat vaak in spam stond, duwt de score omhoog, en een woord uit gewone berichten duwt hem omlaag. Een woord dat het filter nooit zag, staat in geen van beide tellingen en draagt niets bij.
Het filter weet dus alleen wat in zijn voorbeelden stond.
Onderzoek
Draai de code eerst zoals hij is: je ziet score 2 en spam. Pas daarna het bericht aan, en kijk wat het filter ervan maakt.
- Probeer
"ben je nu op school". Het woordnustaat in de spam én in de gewone berichten. Wat doet het met de score? - Probeer
"hoe laat is het". De meeste woorden heeft het filter nooit gezien. Wat gebeurt er met zulke woorden? - Zet in
spamwoordenhet woordschoolerbij, drie keer. Wat gebeurt er nu met het bericht uit vraag 1?
Antwoorden
- Score -5, geen spam.
nugeeft +2 (twee keer in spam) en -1 (één keer in gewone berichten).je,openschooltrekken de score verder omlaag. - Woorden die het filter nooit zag, staan in geen van beide dictionaries en
tellen niet mee. Alleen
hettelt: -1, geen spam. schoolgeeft nu +3 en -2, samen +1 in plaats van -2. De score wordt -2: nog steeds geen spam, maar het scheelde drie punten. Het filter leert van wat je het geeft. Geef je het rare voorbeelden, dan leert het rare dingen.
Opdracht: wat telt het zwaarst?
Laat het filter bij elk woord van het bericht printen wat dat woord aan de
score bijdraagt. Voor "klik hier voor je prijs" wordt dat:
klik 2
hier 1
voor 1
je -3
prijs 1
Begin klein, en breid de code stap voor stap uit:
- Draai de code: hij print de spam-telling van elk woord dat in
spamstaat.jemist nog. - Zet een tweede
ifin de loop voorgewoon, en print daar het woord met min de gewone telling. Nu staatje -3erbij. - Verander het bericht in
"ben je nu op school".nustaat in allebei, en je ziet hem twee keer:nu 2ennu -1. - Maak per woord één variabele
bijdrage: begin op 0, tel de spam-telling erbij en de gewone telling eraf, en print na de tweeif's het woord met zijn bijdrage. Nu krijgtnuéén regel:nu 1.
In de editor staan de tellingen uit het onderzoek al klaar, en een loop met één if.
Tip
Zie je bij stap 4 nog steeds twee regels voor nu? Kijk of de print nog
in een van de if's staat. Hij hoort eronder, op de hoogte van de if's.
Antwoord
Dit vervangt de loop onder de tellingen in de editor:
bericht = "klik hier voor je prijs"
for woord in bericht.split():
bijdrage = 0
if woord in spam:
bijdrage = bijdrage + spam[woord]
if woord in gewoon:
bijdrage = bijdrage - gewoon[woord]
print(woord, bijdrage)
klik 2
hier 1
voor 1
je -3
prijs 1
Zo zie je waarom het filter beslist wat het beslist. Dat is bij elk systeem dat leert een goede vraag: welke stukjes van de invoer gaven de doorslag?
Door naar jouw berichten.