•
분류와 회귀 모두 지원한다
•
예측하려는 데이터와 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
복사