ㅅㅇ
머신러닝 _ 07_ 지도학습 _ 최근접이웃 본문
플레이데이터 빅데이터캠프 공부 내용 _ 7/5
머신러닝 _ 07_ 지도학습 _ 최근접이웃
1. K-최근접 이웃 (K-Nearest Neighbors, KNN)
: 예측하려는 데이터와 input 데이터들 간의 거리를 측정해
가장 가까운 K개의 데이터셋의 레이블을 참조해 분류/예측한다.
- 분류(Classification)와 회귀(Regression) 를 모두 지원한다.
1) 학습시 단순히 input 데이터(train)들을 저장만 하며,
- 학습 할 게 없다. 단순히 저장만 하면 된다.
2) 예측 시점에 거리를 계산한다. 이때 들어온 새로운 데이터셋과 학습 데이터 간의 거리를 계산하는 것
- 학습은 빠르지만, 예측시 시간이 많이 걸린다.
2. 분류 문제 에서의 KNN 예측 예시 설명
- 물음표는 무엇인지 추측하고자 한다.
- K-NN에서 K는 새로운 데이터포인트를 분류할때 확인할 데이터 포인트의 개수를 지정하는 하이퍼파라미터 가 있다.
- K를 1로 하면 파란색 = > overfitting
K를 3으로 하면 주황색 으로 분류한다.
1) K가 너무 작으면 Overfitting (복잡)이 일어날 수 있다. = > K값을 더 크게 잡는다.
2) K가 너무 크면 Underfitting (단순)이 발생할 수 있다. = > K값을 더 작게 잡는다.
- 예측하려는 데이터와 거리가 먼 input 데이터까지 범위로 지정하게 됨.
3. 주요 하이퍼 파라미터
- sklearn.neighbors.KNeighborsClassifier 사용
1) 이웃 수 n_neighbors = K
- K가 작을 수록 모델이 복잡해져 과대적합이 일어나고,
너무 크면 단순해져 성능이 나빠지는 과소적합이 일어난다.
- n_neighbors는 Feature 수의 제곱근 정도를 지정할 때 성능이 좋은 것으로 알려져 있다.
2) 거리 재는 방법 p =
- feature 가 몇 개이든(몇 차원이든) 같은 feature 끼리 아래처럼 연산해주면 됨.
- p=2 유클리디안 거리(Euclidean distance - 기본값)
- p=1: 맨하탄 거리(Manhattan distance)
- 유클리디안 거리(Euclidean_distance)
- 맨하탄 거리 (Manhattan distance)
< 요약 정리 >
- K-NN은 이해하기 쉬운 모델이며 튜닝할 하이퍼파라미터의 수가 적어 빠르게 만들 수있다.
- 계산을 추론할 때 하기에 이때 시간이 많이 걸림으로 서비스 운영할 때는 좋은 모델이 아니다.
- K-NN은 서비스할 모델을 구현할때 보다는 복잡한 알고리즘을 적용해 보기 전에 확인용 또는 base line을 잡기 위한 모델로 사용한다. - 튜닝 전에 기준점 값 (우리가 튜닝하여 더 향상 시키는 작업에서 기준 base line 점)
- 훈련세트가 너무 큰 경우(Feature나 관측치의 개수가 많은 경우) 거리를 계산하는 양이 늘어나 예측이 느려진다.
- 추론에 시간이 많이 걸린다.
- Feature간의 값의 단위가 다르면 작은 단위의 Feature에 영향을 많이 받게 되므로 전처리로 Feature Scaling작업이 필요하다.
- Feature가 너무 많은 경우와 대부분의 값이 0으로 구성된(희소-sparse) 데이터셋에서 성능이 아주 나쁘다.
4. KNN 기본예제 - K 값 변화에 따른 성능 변화 확인
# 위스콘신 유방암 데이터를 이용한 암환자 분류
from sklearn.datasets import load_breast_cancer
1) 데이터 셋 로드, train/test set 분리
import pandas as pd
import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=1)
2) Feature scaling 전처리
- Feature간의 값의 단위가 다르면 작은 단위의 Feature에 영향을 많이 받게 되므로 해야하는 전처리.
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
3) 학습, 예측, 평가
- 하이퍼 파라미터 k값 변화에 따른 accuracy의 변화 확인
= > k_params = range(1,11) # 1 ~ 10
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
train_acc = []
test_acc = []
k_params = range(1,11) # 1 ~ 10
for k in k_params:
# 모델 생성
knn = KNeighborsClassifier(n_neighbors = k) # p = 2 : 기본값 유클리디안 거리
# 학습
knn.fit(X_train_scaled, y_train)
#추론 및 평가
pred_train = knn.predict(X_train_scaled)
pred_test = knn.predict(X_test_scaled)
#평가
train_acc.append(accuracy_score(y_train, pred_train))
test_acc.append(accuracy_score(y_test, pred_test))
4) accuracy 평가 결과 데이터 프레임과 그래프로 최적의 k 값 확인
- 하이퍼 파라미터 k값 변화에 따른 accuracy의 변화 확인
: k=1 에서 부터 커질 때 점차 단순한 모델이 되면서 train set의 성능은 점차 떨어지고
test set은 overfitting에서 벗어나 성능이 좋아지다가 점차 단순한 모델이 되어가면서 유지되고 심하면 낮아짐.
df = pd.DataFrame({
"K":k_params,
"Train":train_acc,
"Test": test_acc
})
df.set_index('K', inplace=True)
df
- 현재 test set 성능을 보면 좋은 편이기에
train 과 test 셋 의 성능 차이가 가장 적게 나는 k = 8 가 최적의 하이퍼파라미터라 생각 된다.
import matplotlib.pyplot as plt
df.plot(figsize=(8,6))
plt.show()
# 가장 성능 차이가 적게 나는 k = 8 정도가 좋을 듯 하다.
5) 최종 평가
best_model = KNeighborsClassifier(n_neighbors=8)
best_model.fit(X_train_scaled, y_train)
#예측
pred_train = best_model.predict(X_train_scaled)
pred_test = best_model.predict(X_test_scaled)
#평가
print('Train 정확도: ',accuracy_score(y_train, pred_train))
print('Test 정확도: ',accuracy_score(y_test, pred_test))
Train 정확도: 0.9741784037558685
Test 정확도: 0.972027972027972
5. GridSearch/Pipline 을 이용해 구현
- Pipeline을 이용해 == > 전처리기와 모델을 연결한다.
- GridSearchCV를 이용해 == > 최적의 하이퍼파라미터를 검색한다.
1) 데이터 셋 로드 및 train/test set 나누기
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score, classification_report
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X,y, stratify=y, random_state=0)
2) Pipeline / GridSearchCV 생성 및 학습
# pipeline
order = [
('scaler', StandardScaler()),
('knn', KNeighborsClassifier())
]
pipeline = Pipeline(order, verbose=True)
# gridsearchCV
param = {
"knn__n_neighbors":range(1,11), # k
"knn__p":[1,2] # 거리재는 방식
}
gs = GridSearchCV(pipeline, param, scoring='accuracy', cv=5, n_jobs=-1)
gs.fit(X_train, y_train)
3) 결과 확인
result_df = pd.DataFrame(gs.cv_results_)
result_df[result_df.columns[6:]].sort_values('rank_test_score').head()
gs.best_params_
{'knn__n_neighbors': 3, 'knn__p': 1}
4) 최종평가
pred_test = gs.predict(X_test)
accuracy_score(y_test, pred_test)
0.958041958041958
print(classification_report(y_test, pred_test))
precision recall f1-score support
0 0.98 0.91 0.94 53
1 0.95 0.99 0.97 90
accuracy 0.96 143
macro avg 0.96 0.95 0.95 143
weighted avg 0.96 0.96 0.96 143
'AI_STUDY > 머신러닝' 카테고리의 다른 글
머신러닝 _ 12_회귀모델개요_평가지표 (0) | 2022.07.14 |
---|---|
머신러닝 _ 08_지도학습_SVM (0) | 2022.07.14 |
머신러닝 _ 06_2_파이프라인 (0) | 2022.07.09 |
머신러닝 _ 06_1_과적합 일반화와 그리드 서치 (0) | 2022.07.06 |
머신러닝 _ 04_데이터 전처리 (0) | 2022.07.01 |