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.
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
- Draai de code. Welke woorden zag de loop meer dan één keer?
- Zet
print(telling)in de loop, onder deelse-tak, op de hoogte van deif. Hoe groeit de dictionary? - Haal de
ifen deelseweg, en laat alleentelling[woord] = telling[woord] + 1in de loop staan. Wat gebeurt er?
Antwoorden
- De loop print
{'gratis': 3, 'geld': 2, 'klik': 2, 'nu': 1, 'prijs': 1}.gratiszag hij drie keer,geldenkliktwee keer. - 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. - 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:
- Draai de code: je ziet elk woord van de zin onder elkaar, en daarna een lege dictionary
{}. - Vervang in de loop de
printdoortelling[woord] = 1, en draai. Elk woord staat nu intelling, maar allemaal met waarde 1. - Maak er een
ifen eenelsevan: staatwoordal intelling, tel er dan 1 bij op, en zet het er anders in met 1. Nu heeftdede waarde 4.
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.