오늘의 학습 목표는 K-최근접 이웃 회귀와 선형 회귀 알고리즘의 차이를 이해하고 사이킷런을 사용해 여러 가지 선형 회귀 모델을 만드는 것입니다.💪💪💪
k-최근접 이웃 회귀 모델로 길이가 50cm인 농어의 무게를 예측했더니 실제 저울의 농어의 무게와 차이가 너무 많이 난다고 합니다..🥹
해당 문제를 확인하기 위해서 코드를 구현해보겠습니다.
우선 지난 챕터에서 공부했던대로 데이터와 모델을 준비하고 훈련까지 진행해보겠습니다.
우선 특성이 되는 농어의 길이 데이터와 타겟이 되는 농어의 무게 데이터를 준비하고
훈련 세트와 테스트 세트를 분리합니다.
사이킷런의 KNeighborRegressor 를 호출해서 k-최근접 이웃 회귀 모델을 훈련시켰습니다.
길이가 50cm 인 농어의 무게를 1033g으로 예측했는데요, 실제로 이 농어의 무게는 훨씬 더 많이 나간다고 합니다. 어디서 문제가 생긴 것인지 알아보겠습니다.
kneighbors() 매서드를 사용해서 가장 가까운 이웃까지의 거리와 이웃 샘플의 인덱스를 얻은 후에 최근접 이웃을 산점도로 표시했습니다.
길이가 50cm이고 무게가 1033g인 농어는 초록색 삼각형으로 표시되어있고 그 주변의 샘플은 주황색 마름모 형태로 시각화했습니다.
산점도를 보면 길이가 커질수록 농어의 무게가 증가하는 경향이 있습니다. 하지만 50cm 농어에서 가장 가까운 것은 45cm 근방이기 때문에 모델은 이 샘플들의 무게의 평균값으로 예측하게됩니다. 이웃 샘플의 타깃의 평균을 구해보겠습니다.
모델이 예측한 값과 정확히 일치합니다. 이번에는 훈련 세트의 범위를 벗어난 새로운 샘플에 대해서 예측해보겠습니다.
길이가 100cm인 농어도 여전히 1033g으로 예측합니다. 마찬가지로 시각화해서 자세히 살펴보겠습니다.
농어 길이가 아무리 길어져도 학습된 데이터는 일정 범위로 고정되어있고 이웃 샘플이 고정되기 때문에 동일한 예측값을 가질 수 밖에 없습니다.
K-최근접 이웃을 사용해 이 문제를 해결하려면 가장 큰 농어가 포함되도록 훈련 세트를 다시 만들어야 한다는 한계가 있습니다.
머신러닝 모델은 시간과 환경이 변화하면서 데이터도 자주 바뀌기 때문에 주기적으로 새로운 데이터를 사용해서 훈련을 해야합니다.
선형 회귀
- 특성과 타깃 사이의 관계를 가장 잘 나타내는 선형 방정식을 찾는 알고리즘으로 특성이 하나인 경우 직선 방정식이 됨
- 선형 회귀가 찾은 특성과 타깃 사이의 관계는 선형 방정식의 계수 또는 가중치에 저장. 머신러닝에서 종종 가중치는 기울기와 절편을 모두 의미하는 경우가 많음
위 그래프 중에서 농어의 특성을 가장 잘 나타내는 것은 맨 오른쪽 그래프입니다. 이러한 직선을 찾아주는 알고리즘이 선형 회귀입니다.
사이킷런의 LinearRegression 클래스로 선형 회귀 알고리즘을 사용해보겠습니다.
k-최근접 이웃 회귀 모델과 달리 선형 회귀 모델은 50cm 농어의 무게를 잘 예측한 것을 알 수 있습니다. 선형 회귀가 학습한 직선을 그려서 확인해보겠습니다.
우선 직선을 그리기 위해서는 기울기와 절편이 있어야 합니다.
y= ax + b 처럼 쓸 수 있습니다. 여기에서 x를 농어의 길이, y를 농어의 무게로 바꾸면 아래와 같습니다.
기울기인 a와 절편인 b의 값은 LiniearRegression 객체의 coef 와 intercept 속성에 저장되어있습니다.
LinearRegressor( ) 의 모델 파라미터
- coef_ : 기울기, 계수 혹은 가중치
- intercept_ : 절편
기울기와 절편을 활용하여 선형 회귀 모델이 학습한 직선을 그려보겠습니다.
농어 길이 15에서 50까지를 직선으로 그리기 위해 (15, 15x39-709) 와 (50, 50x39-709) 두 점을 이어 그리고 훈련세트의 산점도도 함께 확인했습니다.
이제 훈련 세트 범위를 벗어난 농어의 무게도 예측할 수 있게되었습니다. 그럼 이전 절과 같이 훈련 세트와 테스트 세트에 대한 점수를 확인해볼게요.
훈련세트와 테스트 세트의 점수가 차이가 나는데요, 사실 훈련 세트의 점수도 높지 않습니다. 과대적합되었다기보다는 전체적으로 과소적합되었다고 볼 수 있습니다.
그리고 또 다른 문제가 있습니다. 그래프 왼쪽 아래를 보면 직선에서 벗어난 구간이 있는 걸 확인할 수 있어요..!
농어의 길이와 무게에 대한 산점도를 보면 전체적인 경향이 일직선 보다는 우상향하는 곡선에 가깝다는 걸 알 수 있습니다. 따라서 최적의 직선보다는 최적의 곡선을 찾는다면 더 알맞게 모델을 만들 수 있을 것입니다.
이를 위해 2차 방정식 그래프를 그려볼텐데요, 2차 방정식 그래프를 그리려면 길이를 제곱한 항이 훈련 세트에 추가되어야 합니다. 넘파이를 사용해서 간단하게 만들어 볼게요.
np.column_stack( ) : 두 배열을 나란히 붙이는 매서드
train_poly 데이터를 사용해서 선형 회귀 모델을 다시 훈련하겠습니다. 이 때 훈련 세트에 제곱항을 추가했지만 타깃값은 그대로 사용해야 합니다. 목표하는 값은 어떤 그래프를 훈련하든 바꿀 필요가 없습니다.
앞서 훈련한 모델보다 더 높은 값을 예측했습니다. 모델의 훈련계수와 절편을 확인하고, 모델이 학습한 그래프를 시각화해볼게요.
단순 선형 회귀 모델보다 훈련 세트의 경향을 잘 따르고 있고, 무게가 음수로 나올 일이 없다는 점을 알 수 있습니다!!!
훈련세트와 테스트 세트의 결정계수 점수가 크게 높아졌습니다. 하지만 여전히 테스트 세트의 점수가 조금 더 높은 것으로 보아 과소적합이 남아있는 것 같습니다.
자료출처: 한빛미디어