UOMOP
농어(perch) 무게 예측 using "k-최근접 이웃 회귀" 본문
지도 학습에는 분류(Classify), 회귀(Regress)가 있다,
- "분류"는 종류를 분류하는 것이고, 예를 들어서 도미와 빙어의 데이터로 학습을 한 후에, 새로운 샘플에 대해서 도미인지 빙어인지 확인하는 실습이 있었다.
- "회귀"는 임의의 숫자를 예측하는 것이고, 예를 들어 데이터를 통해서 학습을 한 후에, 새로운 샘플에 대해서 임의의 특징에 대한 값을 예측하는 실습이 있다.
k-최근접 이웃
- k-최근접 이웃 분류는 실험 샘플의 주변 중 더 많은 target으로 분류시키는 과정이었다면
- k-최근점 이웃 회귀는 실험 샘플의 주변의 데이터를 평균을 내어 target값을 예측한다.
1. 농어의 길이, 무게 데이터를 가져오고 각종 module을 호출
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import mean_absolute_error
from sklearn.neighbors import KNeighborsRegressor
from sklearn.model_selection import train_test_split
perch_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]
)
perch_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]
)
2. 위의 데이터가 어떤 그래프 개형을 가지는 확인
plt.scatter(perch_length, perch_weight)
plt.xlabel("length")
plt.ylabel("weight")
plt.show()
3. input data를 2차원 배열로
print("perch_length 의 1차원 Data : \n{}".format(perch_length))
print("")
print("perch_weight 의 1차원 Data : \n{}".format(perch_weight))
perch_length의 1차원 Data : [ 8.4 13.7 15. 16.2 17.4 18. 18.7 19. 19.6 20. 21. 21. 21. 21.3 22. 22. 22. 22. 22. 22.5 22.5 22.7 23. 23.5 24. 24. 24.6 25. 25.6 26.5 27.3 27.5 27.5 27.5 28. 28.7 30. 32.8 34.5 35. 36.5 36. 37. 37. 39. 39. 39. 40. 40. 40. 40. 42. 43. 43. 43.5 44. ]
perch_weight의 1차원 Data : [ 5.9 32. 40. 51.5 70. 100. 78. 80. 85. 85. 110. 115. 125. 130. 120. 120. 130. 135. 110. 130. 150. 145. 150. 170. 225. 145. 188. 180. 197. 218. 300. 260. 265. 250. 250. 300. 320. 514. 556. 840. 685. 700. 700. 690. 900. 650. 820. 850. 900. 1015. 820. 1100. 1000. 1100. 1000. 1000. ]
ML 모델에서는 input data가 2차원 배열로 입력이 되어야 한다. 1차원인 데이터를 2차원으로 바꿔주는 과정이 필요하다. 위 내용에서는 input data가 perch_length이므로 perch_length를 2차원 배열로 바꿔주도록 하자.
perch_length = perch_length.reshape(-1, 1)
print("perch_length 의 2차원 Data : \n\n{}".format(perch_length))
2차원 배열이 된 것을 확인할 수 있다.
4. 학습/검증 데이터 분리, 학습, 성능확인
train_input, test_input, train_target, test_target = train_test_split(perch_length,
perch_weight, random_state = 42)
knr = KNeighborsRegressor()
knr.fit(train_input, train_target)
print("성능 확인 : {}".format(knr.score(test_input, test_target)))
성능 확인 : 0.992809406101064
"분류"에서는 score()메소드를 통해 정확도를 반환받을 수 있었다.
"회귀"에서는 score()메소드를 통해 R^2(결정계수)를 반환받는다.
"회귀" 모델에서는 score()를 통해 결정계 수로 성능을 평가할 수 있지만, 다른 성능 지표들도 존재한다.
그중 평균 절댓값 오차를 이용하여 또 다른 성능 지표를 확인해보도록 한다.
test_prediction = knr.predict(test_input)
mae = mean_absolute_error(test_prediction, test_target)
print("'평균 제곱 오차'를 통해 확인해본 성능 점수 : {}".format(mae))
'평균 제곱 오차'를 통해 확인해본 성능 점수 : 19.157142857142862
평균 제곱 오차가 약 19g이 확인되었다.
5. 과적합 확인
print("train data로 확인 해본 score : {}".format(knr.score(train_input, train_target)))
print("")
print("test data로 확인 해본 score : {}".format(knr.score(test_input, test_target)))
train data로 확인해본 score : 0.9698823289099254
test data로 확인 해본 score : 0.992809406101064
train data로 확인해본 score이 test data로 확인해본 score보다 더 높아야 한다.
위와 같이 train data로 확인해본 score이 더 낮은 경우, 과소적합(underfitting)된 상황이다.
반면에 train data로 확인 해본 score이 더 높지만, test data로 확인 해본 score이 너무 낮은 경우에는 과대 적합(overfitting)이라고 한다.
k-최근접 이웃 회귀 모델에서는 k(이웃)의 개수를 줄이면 과대 적합, 늘리면 과소 적합이 발생한다.
현재 과소 적합이 발생했으므로 k(이웃)의 개수를 줄여야 할 것이다.
6. 최적의 k(이웃) 값 도출
for i in range(1, 5) :
knr.n_neighbors = i
knr.fit(train_input, train_target)
print("##### k(이웃)의 갯수 : {} ####".format(i))
print("train data로 확인해본 결정계수 : {:.5f}".format(knr.score(train_input, train_target)))
print("test data로 확인해본 결정계수 : {:.5f}".format(knr.score(test_input, test_target)))
print("두 결정계수의 차이의 절대값 : {:.5f}".format((knr.score(train_input, train_target)-knr.score(test_input, test_target))))
print("")
##### k(이웃)의 개수 : 1 ####
train data로 확인해본 결정계수 : 0.98528
test data로 확인해본 결정계수 : 0.99131
두 결정계수의 차이의 절댓값 : -0.00603
##### k(이웃)의 개수 : 2 ####
train data로 확인해본 결정계수 : 0.98284
test data로 확인해본 결정계수 : 0.97250
두 결정계수의 차이의 절댓값 : 0.01034
##### k(이웃)의 개수 : 3 ####
train data로 확인해본 결정계수 : 0.98049
test data로 확인해본 결정계수 : 0.97465
두 결정계수의 차이의 절댓값 : 0.00584
##### k(이웃)의 개수 : 4 ####
train data로 확인해본 결정계수 : 0.97821
test data로 확인해본 결정계수 : 0.98402
두 결정계수의 차이의 절댓값 : -0.00581
k(이웃)의 개수가 2, 3 일 때가 가장 좋은 성능을 보여주고 있다. k를 3으로 설정하고 학습을 시켜보도록 한다.
7. 최적의 매개변수로 학습시킨 후, 예측 결과 확인
knr.n_neighbors = 3
knr.fit(train_input, train_target)
print("17cm 농어의 예측된 무게 : {}".format(knr.predict([[17]])))
print("32cm 농어의 예측된 무게 : {}".format(knr.predict([[32]])))
print("40cm 농어의 예측된 무게 : {}".format(knr.predict([[40]])))
17cm 농어의 예측된 무게 : [62.66666667]
32cm 농어의 예측된 무게 : [636.66666667]
40cm 농어의 예측된 무게 : [921.66666667]
'Ai > ML' 카테고리의 다른 글
Linear Regression(선형 회귀) (0) | 2022.01.25 |
---|---|
k-최근접 이웃 model의 문제점 (0) | 2022.01.25 |
전처리 과정 中 Scaling의 중요성 (0) | 2022.01.23 |
KNeighborsClassifier(k-최근접 이웃)의 기본 (0) | 2022.01.23 |
타이타닉 생존자 예측 using DecisionTreeClassifier (0) | 2022.01.15 |
Comments