Ch3-1에서는 KNN 회귀 알고리즘과 그 한계에 대해 공부합니다.
KNN 알고리즘은 분류 뿐만 아니라 회귀에서도 사용할 수 있습니다.
값들은 인접한 \(k\)개의 값들의 평균으로 계산됩니다.
KNN 회귀함수는 사이킷런의 KNeighborRegressor을 import하여 사용할 수 있습니다.
어떤 물고기의 데이터를 받아 그래프를 찍어봅시다.
fish_length = np.array([8.4, 13.7, 15.0, 16.2, 17.4, 18.0, 18.7, 19.0, 19.6, 20.0, 21.0,
21.0, 21.0, 21.3, 22.0, 22.0, 22.0, 22.0, 22.0, 22.5, 22.5, 22.7,
23.0, 23.5, 24.0, 24.0, 24.6, 25.0, 25.6, 26.5, 27.3, 27.5, 27.5,
27.5, 28.0, 28.7, 30.0, 32.8, 34.5, 35.0, 36.5, 36.0, 37.0, 37.0,
39.0, 39.0, 39.0, 40.0, 40.0, 40.0, 40.0, 42.0, 43.0, 43.0, 43.5,
44.0])
fish_weight = np.array([5.9, 32.0, 40.0, 51.5, 70.0, 100.0, 78.0, 80.0, 85.0, 85.0, 110.0,
115.0, 125.0, 130.0, 120.0, 120.0, 130.0, 135.0, 110.0, 130.0,
150.0, 145.0, 150.0, 170.0, 225.0, 145.0, 188.0, 180.0, 197.0,
218.0, 300.0, 260.0, 265.0, 250.0, 250.0, 300.0, 320.0, 514.0,
556.0, 840.0, 685.0, 700.0, 700.0, 690.0, 900.0, 650.0, 820.0,
850.0, 900.0, 1015.0, 820.0, 1100.0, 1000.0, 1100.0, 1000.0,
1000.0])
# 분포 확인
plt.scatter(fish_length, fish_weight)
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
이제 KNN 알고리즘을 수행해줍시다.
# train, test data set
train_X, test_X, train_Y, test_Y=train_test_split(
fish_length, fish_weight, random_state=42
)
# 2차원 배열로 전환
train_X=train_X.reshape(-1,1)
test_X=test_X.reshape(-1,1)
# knn 회귀
knr=KNeighborsRegressor()
knr.fit(train_X, train_Y)
print(knr.score(test_X, test_Y))
그 결과는
0.992809406101064
가 나오게 됩니다. 테스트 결과가 만족스럽네요. 하지만 이런 입력은 어떨까요?
지금까지 훈련한 범위를 벗어나는 값을 줘보는 것입니다. 그 값을 찍은 그래프를 보면,
노란 점과 초록점은 훈련데이터와 동떨어진 점입니다.
현재 두 점의 좌표는 각각 (47.4, 1342.2) , (49.2 , 1512.9) 입니다. .
이제 KNN 회귀로 예측해보겠습니다.
print(knr.predict([[47.4]]))
print(knr.predict([[49.2]]))
그 결과는
[1010.]
[1010.]
아.. 문제가 생겼습니다. 그보다 두 값을 같다고 예측을 한다니 뭐가 잘못된걸까요?
KNN 알고리즘은 현재 데이터들중에서 \(k\) 개로 예측을 하는 모델입니다. 따라서 어느정도 범위를
넘어간다면 당연히 선택되는 영역도 같아지고 그 평균 또한 훈련데이터 안에서만 놀게 됩니다.
즉, 새로운 length에 비례하는 더 큰 weight를 예측해주지 못한다는 단점을 지니고 있습니다.
이를 해결하기 위한 한 방법으로 선형 회귀가 있습니다. 이 부분은 3-2에서 공부합니다.
오늘의 전체 코드입니다.
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsRegressor
fish_length = np.array([8.4, 13.7, 15.0, 16.2, 17.4, 18.0, 18.7, 19.0, 19.6, 20.0, 21.0,
21.0, 21.0, 21.3, 22.0, 22.0, 22.0, 22.0, 22.0, 22.5, 22.5, 22.7,
23.0, 23.5, 24.0, 24.0, 24.6, 25.0, 25.6, 26.5, 27.3, 27.5, 27.5,
27.5, 28.0, 28.7, 30.0, 32.8, 34.5, 35.0, 36.5, 36.0, 37.0, 37.0,
39.0, 39.0, 39.0, 40.0, 40.0, 40.0, 40.0, 42.0, 43.0, 43.0, 43.5,
44.0])
fish_weight = np.array([5.9, 32.0, 40.0, 51.5, 70.0, 100.0, 78.0, 80.0, 85.0, 85.0, 110.0,
115.0, 125.0, 130.0, 120.0, 120.0, 130.0, 135.0, 110.0, 130.0,
150.0, 145.0, 150.0, 170.0, 225.0, 145.0, 188.0, 180.0, 197.0,
218.0, 300.0, 260.0, 265.0, 250.0, 250.0, 300.0, 320.0, 514.0,
556.0, 840.0, 685.0, 700.0, 700.0, 690.0, 900.0, 650.0, 820.0,
850.0, 900.0, 1015.0, 820.0, 1100.0, 1000.0, 1100.0, 1000.0,
1000.0])
# 분포 확인
plt.scatter(fish_length, fish_weight)
plt.scatter(47.4, 1342.2, marker='^')
plt.scatter(49.2, 1512.9, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
# train, test data set
train_X, test_X, train_Y, test_Y=train_test_split(
fish_length, fish_weight, random_state=42
)
# 2차원 배열로 전환
train_X=train_X.reshape(-1,1)
test_X=test_X.reshape(-1,1)
# knn 회귀
knr=KNeighborsRegressor()
knr.fit(train_X, train_Y)
print(knr.score(test_X, test_Y))
print(knr.score(train_X, train_Y))
print(knr.predict([[47.4]]))
print(knr.predict([[49.2]]))
'CS > 머신러닝' 카테고리의 다른 글
혼자 공부하는 머신러닝 + 딥러닝 - Ch 3-3 (0) | 2023.01.11 |
---|---|
혼자 공부하는 머신러닝 + 딥러닝 - Ch3-2 (0) | 2023.01.08 |
혼자 공부하는 머신러닝 + 딥러닝 - Ch2 (0) | 2023.01.07 |
혼자 공부하는 머신러닝 + 딥러닝 - Ch1 (0) | 2023.01.04 |
로지스틱 회귀 (0) | 2022.12.20 |
댓글