K-Nearest Neighbor 알고리즘을 이용하여 Iris Classification 문제 해결하기
가장 가까운 K개의 이웃(training data)을 골라 이웃의 output을 합하여 test data의 output을 도출해냄
✔ A distance metric : Euclidean
✔ Number of neighbors to consult : k(3, 5, 7) Ÿ Combining neighbors’ outputs :
Classification(0: setosa, 1: versicolor, 2: virginica)
Majority vote : 가장 가까운 K개의 이웃의 output 중 가장 많이 나온 것의 output을 test data의 output으로 함
Weighted majority vote : 가장 가까운 K개의 이웃을 거리에 따라 가중치를 두어 합산하고, 그 값이 가장 큰 것의 output을 test data의 output으로 함
iris data의 매 15번째 data를 test data로 추출하고, 나머지 data를 train data로 이용하여 입력받은 test data와의 거리를 구해 가장 거리가 가까운 train data K개의 class 이름을 배열로 return
import numpy as np
from sklearn.datasets import load_iris
class Knn:
def __init__(self):
self.iris = load_iris()
self.X = list(self.iris.data)
self.Y = list(self.iris.target)
self.y_name = self.iris.target_names
# test data로 추출한 data를 training data에서 제거
del self.X[14::15]
del self.Y[14::15]
# 입력된 test data에 대해 모든 training data와의 거리 리스트 반환
def calculate_distance(self, test_data):
# 좌표 간의 거리
x_distance = (np.array(self.X) - np.array(test_data))**2
distance = x_distance.sum(axis=1)**(1/2)
return distance
# K개의 거리가 가장 가까운 data의 index 리스트 반환
def obtain_KNN(self, k, distance_list):
# 측정한 거리 값을 저장한 리스트를 오름차순으로 정렬하여
# 앞에서부터 K개 선택하여 인덱스를 저장
idx = (distance_list).argsort()[:k]
return idx
def obtain_majority_vote(self, k, distance_list):
idx = self.obtain_KNN(k, distance_list)
vote = np.array([0, 0, 0])
# 각 index가 포함된 class의 값을 1 증가
for i in idx:
vote[self.Y[i]] += 1
return self.y_name[vote.argmax()]
def obtain_weighted_majority_vote(self, k, distance_list):
idx = self.obtain_KNN(k, distance_list)
weighted_vote = np.array([0., 0., 0.])
# 거리가 가까울수록 가중치가 커져야하므로
# 각 index가 포함된 class의 값을 거리에 반비례하게 가중치를 부여하여 증가
for i in idx:
weighted_vote[self.Y[i]] += 1/distance_list[i]
return self.y_name[weighted_vote.argmax()]
numpy에서 np.sum의 axis
axis=0 : x축(열(column)별로 더함)
axis=1 : y축(행(row)별로 더함)
매 15번째 data를 추출하여 분류 결과 확인
import knn_class
from sklearn.datasets import load_iris
iris = load_iris()
knn = knn_class.Knn()
# 매 15번째 data(14th, 29th, ...)는 test data로 추출
test_data = iris.data[14::15]
test_target = iris.target[14::15]
name = iris.target_names
k = int(input("k = "))
# majority vote를 이용하여 구하는 경우
print("*** obtain majority vote ***")
for i in range(len(test_data)):
print('Test Data Index: ', i, ' Computed class: ', knn.obtain_majority_vote(k, knn.calculate_distance(test_data[i])), ' True Class: ', name[test_target[i]])
# weighted majority vote를 이용하여 구하는 경우
print("*** obtain weighted majority vote ***")
for i in range(len(test_data)):
print('Test Data Index: ', i, ' Computed class: ', knn.obtain_weighted_majority_vote(k, knn.calculate_distance(test_data[i])), ' True Class: ', name[test_target[i]])