Search

KNN

분류와 회귀 모두 지원한다
예측하려는 데이터와 input데이터들간의 거리를 측정해 가장 가까운 K개의 데이터의 레이블을 참조해 분류/예측한다.
학습은 빠르지만 예측시 시간이 많이 걸린다.
k가 하이퍼파라미터
k가 너무 작으면 overfitting되고 너무 크면 성능이 underfitting 된다.

주요 하이퍼파라미터

이웃 수(k)
n_neighbors : 피처수의 제곱근으로 지정할 때 성능이 좋은 것으로 알려져 있다.(default=5)
distance 재는 방법
p=2 : 유클리디안 거리(default)
p=1 : 맨하탄 거리
p = 아무숫자 : minkowski 거리

요약

knn은 이해하기 쉽고 하이퍼파라미터 수가 적어 빠르게 만들 수 있다.
일반적으로 모델 구현보다는 base line을 잡기 위한 모델로 사용된다.
훈련세트가 너무 큰 경우(피처 수가 많거나 관측개수가 많은 경우) 거리를 계산하는 양이 늘어나 예측이 느려진다.
피처 간의 값의 단위가 너무 다르면 작은 단위의 피처에 영향을 많이 받기 때문에 scaling 과정이 필요하다.
피처수가 너무 많거나 대부분의 값이 0인 희소데이터셋에서 성능이 매우 나쁘다.

위스콘신 유방암 데이터를 이용한 암환자분류 예제

malignant : 악성
benign : 양성
import pandas as pd import numpy as np import sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split cancer = load_breast_cancer() X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, stratify = cancer.target) # feature scaling from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) # knn from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import accuracy_score k_param = range(1,11) # k값을 1~10 변경해가면서 성능 체크 train_acc_list = [] test_acc_list = [] for k in k_param: knn = KNeighborsClassifier(n_neighbors=k) # 모델 학습 knn.fit(X_train_scaled, y_train) # 예측 및 검증 pred_train = knn.predict(X_train_scaled) pred_test = knn.predict(X_test_scaled) # 성능점수를 list에 추가 train_acc_list.append(accuracy_score(y_train,pred_train)) test_acc_list.append(accuracy_score(y_test,pred_test)) dic = { 'k':k_param, 'Train 정확도' : train_acc_list, 'Test 정확도' : test_acc_list } acc_df = pd.DataFrame(dic)
Python
복사
import matplotlib.pyplot as plt acc_df2 = acc_df.set_index('k') acc_df2 = acc_df2.sort_index(ascending=False) acc_df2.plot(figsize=(7,7)) plt.plot(acc_df2.index, acc_df2['Train 정확도']) plt.plot(acc_df2.index, acc_df2['Test 정확도']) plt.xlabel('K값-모델의 복잡도') plt.show()
Python
복사

파이프라인(scaling, knn), gridsearchcv

from sklearn.model_selection import GridSearchCV from sklearn.pipeline import Pipeline pipeline = Pipeline([ ('scaler', StandardScaler()), ('knn', KNeighborsClassifier()) )] param_grid = { 'knn_n_neighbors':range(1,11), 'knn_p':[1,2] # 1은 맨하탄, 2는 유클리디안 } gs = GridSearchCV(pipeline, param_grid = param_grid, cv=5) gs.fit(X_train, y_train)
Python
복사
gs.best_score_ # 가장 좋은 성능 지표값 gs.best_params_ # 가장 좋은 파라미터 조합 gs.best_estimator_ # 가장 좋은 모델 # 가장 좋은 모델로 학습 best_model = gs.best_estimator_ best_model.fit(X_train_scaled, y_train) # 예측 검증 pred_train = best_model.predict(X_train_scaled) pred_test = best_model.predict(X_test_scaled) accuracy_score(pred_train,y_train), accuracy_score(pred_test, y_test) accuracy_score(y_train, gs.predict(X_train_scaled))
Python
복사