Ga naar hoofdinhoud

Woorden tellen

In het vorige filter schreef jij de lijst verdachte woorden, en de spammer verzon steeds een nieuw woord. Dit filter krijgt geen lijst van jou, maar voorbeelden: berichten waarvan je al weet of ze spam zijn. Het telt welke woorden in spam voorkomen en welke in gewone berichten, en beslist daarmee over een nieuw bericht. Dat is je eerste stukje machine learning: de regels komen uit de data. Eerst leer je tellen.

info

In dit project gebruik je een dictionary uit Dictionaries, kijken of een sleutel erin staat met in uit Door een dictionary lopen, en .split() uit hele woorden.

Voorspel​

telling = {"gratis": 2, "geld": 1}
telling["gratis"] = telling["gratis"] + 1
telling["klik"] = 1
print(telling)

Wat print dit programma?

Antwoord
{'gratis': 3, 'geld': 1, 'klik': 1}

Bij gratis komt er 1 bij. klik stond er nog niet in: dat woord zet Python erbij, met waarde 1.

Zo werkt het​

Een dictionary koppelt een sleutel aan een waarde. Hier is de sleutel een woord, en de waarde hoe vaak je dat woord al zag. Om alle woorden van een lijst te tellen, loop je erlangs. Het patroon in de loop heet tellen met een dictionary:

  • staat het woord al in telling, dan komt er 1 bij;
  • staat het er nog niet in, dan zet je het erin met waarde 1.

Na de loop weet de dictionary hoe vaak elk woord voorkwam. In de runner hieronder staat dat patroon voor negen spamwoorden.

Onderzoek​

  1. Draai de code. Welke woorden zag de loop meer dan één keer?
  2. Zet print(telling) in de loop, onder de else-tak, op de hoogte van de if. Hoe groeit de dictionary?
  3. Haal de if en de else weg, en laat alleen telling[woord] = telling[woord] + 1 in de loop staan. Wat gebeurt er?
Python
Code-omgeving wordt voorbereid…
Antwoorden
  1. De loop print {'gratis': 3, 'geld': 2, 'klik': 2, 'nu': 1, 'prijs': 1}. gratis zag hij drie keer, geld en klik twee keer.
  2. Hij print negen keer, na elk woord. Eerst {'gratis': 1}, dan {'gratis': 1, 'geld': 1}. Een nieuw woord komt achteraan erbij, met waarde 1, en een woord dat er al in staat, krijgt er 1 bij.
  3. Python stopt bij het eerste woord met een foutmelding: telling["gratis"] bestaat nog niet, dus er valt niets bij op te tellen. Zie Er gaat iets mis.

Opdracht: tel de woorden van een zin​

Tel hoe vaak elk woord in de zin uit de editor voorkomt. De uitvoer wordt:

{'de': 4, 'kat': 1, 'zit': 2, 'op': 2, 'mat': 1, 'en': 1, 'hond': 1, 'bank': 1}

Begin klein, en breid de code stap voor stap uit:

  1. Draai de code: je ziet elk woord van de zin onder elkaar, en daarna een lege dictionary {}.
  2. Vervang in de loop de print door telling[woord] = 1, en draai. Elk woord staat nu in telling, maar allemaal met waarde 1.
  3. Maak er een if en een else van: staat woord al in telling, tel er dan 1 bij op, en zet het er anders in met 1. Nu heeft de de waarde 4.
Python
Code-omgeving wordt voorbereid…
Tip

Heeft elk woord na stap 3 nog steeds waarde 1? Kijk wat er in de if staat. Daar moet de nieuwe waarde uit de oude komen, net als bij score.

Antwoord
zin = "de kat zit op de mat en de hond zit op de bank"
woorden = zin.split()

telling = {}
for woord in woorden:
if woord in telling:
telling[woord] = telling[woord] + 1
else:
telling[woord] = 1
print(telling)
{'de': 4, 'kat': 1, 'zit': 2, 'op': 2, 'mat': 1, 'en': 1, 'hond': 1, 'bank': 1}

De woorden staan in de volgorde waarin de loop ze voor het eerst zag.

Er gaat iets mis​

KeyError: 'gratis'

Oorzaak: je telt een woord op dat nog niet in de dictionary staat. telling["gratis"] bestaat de eerste keer nog niet, dus Python kan er niets bij optellen.

Oplossing: kijk eerst of het woord er al in staat, en zet het er anders in met waarde 1.

# FOUT
telling = {}
for woord in ["gratis", "geld", "gratis"]:
telling[woord] = telling[woord] + 1

# GOED
telling = {}
for woord in ["gratis", "geld", "gratis"]:
if woord in telling:
telling[woord] = telling[woord] + 1
else:
telling[woord] = 1

Meer uitleg: Dictionaries.

Door naar twee tellingen.