ML

ML/ k-최근접 이웃 회귀로 무게 예측하기

석새우 2026. 1. 14. 13:35

주어진 길이에 따라서 무게를 예측해보는 알고리즘이다.

 

import numpy as np
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]
     )

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)

훈련데이터와 테스트 데이터를 정의한다.

 

train_input=train_input.reshape(-1,1)
test_input=test_input.reshape(-1,1)

사이킷 런에 사용할 훈련 세트는 반드시 2차원 배열이어야 한다!!!!! 따라서 배열의 원소는 동일하지만 2차원배열로 손쉽게 바꿔줄 reshape() 메서드를 사용했다.

 

from sklearn.neighbors import KNeighborsRegressor

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

사이킷런에서 훈련을 시킨 후 점수를 출력해보면,

0.992809406101064

의 수가 나온다. 이 수는 결정계수, R^2이다.

 

1 - (각 샘플의 타깃과 예측한 값의 차이를 제곱해서 모두 더한값) / (타깃과 타깃 평균의 파이를 제곱해서 모두 더한 값)

예측이 타깃과 아주 가까워 지면 분자가 0에 가까워져서 결정계수가 1에 가까워진다.

결정계수에 알게 되었으니 이제 문제에 직면하게 된다. 우리가 출력한 것은 "테스트 데이터"의 score이다. "훈련 데이터"로 훈련시킨 모델의 "훈련 데이터"의 score은 당연히 "테스트 데이터"의 score 보다 높아야 정상이지 않을까?

 

knr.score(train_input,train_target)
0.9698823289099254

하지만 현재 그렇지 않은 것을 확인할 수 있다. 

이렇듯이 훈련 세트보다 테스트 세트의 점수가 높거나 만약 두 점수가 모두 너무 낮은 경우는 모델이 훈련 세트에 과소적합 되었다고 한다.

 

반대로 훈련세트에서 점수가 굉장히 좋았는데 테스트 세트에서는 점수가 굉장히 나쁘다면 모델이 훈련세트에 과대적합 되었다고 한다.

 

k-최근접 이웃에서 과대적합일 경우 모델을 덜 복잡하게 만들면 된다. (n_neighbors값 증가)

반대로 과소적합일 경우 모델을 더 복잡하게 만들면 된다.(n_neighbors 값 감소)

k-최근접 이웃 알고리즘의 기본 k값은 5이다. 이를 3으로 낮춰서 출력해보면 간단하게 해결된다.

knr.n_neighbors=3
knr.fit(train_input,train_target)
knr.score(train_input,train_target)
0.9804899950518966
0.9746459963987609

다음은 선형회귀에 대해서 알아보겠슨