지난 시간에는 스케일이 다른 두 특성을 기준값을 전처리하는 과정을 가졌다. 이번 시간에는 회귀 모델을 만들어보자.
지도 알고리즘은 분류와 회귀로 나뉜다.
분류는 샘플을 몇 개의 클래스 중 하나로 분류하는 문제이고, 회귀는 임의의 어떤 숫자를 예측하는 문제이다.
예시) 내년도 경제 성장률, 배달 도착 시간 ...
데이터 준비
이번에는 농어의 길이(perch_length)를 특성으로 농어의 무게(perch_weight)를 타깃으로 하여 모델을 만들어보자.
넘파이 배열로 데이터를 준비하고 위 데이터들이 어떤 형태를 띠는지 산점도를 통해서 확인해보자.
## x축은 특성 데이터, y축은 타겟 데이터
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)
perch_length는 1차원 배열이고 사이킷런에서 사용할 훈련 세트는 2차원 배열이어야 하므로 reshape() 메소드를 사용하여 train_input과 test_input을 2차원 배열로 바꾸자.
## train_input의 크기는 (42, )
## train_input(42, 1)을 사용해도 된다.
## 열의 크기를 지정하고, 크기에 -1을 지정하면 나머지 원소 개수로 모두 채우라는 의미
train_input = train_input.reshape(-1, 1)
test_input = test_input.reshape(-1, 1)
print(train_input.shape, test_input.shape)
## 출력값
(42, 1) (14, 1)
원래 train_input의 크기는 (42, )이다. 2차원 배열로 바꾸기 위해 train_input.reshape(42, 1) 또는 train_input.reshape(-1, 1)을 사용한다. reshape(-1, 1)을 사용하면 첫 번째 크기를 나머지 원소로 채우고, 두 번째 크기를 1로 할 때 사용한다. 이를 사용하면 배열의 전체 원소 개수를 매번 외우지 않아도 되므로 편하다.
결정계수($R^2$)
결정계수는 대표적인 회귀 문제의 성능 측정 도구이다.
사이킷런에서 k-최근접 이웃 회귀 알고리즘을 구현한 클래스는 KNeighborsRegressor이다.
KneighborClassifier와 마찬가지로 객체를 생성한 후 fir() 메소드로 회귀 모델을 훈련한다.
## 사이킷런에서 k-최근접 이웃 회귀 알고리즘을 구현한 클래스는 KNeighborsRegressor이다.
## 객체를 생성하고 fit() 메소드로 훈련
from sklearn.neighbors import KNeighborsRegressor
knr = KNeighborsRegressor()
## k-최근접 이웃 회귀 모델을 훈련한다.
knr.fit(train_input, train_target)
## 테스트 세트의 점수
print(knr.score(test_input, test_target))
## 출력값
0.992809406101064
위 점수는 분류의 경우 정답을 맞힌 개수의 비율, 즉 정확도이다. 회귀의 경우에는 이 점수를 결정계수($R^2$)라고 한다.
$$ R^2 = 1 - {(타깃 - 예측)^2의 합 \over (타깃 - 평균)^2의 합} $$
예측이 타깃의 평균 정도를 예측하면 0에 가까워지고, 예측이 타깃에 아주 가까워지면 1에 가까워지기 때문에 결정계수는 1에 가까울수록 좋고, 0에 가까울수록 성능이 나쁜 모델이다.
이번에는 결정계수 말고 타깃과 예측한 값 사이의 차이를 구해보자.
사이킷런은 sklearn.metrics 패키지에 여러 가지 측정 도구를 제공한다.
타깃과 예측의 절댓값 오차를 평균하여 반환하는 mean_absolute_error를 사용해보자.
## 사이킷런에서는 sklearn.metrics 아래의 mean_absolute_error는 타깃과 예측의 절댓값 오차를 평균하여 반환한다.
from sklearn.metrics import mean_absolute_error
## 테스트 세트에 대한 예측을 만든다.
test_prediction = knr.predict(test_input)
## 테스트 세트에 대한 평균 절댓값 오차를 계산한다.
mae = mean_absolute_error(test_target, test_prediction)
print(mae)
## 출력값
19.157142857142862
예측이 평균적으로 약 19g 정도 타깃값과 다르다는 것을 알 수 있다.
지금까지는 테스트 세트에 대한 점수를 출력해보았고 이제는 훈련 세트에 대한 점수를 출력해보자.
## 테스트 세트가 아닌 훈련 세트를 사용하여 평가를 진행해보면 어떤 차이가 있는지 확인
print(knr.score(train_input, train_target))
## 출력값
0.9698823289099254
테스트 세트에 대한 점수는 0.992809406101064
훈련 세트에 대한 점수는 0.9698823289099254가 나왔다.
훈련 세트를 가지고 모델을 훈련하기 때문에 일반적으로 훈련 세트의 점수가 더 좋은 점수가 나온다.
위처럼 훈련 세트보다 테스트 점수가 높거나 두 점수 모두 낮은 경우 모델이 훈련 세트에 과소적합되었다고 한다. 모델이 너무 단순하여 훈련 세트에 적절히 훈련되지 않은 경우이다.
반대로 훈련 세트에서 점수가 좋았는데 테스트 세트에서 점수가 나쁘다면 이 모델은 훈련 세트에 과대적합되었다고 한다. 이 모델은 훈련 세트에만 잘 맞는 모델이기 때문에 실전에서 잘 동작하지 않을 것이다.
과소적합을 해결하기 위해서는 모델을 조금 더 복잡하게 만들어 훈련 세트에 더 잘 맞게 만들면 된다.
k-최근접 이웃 알고리즘으로 모델을 더 복잡하게 만드는 방법은 이웃의 개수 k를 줄이는 것이다. 이웃의 개수를 줄이면 국지적인 패턴에 민감해지고, 이웃의 개수를 늘리면 데이터 전반의 일반적인 패턴을 따를 것이다.
이번에는 n_neighbors의 값을 3으로 설정하여 객체를 다시 만들고 점수까지 출력해보자.
## 이웃의 개수를 3개로 만듦
knr.n_neighbors = 3
## 다시 훈련
knr.fit(train_input, train_target)
## 훈련 세트 점수
print(knr.score(train_input, train_target))
## 출력값
0.9804899950518966
## 테스트 세트 점수
print(knr.score(test_input, test_target))
## 출력값
0.9746459963987609
훈련 세트의 $R^2$점수가 높아지고, 테스트 세트의 $R^2$점수는 훈련 세트보다 낮아졌으므로 과소적합은 해결했다. 또한 두 점수의 차이가 크지 않으므로 과대적합도 아니라고 볼 수 있다.
성공적으로 k-최근접 이웃 회귀 모델을 훈련했다.
정리
1. 지도 알고리즘은 분류와 회귀로 나뉜다.
2. 사이킷런에서 사용할 훈련 세트는 2차원 배열이어야 한다.
3. 결정계수는 대표적인 회귀 문제의 성능 측정 도구이다. 1에 가까울수록 좋고, 0에 가까울수록 성능이 나쁜 모델이다.
4. k-최근접 이웃 회귀는 가장 가까운 이웃 샘플을 찾고 이 샘플들의 타깃값을 평균하여 예측으로 삼는다.
5. KNeighborsRegressor는 KneighborClassifier와 마찬가지로 객체를 생성한 후 fir() 메소드로 회귀 모델을 훈련한다.
6. 과소적합: 훈련 세트보다 테스트 점수가 높거나 두 점수 모두 낮은 경우. 모델이 너무 단순하여 훈련 세트에 적절히 훈련되지 않았다.
7. 과대적합: 훈련 세트에서 점수가 좋았는데 테스트 세트에서 점수가 나쁜 경우. 실전에서 잘 작동하지 않을 것이다.
'혼자 공부하는 머신러닝 + 딥러닝' 카테고리의 다른 글
혼자 공부하는 머신러닝 + 딥러닝 Day 6 (0) | 2022.09.08 |
---|---|
혼자 공부하는 머신러닝 + 딥러닝 Day 5 (0) | 2022.09.06 |
혼자 공부하는 머신러닝 + 딥러닝 Day 3 (0) | 2022.08.24 |
혼자 공부하는 머신러닝 + 딥러닝 Day 2 (0) | 2022.08.16 |
혼자 공부하는 머신러닝 + 딥러닝 Day 1 (0) | 2022.08.15 |