Ga naar hoofdinhoud

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.

  1. Probeer "ben je nu op school". Het woord nu staat in de spam én in de gewone berichten. Wat doet het met de score?
  2. Probeer "hoe laat is het". De meeste woorden heeft het filter nooit gezien. Wat gebeurt er met zulke woorden?
  3. Zet in spamwoorden het woord school erbij, drie keer. Wat gebeurt er nu met het bericht uit vraag 1?
Python
Code-omgeving wordt voorbereid…
Antwoorden
  1. Score -5, geen spam. nu geeft +2 (twee keer in spam) en -1 (één keer in gewone berichten). je, op en school trekken de score verder omlaag.
  2. Woorden die het filter nooit zag, staan in geen van beide dictionaries en tellen niet mee. Alleen het telt: -1, geen spam.
  3. school geeft 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:

  1. Draai de code: hij print de spam-telling van elk woord dat in spam staat. je mist nog.
  2. Zet een tweede if in de loop voor gewoon, en print daar het woord met min de gewone telling. Nu staat je -3 erbij.
  3. Verander het bericht in "ben je nu op school". nu staat in allebei, en je ziet hem twee keer: nu 2 en nu -1.
  4. Maak per woord één variabele bijdrage: begin op 0, tel de spam-telling erbij en de gewone telling eraf, en print na de twee if's het woord met zijn bijdrage. Nu krijgt nu één regel: nu 1.

In de editor staan de tellingen uit het onderzoek al klaar, en een loop met één if.

Python
Code-omgeving wordt voorbereid…
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.