본문 바로가기
컴퓨터공학과/기계학습

1.2. K-NN classifier (실습)

by 수학과인데 공대생 2023. 9. 18.
728x90

본 포스팅은 충남대학교 박정희 교수님의 기계학습 수업과 으뜸 머신러닝 (강영민 , 박동규 저)를 참고하였습니다.

 

K-NN classifier에 대한 이론 정리는 아래 포스팅에서 정리하였습니다.https://math-love.tistory.com/30

 

1.1. K-NN classifier (이론)

본 포스팅은 충남대학교 박정희 교수님의 기계학습 수업과 으뜸 머신러닝 (강영민 , 박동규 저)를 참고하였습니다. K-NN classifier k-NN 알고리즘은 k-Nearest Neighbor의 약자입니다. k-최근접 이웃이라고

math-love.tistory.com

 

 

실습문제

 

문제에서 주어진 csv파일은 iris 데이터입니다.

클래스는 0, 1, 2로 분류되어 있으며 4개의 feature를 가진 iris 데이터입니다.

lab3_test.csv
0.00MB

 

from google.colab import drive
drive.mount('/content/drive')
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split

import numpy as np

우선 google dirve를 mount한 이후 csv파일을 google drive에 저장합니다.

이후, sklearn의 K-NN알고리즘을 사용할 것이기 때문에 KNeighborsClassifier를 import해줍니다.

train_set과 test_set의 분리를 위해 train_test_split를 import하고 csv파일을 읽어들이기 위한 numpy라이브러리까지 import합니다.

 

 

data = np.loadtxt("/content/drive/MyDrive/ML_Lab/report/3/lab3_test.csv", delimiter = ',', dtype = np.float64)

numpy의 loadtxt 메소드를 이용해 google drive에 저장한 csv파일을 읽습니다.

delimiter는 구분자, dtype은 데이터 타입을 의미합니다.

 

# 전체 데이터 샘플의 개수
data_num = len(data)
print(data_num)

# 클래스 레이블 파악
arr = data[:, -1]
unique_values = np.unique(arr)
print(unique_values)

주어진 data의 sample 개수와 class label에 어떤 것이 있는지 알아보는 코드입니다.

2차원 배열에서 len(data)는 행의 개수를 출력해주기 때문에 iris 데이터에서는 sample의 개수와 동일합니다.

 

class label은 2차원 배열의 마지막 열에 있습니다. data[:, -1]로 슬라이싱한 후

numpy의 unique 메소드를 활용해 중복되는 값을 없애줍니다.

 

trn, tst = train_test_split(data, test_size = 0.25, random_state = 0)

x_train = trn[:, :-1]
y_train = trn[:, -1]

x_test = tst[:, :-1]
y_test = tst[:, -1]

이제 train_set과 test_set을 분리해주어야 합니다.

문제에서 train_set과 test_set을 3:1의 비율로 나누라고 했으므로 test_size를 0.25로 지정합니다.

input데이터는 모든 행에서 마지막 열 전까지 이므로 [:, :-1]로 슬라이싱하고

target데이터는 모든 행의 마지막 열이므로 [:, -1]로 슬라이싱합니다.

 

이제 학습을 시켜주면 문제풀이가 끝납니다.

K-NN classifier에서는 k값이 하이퍼파라미터이므로

어떤 k값에서 가장 최적의 성능을 내는지 확인할 필요가 있습니다.

knn = KNeighborsClassifier()

print("== interval: 5 ==")
print("k: ACC")

for k in range(1, int(data_num/3), 5):
  knn.n_neighbors = k
  knn.fit(x_train, y_train)
  y_pred = knn.predict(x_test)
  print(str(k) + ": {:.3f}%".format(np.mean(y_pred == y_test)))

우선 knn 객체를 생성합니다.

그리고 for loop을 통해 최적의 k값을 찾아냅니다.

문제에서 종료 지점을 데이터 sample 개수의 1/3이라고 지정해주었으므로 int(data_num/3)을 종료 지점으로 설정합니다. 다른 데이터가 들어왔을 때 data_num/3이 실수가 되는 것을 방지하기 위해 int로 변환해주어야 합니다.

 

for loop안에서는 x_train과 y_train을 이용해 모델을 학습하고

x_test데이터를 input하여 y_pred를 저장합니다.

마지막으로 'y_pred == y_test' 논리연산을 통해 평균을 구하면 최종 score를 얻을 수 있습니다.

 

iris 데이터는 k값이 커지면 커질 수록 성능이 떨어지는 모습을 보이는 것을 알 수 있습니다.

 

실제로 iris데이터를 시각화해보면

setosa의 경우 잘 나눠져 있으나 versicolor와 virginica는 겹쳐진 data sample들이 일부 존재함을 시각적으로 확인할 수 있습니다.

728x90

'컴퓨터공학과 > 기계학습' 카테고리의 다른 글

2.1. Decision Tree (의사결정 나무)  (0) 2023.09.22
1.1. K-NN classifier (이론)  (0) 2023.09.14