Notice
Recent Posts
Recent Comments
Link
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Tags
more
Archives
Today
Total
관리 메뉴

kang's study

4일차 : k-최근접 이웃 회귀 본문

[학습 공간]/[혼공머신러닝]

4일차 : k-최근접 이웃 회귀

보끔밥0302 2022. 3. 2. 01:31

k-최근접 이웃회귀

농어의 무게를 예측하라
회귀 regression -> 타깃 (임의의 숫자)
지도학습 : 분류, 회귀

 
In [ ]:
import numpy as np
In [ ]:
# 농어의 무게를 예측하라
# 회귀 regression -> 타깃 (임의의 숫자)
# 지도학습 : 분류, 회귀
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]
     )
In [ ]:
import matplotlib.pyplot as plt
In [ ]:
plt.scatter(perch_length, perch_weight)
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
 
 

사이킷런 모델 : 입력 데이터가 2차원 배열로 기대 행방향 샘플 열방향 특성

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

train_input = train_input.reshape(-1,1)
test_input = test_input.reshape(-1,1)
# 행(row)의 위치에 -1을 넣고 열의 값을 지정해주면 변환될 배열의 행의 수는 알아서 지정이 된다는 소리
 

회귀 모델 훈련

In [ ]:
from sklearn.neighbors import KNeighborsRegressor 
# 분류 Classifier ,회귀 Regressor
In [ ]:
knr = KNeighborsRegressor()
knr.fit(train_input, train_target) # k-최근접 이웃 회귀 모델을 훈련합니다

knr.score(test_input, test_target) # k-최근접 훈련한 모델의 검증 (예측 수준)
Out[ ]:
0.992809406101064
 

결정 계수 ($ R^2$)

결정계수 : X가 Y를 얼마나 설명하는지에 대한 정보 제공 (= 회귀식은 얼마나 정확한가?)
반응변수의 전체변동 중 예측변수가 차지하는 변동의 비율
결정계수 = 1 : 회귀직선으로 Y를 완전히 설명 가능.
결정계수 = 0. 추정된 회귀직선은 X와 Y의 관계 설명 불가.

값이 1에 가까울수록 좋은 모형이다. (분자가 0에 가까움)
 
20220217_163826.png
In [ ]:
from sklearn.metrics import mean_absolute_error # 평균 절대값 오차
In [ ]:
test_prediction = knr.predict(test_input) # 테스트 세트에 대한 예측을 만듭니다
mae = mean_absolute_error(test_target, test_prediction) # 테스트 세트에 대한 평균 절댓값 오차를 계산합니다
print(mae) # 19g정도 오차가 생긴다
                          
 
19.157142857142862
 

과대적합과 과소적합

In [ ]:
print(knr.score(train_input, train_target)) 
print(knr.score(test_input, test_target))
# 훈련 < 테스트 : underfitting
# 반대로 훈련 > 테스트 : overfitting
# 지금은 underfitting
 
0.9698823289099254
0.992809406101064
 

이웃 개수 줄이기

이웃의 개수 k를 늘리면 과소적합, 줄이면 과대적합
이웃의 개수를 줄이면 훈련 세트에 국지적인 패턴에 민감해지고, 늘리면 훈련 세트의 데이터 전반에 있는 일반적인 패턴을 따를 것이다.
In [ ]:
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
In [ ]:
# 복잡한 모델과 단순한 모델 한 번에 만들어보기
# k-최근접 이웃 회귀 객체를 만듭니다
knr = KNeighborsRegressor()
# 5에서 45까지 x 좌표를 만듭니다 (농어의 길이를 5에서 45로 바꾸며 예측해보기)
x = np.arange(5, 45).reshape(-1, 1)

# n = 1, 5, 10일 때 예측 결과를 그래프로 그립니다.
for n in [1, 5, 10]:
    # 모델 훈련
    knr.n_neighbors = n
    knr.fit(train_input, train_target)
    # 지정한 범위 x에 대한 예측 구하기 
    prediction = knr.predict(x)
    # 훈련 세트와 예측 결과 그래프 그리기
    plt.scatter(train_input, train_target)
    plt.plot(x, prediction)
    plt.title('n_neighbors = {}'.format(n))    
    plt.xlabel('length')
    plt.ylabel('weight')
    plt.show()
 
 
 

출처 : 박해선, 『혼자공부하는머신러닝+딥러닝』, 한빛미디어(2021), p114-126

Comments