#!/usr/bin/env python3

k_NN(k-최근접 이웃) Regression


k-NN 회귀모델을 알아보겠습니다.
k-NN regression의 동작환경은 다음과 같습니다.

import mglearn

import matplotlib.pyplot as plt

mglearn.plots.plot_knn_regression(n_neighbors=1)
plt.show()

n_neighbors=1 일때 algorithm

x축에 3개의 테스트 데이터를 녹색 별로 표시합니다.
최근접 이웃을 한 개만 사용할 때 예측은 가장 가까운 데이터 포인트의 값으로 인식합니다.

다음은 이웃의 수가 3일 때 knn algorithm의 동작 환경입니다.
mglearn.plots.plot_knn_regression(n_neighbors=3)
plt.show()

n_neighbors=3 일때 algorithm

마찬가지로 3개의 녹색 테스트 데이터를 기준으로 가장 이웃한 3개의 최근접 데이터 포인트를 구합니다.
그리고 나서 각 데이터포인트사이의 거리의 역수를 가중치로 타겟 값을 산정합니다.


이해를 돕기위해 인위적 데이터를 사용하여 k-NN Regression을 사용해보겠습니다.
from mglearn.datasets import make_wave
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsRegressor

x, y = make_wave(n_samples=40)

x_train, x_test, y_train, y_test = \
  train_test_split(x, y, 
                   random_state=0, test_size=0.3)

knn_reg = KNeighborsRegressor(n_neighbors=3, n_jobs=-1) n_jobs = 사용할 코어의 수, -1 => 모든 코어 사용
knn_reg.fit(x_train, y_train)

print('{:.3f}'.format(knn_reg.score(x_test, y_test)))
# 0.697


1차원 데이터 셋이므로 시각화가 가능하므로 n_neighbors의 값에 따라 어떻게 변하는지 확인해보겠습니다.
import numpy as np
_, axes = plt.subplots(1, 3)

line = np.linspace(-5, 5, num=1000)
line = line.reshape(-1, 1)

for i, ax in zip([1, 3, 9], axes.ravel()):
    knn_reg = KNeighborsRegressor(n_neighbors=i, n_jobs=-1)
    knn_reg.fit(x_train, y_train)

    prediction = knn_reg.predict(line)
    ax.plot(line, prediction, label='model predict', c='k'
    ax.scatter(x_train, y_train, marker='^', c='darkred', label='train target')
    ax.scatter(x_test, y_test, marker='v', c='darkblue', label='test target')
    
    train_score = knn_reg.score(x_train, y_train)
    test_score = knn_reg.score(x_test, y_test)
    ax.set_title('k={}\ntest score={:.3f}\ntrain score={:.3f}'.format(i, train_score, test_score))
    ax.set_xlabel('feature')
    ax.set_ylabel('target')
axes[0].legend(loc=2)
plt.show()

n_neighbors 값에 따라 최근접 이웃 회귀로 만들어진 예측 회귀 비교

이웃을 하나만 사용할 때는 훈련 세트의 각 데이터 포인트가 모든 선을 통과합니다. 이 것은 너무 복잡하게 모델이 짜여져 있는 것을 말하며 실제로 예측할 때는 그 결과가 좋지 못합니다. 반대로 이웃을 많이 사용할 수록 훈련 데이터에는 잘 안맞을 수 있지만 높은 정확도를 얻게 됩니다.


k-NN은 이해하기 매우 쉬운 모델입니다. 그러나 수백 개 이상의 많은 특성을 가진 데이터 셋에는 잘 동작하지 않으며 특성값이 0이 많은 데이터셋이는 잘 작동하지 않습니다.
또한 예측이 느리고, 많은 특성을 처리하는 능력이 부족하여 현업에서는 잘 쓰지 않습니다.
KNeighborsRegressor와 KNeighborsClassifier의 객체를 생성할 때 'metric' parameter를 사용하여 거리 측정 방식을 변경할 수 있습니다. 'metric' parameter의 기본값은 'minkowski', 거듭제곱의 크기를 정하는 parameter느 'p'입니다.
metric='minkowski', p=2는 metric='euclidean'과 같습니다.



참고 자료: 

[1]Introduction to Machine Learning with Python, Sarah Guido


'python 머신러닝 -- 지도학습 > Regression' 카테고리의 다른 글

Decision Tree Regressor  (0) 2018.03.14
Lasso  (0) 2018.03.13
Ridge  (0) 2018.03.12
LinearRegression  (0) 2018.03.12

+ Recent posts