[머신러닝] 다항 회귀
다항 회귀
선형 회귀란?
다항 회귀를 알아보기 전에 선형 회귀부터 알아보자.
선형 회귀는 특성과 타깃 사이의 관계를 가장 잘 나타내는 선형 방정식을 찾는다.
특성이 하나인 경우 어떤 직선을 학습하는 알고리즘이다.
다항 회귀란?
다항식을 사용하여 특성과 타깃 사이의 관계를 나타낸다. 이 함수는 비선형 일 수도 있지지만 선형 회귀로 표현 가능하다. 다항식을 사용한 선형 회귀를 다항 회귀라고 부른다.
선형 회귀로 데이터 예측
선형 회귀로 훈련 세트 범위 밖 데이터 예측을 한 그래프다.
하지만 산점도를 보면 직선보다는 곡선의 가깝다.
이때 다항 회귀를 사용하면 최적의 곡선을 찾을 수 있다.
다항 회귀 사용을 위한 데이터 준비
다항 회귀 알고리즘을 사용하기 위해 데이터를 준비하자.
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://hongong.hanbit.co.kr/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-%EB%94%A5%EB%9F%AC%EB%8B%9D/
혼자 공부하는 머신러닝 + 딥러닝(깃 허브) : https://github.com/rickiepark/hg-mldl
댓글
댓글 쓰기