This is an old revision of the document!
Einführung
Ziel
Den $k$-nearest-neighbour Algorithmus in $\mathbb{R}^2$ implementieren.
Wichtige Zutaten
Empfehlung: Mindestens zwei Funktionen definieren. Eine zur Berechnugn der Distanz-Klassen-Liste, eine zur Zuweisung der Klasse (0 oder 1).
Wer $k$-nearest-neighbour implementiert hat, kann sich überlegen, wie die untenstehende Daten klassifiziert werden sollen:
Die Daten finden sich in einer neuen ZIP-Datein
- knn.py
from gpanel import *
import time
import csv # um Text-Dateien im CSV-Format zu lesen
import random
# CSV-File oefffnen
csvfile = open('C:/temp/data.csv', 'r')
# CSV-File einlesen.
reader = csv.reader(csvfile, delimiter=',',
quoting=csv.QUOTE_NONNUMERIC)
# CSV-File in Liste umwandeln
datalist = list(reader)
# GPanel aufsetzen
makeGPanel(-20, 20, -20, 20)
drawGrid(-15, 15, -15, 15)
# Punkte zeichnen
for i in range(len(datalist)):
move(datalist[i][0], datalist[i][1])
if int(datalist[i][2]) == 1:
setColor('orange')
else:
setColor('green')
fillCircle(0.1)
# Funktion, die einem Punkt eine Klasse auf Grund der k naechsten Nachbarn zuweist.
def assignClass(point, k):
# Funktion die die Distanzen vom Punkt zu den exisitierenden Punkte berechnet
# Liste um die Distanzen zu speichern. Achtung: Speicher!!
distlist = []
#
for i in range(len(datalist)):
distlist.append([datalist[i][2], sqrt((point[0]
- datalist[i][0]) ** 2 + (point[1]
- datalist[i][1]) ** 2)])
# das waere ein sehr Pythonesquer Weg mit Lambda-Funktionen
# nearest = sorted(distlist,key=lambda result:result[1])
# definiere eine Funktion, welche das zweite Element zurueckgibt. ....
def sortFunction(item):
return item[1]
# Sortiere die liste! Achtung: Man koennte auch ohne key Arbeiten, wenn Distanz an 1. Stelle waere
nearest = sorted(distlist, key=sortFunction)
# Zaehle Klassennummern und entscheide ueber Klasse. Achtung: Laesst sich so nicht auf k>2 Klassen erweitern.
classsum = sum([nearest[i][0] for i in range(k)])
if classsum > k / 2:
retclass = 1
elif classsum < k / 2:
retclass = 0
else:
retclass = random.randint(0, 1)
return retclass
# Funktion um Pt zu zeichnen und mit Label auf Grund der k-naechsten Nachbarn zu versehen
def drawAndLablePoint(point, k):
guessedclass = assignClass(point, k)
move(point)
setColor('black')
fillRectangle(0.02, 0.02)
text(str(guessedclass))
# Programm teseten
drawAndLablePoint([-0.5, 0.5], 3)
drawAndLablePoint([0.5, 0.5], 3)
print assignClass([-1, -1], 3)
print assignClass([-1, 1], 3)
print assignClass([1, -1], 3)
print assignClass([1, 1], 3)
print assignClass([-1, 0.5], 3)