De buren sorteren
Bij de dichtstbijzijnde buur bepaalde één verkeerd voorbeeld het hele
antwoord. Dat los je op door niet naar één buur te kijken, maar naar de k
dichtstbijzijnde, bijvoorbeeld de drie dichtstbijzijnde. Die buren stemmen,
en de soort met de meeste stemmen wint. Dat heet
k-nearest neighbors, of kortweg k-NN. In deze stap zoek je de k
dichtstbijzijnde buren: je sorteert op afstand en pakt de eerste k.
Je gebruikt hier je functie afstand uit
welk fruit is dit?,
.append() uit Lijst-methoden,
tellen met een dictionary uit
het spamfilter dat leert,
en een loop over de sleutels van een dictionary uit
Door een dictionary lopen.
Voorspel
paren = [(3, "appel"), (1, "banaan"), (11, "banaan"), (2, "appel")]
paren = sorted(paren)
print(paren)
print(paren[:2])
Wat print dit programma?
Antwoord
[(1, 'banaan'), (2, 'appel'), (3, 'appel'), (11, 'banaan')]
[(1, 'banaan'), (2, 'appel')]
Zo werkt het
Twee dingen zijn nieuw.
sorted geeft een gesorteerde kopie van een lijst terug. Een lijst tuples
sorteert hij op het eerste element van elk tuple: hier de afstand. Zijn twee
afstanden gelijk, dan kijkt hij naar het tweede element.
paren[:2] pakt de eerste twee elementen van de lijst. Dat heet
slicing: paren[:k] geeft je de eerste k. Na het sorteren zijn dat
precies de k dichtstbijzijnde buren.
Onderzoek
In paren staan de afstanden van de voorbeelden tot (10, 7), met de
vergissing uit het vorige project: de banaan op afstand 1 is in het echt een
appel.
- Draai de code met
k = 3. Welke drie buren krijg je? - Wat is het verschil tussen
sorted(paren)[:k]enparen[:k]? - Zet
kop 10. Er staan maar zeven paren in de lijst. Wat gebeurt er? - Zet
(3, "citroen")in de lijstparen. Komt hij na het sorteren vóór of na de appels op afstand 3?
Antwoorden
[(1, 'banaan'), (2, 'appel'), (3, 'appel')].paren[:k]pakt de eerste drie zoals ze in de lijst staan, en dat zijn niet de dichtstbijzijnde.sortedverandertparenzelf niet: het geeft een nieuwe lijst terug.- Je krijgt alle zeven, zonder foutmelding. Slicing pakt wat er is.
- Erna. Bij gelijke afstand sorteert
sortedop de soort, en "appel" komt op alfabet vóór "citroen".
Opdracht: zoek de buren
Maak van de voorbeelden een lijst paren met de afstand en de soort, en
print de k dichtstbijzijnde buren:
buren: [(1, 'banaan'), (2, 'appel'), (3, 'appel')]
Begin klein, en breid de code stap voor stap uit:
- Draai de code: hij print bij elk voorbeeld de afstand en de soort.
- Zet in plaats van de print het tuple
(d, soort)met.append()inparen, en printparenna de loop. - Sorteer
paren, pak de eerstek, en print die buren.
Tip
.append() zet één ding in een lijst. Wil je er twee dingen tegelijk in
zetten, maak er dan eerst één ding van.
Antwoord
Dit vervangt de loop onderaan de editor:
for maten, soort in voorbeelden:
d = afstand(nieuw, maten)
paren.append((d, soort))
buren = sorted(paren)[:k]
print("buren:", buren)
buren: [(1, 'banaan'), (2, 'appel'), (3, 'appel')]
Er gaat iets mis
TypeError: list.append() takes exactly one argument (2 given)
Oorzaak: append zet één ding in een lijst. Met
paren.append(3, "appel") geef je er twee: een getal en een tekst.
Oplossing: maak er één tuple van, met een extra paar haakjes.
# FOUT
paren.append(3, "appel")
# GOED
paren.append((3, "appel"))
Door naar stemmen tellen.