[머신러닝] 다항 회귀

다항 회귀


선형 회귀란?

다항 회귀를 알아보기 전에 선형 회귀부터 알아보자.
선형 회귀는 특성과 타깃 사이의 관계를 가장 잘 나타내는 선형 방정식을 찾는다.
특성이 하나인 경우 어떤 직선을 학습하는 알고리즘이다. 



다항 회귀란?

다항식을 사용하여 특성과 타깃 사이의 관계를 나타낸다. 이 함수는 비선형 일 수도 있지지만 선형 회귀로 표현 가능하다. 다항식을 사용한 선형 회귀다항 회귀라고 부른다.



선형 회귀로 데이터 예측

선형 회귀로 훈련 세트 범위 밖 데이터 예측을 한 그래프다.
하지만 산점도를 보면 직선보다는 곡선의 가깝다.
이때 다항 회귀를 사용하면 최적의 곡선을 찾을 수 있다.






다항 회귀 사용을 위한 데이터 준비

다항 회귀 알고리즘을 사용하기 위해 데이터를 준비하자.
import numpy as np

height = np.array([10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,
20.5,21.0,22.0,23.0,24.0,25.0,26.0,27.5,28.0,29.0,
30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,37.5,38.0,
39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,
49.0,50.0,51.3,52.0,53.0,54.0,55.0,56.0,57.0,58.0
])

weight = np.array([100.0,101.9,102.0,103.0,104.0,105.0,106.0,107.0,108.0,109.0,
110.0,110.0,111.0,120.0,121.0,122.0,124.0,126.0,127.0,128.0,
130.0,135.0,137.0,138.0,140.0,150.0,151.0,155.0,160.0,162.0,
170.0,180.0,190.0,200.0,300.0,400.0,500.0,600.0,700.0,800.0,
850.0,850.0,860.5,870.7,880.0,890.0,900.0,920.0,930.0,950.0
])


#훈련세트,테스트 세트 나누기. random_stata 42로 하면 프로그램을 껐다켜도 훈련세트와 테스트 세트의 샘플이 유지된다.
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(
height, weight, random_state=42)

# 2차원으로 바꾸기
train_input = train_input.reshape(-1,1)
test_input = test_input.reshape(-1,1)



곡선을 그리는 2차 방정식

곡선을 그리기 위해서는 다음과 같은 2차 방정식이 필요하다.
weight = a x height² + b x height + c

현재 height 값은 있으니 height² 값을 훈련 세트에 추가해 줘야 한다.
a,b,c는 다항 회귀 모델을 훈련하면 찾을 수 있다.


height² 훈련 세트에 추가

height의 샘플은 train_input에 있다.
heigth²의 샘플도 만들어 추가 해 줘야 한다.

넘파이의 column_stack() 메서드를 사용하면 height와 height² 를 하나의 배열h 붙일 수 있다.

** 2 은 제곱 하라는 기호다.

shape함수를 통해 크기를 확인 해보면 열이 2개로 늘어 난 것을 확인 할 수 있다.
#height 제곱 값 훈련 세트에 추가하기
train_poly = np.column_stack((train_input ** 2, train_input))
test_poly = np.column_stack((test_input ** 2, test_input))

#데이터 셋 크기 확인하기
print(train_poly.shape, test_poly.shape)
결과 : (37, 2) (13, 2)




모델 훈련 시키기

weight = a x height² + b x height + c 이 방정식 에서 height와 height² 은 준비 됐으니 a,b,c의 값은 모델을 훈련하면 알아서 찾아진다.
#모델 훈련 시키기
from sklearn.linear_model import LinearRegression

lr = LinearRegression()

#선형 회귀 모델 훈련
lr.fit(train_poly, train_target)


훈련 세트 범위 벗어난 데이터 예측

훈련 세트 범위에서 벗어난 데이터를 예측하고 출력해보자.
#예측하고 출력하기
print(lr.predict([[70**2, 70]]))
결과 : [1909.76793008]




계수, 절편 출력

coef_와 intercept는 각각 계수와 절편을 출력 해준다.
#계수 절편 출력
print(lr.coef_, lr.intercept_)
결과 : [  0.80132558 -35.14185554] 443.2024654421184




완성 된 2차 방정식

계수와 절편을 2차 방정식에 대입 하면 아래와 같다.
weight = 0.8 x height² - 35.14 x height + 443.2

이런 2차 방정식다항식이라고 부르며 다항식을 사용한 선형 회귀다항 회귀라고 부른다.



산점도와 곡선 그래프

계수, 절편(a,b,c)를 대입 하여 그래프를 그려보자.
이때 짧은 직선들을 이어 붙여서 곡선 처럼 표현 가능하다.
point 를 사용하여 1씩 짧게 그려보자.
import matplotlib.pyplot as plt #그래프 그리는 패키지 import

#짧은 직선을 그리기 위해 10 부터 70 정수 배열 만든다.
point = np.arange(10,70)

#훈련 세트 산점도 그리기
plt.scatter(train_input, train_target, color='red')

#곡선 그리기
plt.plot(point, 0.8*point**2 - 35.14*point + 443.2)

#예측 데이터 그리기
plt.scatter([70], [1909.76793008], color='green', marker='*')

plt.xlabel('height')
plt.ylabel('weight')
plt.show()


곡선이 아주 잘 그려졌다.





전체 소스코드

import numpy as np

height = np.array([10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,
20.5,21.0,22.0,23.0,24.0,25.0,26.0,27.5,28.0,29.0,
30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,37.5,38.0,
39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,
49.0,50.0,51.3,52.0,53.0,54.0,55.0,56.0,57.0,58.0
])

weight = np.array([100.0,101.9,102.0,103.0,104.0,105.0,106.0,107.0,108.0,109.0,
110.0,110.0,111.0,120.0,121.0,122.0,124.0,126.0,127.0,128.0,
130.0,135.0,137.0,138.0,140.0,150.0,151.0,155.0,160.0,162.0,
170.0,180.0,190.0,200.0,300.0,400.0,500.0,600.0,700.0,800.0,
850.0,850.0,860.5,870.7,880.0,890.0,900.0,920.0,930.0,950.0
])


#훈련세트,테스트 세트 나누기. random_stata 42로 하면 프로그램을 껐다켜도 훈련세트와 테스트 세트의 샘플이 유지된다.
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(
height, weight, random_state=42)

# 2차원으로 바꾸기
train_input = train_input.reshape(-1,1)
test_input = test_input.reshape(-1,1)

#height 제곱 값 훈련 세트에 추가하기
train_poly = np.column_stack((train_input ** 2, train_input))
test_poly = np.column_stack((test_input ** 2, test_input))

#데이터 셋 크기 확인하기
print(train_poly.shape, test_poly.shape)

#모델 훈련 시키기
from sklearn.linear_model import LinearRegression

lr = LinearRegression()

#선형 회귀 모델 훈련
lr.fit(train_poly, train_target)

#계수 절편 출력
print(lr.coef_, lr.intercept_)


import matplotlib.pyplot as plt #그래프 그리는 패키지 import

#짧은 직선을 그리기 위해 10 부터 70 정수 배열 만든다.
point = np.arange(10,70)

#훈련 세트 산점도 그리기
plt.scatter(train_input, train_target, color='red')

#곡선 그리기
plt.plot(point, 0.8*point**2 - 35.14*point + 443.2)

#예측 데이터 그리기
plt.scatter([70], [1909.76793008], color='green', marker='*')

plt.xlabel('height')
plt.ylabel('weight')
plt.show()


참조


혼자 공부하는 머신러닝 + 딥러닝(깃 허브) : https://github.com/rickiepark/hg-mldl


댓글

이 블로그의 인기 게시물

[Python] 파이썬 if문 사용법과 예제

[네트워크] 오류 제어 방식 이란?(FEC, BEC, ARQ)

[Virtual Box] 가상머신 에러 E_FAIL (0x80004005), (VERR_SUPLIB_PATH_NOT_CLEAN) 해결 방법