인공지능/머신러닝

[머신러닝] K - 최근접 이웃 회귀 (K-NN Regression) 01

노트북 산 김에 공부 2023. 4. 8. 20:45

회귀는 값을 예측하는 것이므로, '새로운 데이터 X가 주어졌을 때, X에 가장 가까운 K개의 데이터 값을 평균내서 값(Y)을 예측하는 알고리즘' 입니다. 

실습  -  물고기 무게 예측

물고기의 길이를 입력 데이터(X)로 사용하고, 물고기의 무게를 출력 데이터(Y)로 사용하겠습니다.

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])

 

당연히 길이가 길수록 무게도 많이 나가는 것을 확인할 수 있습니다.

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(fish_length, fish_weight, random_state=42)

# reshape 함수로 데이터 차원 변경
X_train, X_test = X_train.reshape(-1 , 1), X_test.reshape(-1 , 1)

위에서 X_train과 X_test 의 배열을 2차원으로 만든 이유는 사이킷런에서 사용하는 훈련세트는 2차원 배열이여야 합니다.


훈련 및 과소적합

from sklearn.neighbors import KNeighborsRegressor
knr = KNeighborsRegressor() # 객체 생성
knr.fit(X_train, y_train) # 훈련

print('테스트 데이터셋',knr.score(X_test, y_test)) 
print('훈련 데이터셋',knr.score(X_train, y_train))

과대적합은 훈련세트의 성능이 테스트 세트의 성능보다 훨씬 높게 나오는 현상입니다. 이와 반대로

과소적합은 훈련 세트의 성능보다 테스트 세트의 성능이 더 높게 나오는 현상입니다.

과대적합은 k-최근접 이웃의 k값을 늘리면 되지만 과소적합은 k 값을 줄여서 모델을 더 복잡하게 만들어야 합니다.

 

회귀에서는 정확한 숫자를 맞추는 것은 거의 불가능합니다. 예측하는 값이나 타깃 모두 임의의 수치이기 때문입니다.

따라서 회귀의 경우 주로 결정계수를 사용하여 평가합니다. 


mean_absolute_error( )

mean_absolute_error 함수는 타깃(Y)과 예측(predict)의 절댓값 오차를 평균하여 반환해줍니다.

from sklearn.metrics import mean_absolute_error
predict = knr.predict(X_test)
mae = mean_absolute_error(y_test, predict)
mae

결과에서 예측이 평균적으로 19g 정도 타깃(Y)과 다르다는 것을 알 수 있습니다.

최종 결과

knr.n_neighbors = 3
knr.fit(X_train, y_train)
plt.scatter(X_train, y_train) # 전체 데이터

distnces, indexes= knr.kneighbors([[50]]) # 근접한 데이터
plt.scatter(X_train[indexes], y_train[indexes]) #--

plt.scatter(50,  knr.predict([[50]]),  marker='^', c='r') # 예측 데이터
plt.show