조금씩 꾸준히 완성을 향해

[Sklearn] K-Nearest Neighbor Regression(k-최근접 이웃 회귀) 본문

AI/Machine Learning

[Sklearn] K-Nearest Neighbor Regression(k-최근접 이웃 회귀)

all_sound 2022. 10. 27. 17:51

k-최근접 이웃 분류 vs 회귀

  • 샘플에 가장 가까운 샘플 k개 선택한 후 이 수치들의 평균을 구하여 새로운 샘플의 타깃값 예측.
  • 분류에서는 이웃의 label 개수를 확인해서 다수결로 타깃값을 예측했지만, 회귀에서는 이웃들의 평균을 계산한다는 점에서 차이.

 


▶ 농어의 길이로 무게 예측 예제

 

# 농어의 길이, 무게로 산점도 그리기

import matplotlib.pyplot as plt

plt.scatter(perch_length, perch_weight)
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

# 훈련, 테스트 세트 나누기

from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(
    perch_length, perch_weight, random_state=42)

# 1차원 배열 => 2차원 배열
train_input = train_input.reshape(-1, 1)
test_input = test_input.reshape(-1, 1)
# 회귀 모델 훈련

from sklearn.neighbors import KNeighborsRegressor

knr = KNeighborsRegressor()
knr.fit(train_input, train_target)
knr.score(test_input, test_target)

score 함수 - 분류일 경우 정확도, 회귀일 경우 결정계수(R^2) 반환

 

▶ 결정 계수 (Coefficient of determination, R^2)

  • 결정계수가 0에 가까우면 타깃의 평균 정도를 예측하는 수준이고, 결정 계수가 1에 가까우면 예측이 타깃에 아주 가깝다는 의미

 

# 평균 절대값 오차 구하기
from sklearn.metrics import mean_absolute_error

test_prediction = knr.predict(test_input)
mae = mean_absolute_error(test_target, test_prediction) 
print(mae) # 정확학 값에서 +- 19.157g 정도의 오차가 있다.

 

▶ 과대적합(Overfitting) & 과소적합(Underfitting)

 

과대적합

  • 모델이 훈련 세트에서는 좋은 성능을 내지만 검증 세트에서는 낮은 성능을 내는 경우.
  • 훈련 세트와 검증 세트에서 측정한 성능의 간격이 큼 = 분산이 큼(high variance)

과소적합

  • 훈련 세트와 검증 세트의 성능에는 차이가 크지 않지만 모두 낮은 성능을 내는 경우. 
  • 훈련 세트와 검증 세트의 성능이 서로 가까워지면 성능 자체가 낮음 =  '편향이 큼(high bias)'
# 과소 적합(underfitting)
print(knr.score(train_input, train_target))
print(knr.score(test_input, test_target))
# 0.9698823289099254
# 0.992809406101064

 

  •  개선책 - 이웃 개수 줄이기
knr.n_neighbors = 3
knr.fit(train_input, train_target)
print(knr.score(train_input, train_target))
print(knr.score(test_input, test_target))
# 0.9804899950518966
# 0.9746459963987609

 

  • 이웃 개수에 따른 과대/과소 적합 정도 확인
# x좌표 범위설정
x= np.arange(5, 45).reshape(-1,1)

# subplot 만들기
fig = plt.figure(figsize=(15,8))
for i in range(4):
    globals()[f'ax{i+1}'] = fig.add_subplot(2, 2, i+1)
# 이웃 개수에 따른 예측값 그래프 그리기
for i, k in enumerate([1, 10, 30, 40]):
  knr = KNeighborsRegressor(n_neighbors=k)
  knr.fit(train_input, train_target)
  pred = knr.predict(x)
  globals()[f'ax{i+1}'].scatter(train_input, train_target)
  globals()[f'ax{i+1}'].plot(x, pred)
  globals()[f'ax{i+1}'].set_title(f'n_neighbors={k}')
  globals()[f'ax{i+1}'].set_xlabel('length')
  globals()[f'ax{i+1}'].set_ylabel('weight')
plt.show()

 

 

 

  • 참고 - [한빛미디어] 혼자 공부하는 머신러닝+딥러닝, 박해선 저