데이터 사이언스/하계 AI 중급과정

Ch 4. Polynomial Regression (다항회귀)

수학과인데 공대생 2023. 7. 12. 14:54
728x90

지난 포스팅에서 선형회귀에 대한 예제를 알아보았습니다.
https://math-love.tistory.com/21

Ch 3. Linear Regression(선형회귀)

선형회귀란? 선형회귀의 정의는 아래 포스팅을 참조바랍니다. https://math-love.tistory.com/8 1. Linear Regression (선형 회귀) 머신러닝의 목적은 데이터의 알려진 속성들을 학습하여 예측 모델을 만드는데

math-love.tistory.com

 
지난 포스팅에 이은 data를 그대로 활용하겠습니다.
data를 학습하고 시각화 작업까지 마쳤습니다.
이제 Train_set을 활용해 만들어진 model의 평가를 해봅시다.

lr.score(train_input, train_target)
-> 0.9363463656327585

lr.score(test_input, test_target)
-> 0.8359630155975616

 
Train_set에 대한 점수는 높게 나온 것으로 보입니다.
그런데 Test_set에 대한 점수는 Train_set에 비해 상대적으로 낮은 점수를 보입니다.
 
아무래도 선형 회귀 방식 만으로는 data 전체를 포괄하는데 한계가 있는 것 같습니다.
이럴 때 생각해 볼 수 있는 것이 다항회귀입니다.
 
 

다항 회귀 (Polynomial Regression)

다항 회귀는 각 특성(feature)의 제곱을 새로운 특성으로 추가하여 선형 모델을 학습시키는 방법을 말합니다. 다항 회귀의 식은 다음과 같습니다.

m차 함수의 형태로 모델을 학습시킵니다.
 
 

다항 회귀 모델을 이용한 예측

import numpy as np

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

 
마찬가지로 Train_set과 Test_set을 나누겠습니다.
reshape까지 함께 진행해 주겠습니다.

from sklearn.model_selection import train_test_split

train_input, test_input, train_target, test_target = train_test_split(fish_length, fish_weight, test_size = 0.2, random_state = 42)
train_input = train_input.reshape(-1, 1)
train_target = train_target.reshape(-1, 1)
test_input = test_input.reshape(-1, 1)
test_target = test_target.reshape(-1, 1)

 
input data들을 이용해 degree = 1 인 상태에서 점수가 낮게 나왔으므로
input data의 degree = 2 인 poly data를 구성해 학습시켜보겠습니다.
 

poly를 구성하는 방식에는 2가지가 있습니다.

1. numpy의 column_stack을 이용하는 방법
numpy 내부의 column_stack 함수를 이용해 poly를 구성할 수 있습니다.
column_stack은 말그대로 colum에 stack을 쌓는다는 의미입니다.
np.array 형태로 복사할 수 있습니다.

train_poly = np.column_stack((train_input ** 2, train_input))
tesr_poly = np.column_stack((test_input ** 2, test_input))

 
train_poly의 5번째 행까지만 출력해 확인해 보겠습니다.

train_poly[:5]

좌측에 제곱값이 들어가 degree = 2 인 poly data가 제대로 만들어졌습니다.
 
2. scikit - learn의 PolynomialFeatures를 이용하는 방법

from sklearn.preprocessing import PolynomialFeatures

poly_feature = PolynomialFeatures(degree = 2, include_bias = False) # include_bias = True로 하면 0차까지 만들어지기 때문에 불필요함
train_poly = poly_feature.fit_transform(train_input)
test_poly = poly_feature.fit_transform(test_input)

 
degree = 2 인 poly data가 만들어졌는지 확인해봅시다.

train_poly[:5]

degree = 2 로 만들어진 것을 확인할 수 있습니다.
 
이제 LinearRegression을 이용해 학습을 시켜보겠습니다.

from sklearn.linear_model import LinearRegression

lr = LinearRegression()
lr.fit(train_poly, train_target)

 
모델이 학습되었습니다.
지난 포스팅과 마찬가지로 길이가 50인 물고기의 무게를 predict함수를 써서 예측해보겠습니다.
이번에는 degree = 2이기 때문에 predict안에 50만 넣는 것이 아닌 50의 제곱까지 같이 넣어주어야 정확한 predict를 할 수 있습니다.
 

lr.predict([[50, 50**2]])
-> array([[1579.0440311]])

길이가 '1579.0440311'인 것으로 예측되었습니다.
 
degree = 1 일 때는 '1238.3175398'로 예측되었는데
조금 더 높은 수치로 예측되는 것을 확인할 수 있습니다.
 
이제 시각화 작업을 해보겠습니다.

x = np.linspace(15, 60, 100)

plt.scatter(train_input, train_target, color = 'blue')

plt.plot(x, lr.coef_[0][1]*x**2 + lr.coef_[0][0]*x + lr.intercept_[0], color = 'red')

plt.show()

 
직선 형태보다 좀 더 정교하게 data들을 표현하고 있는 것으로 보입니다.
 
이제 score 함수를 활용해 Train_set과 Test_set의 score를 확인해보겠습니다.

lr.score(train_poly, train_target)
-> 0.970185494758599

lr.score(test_ploym test_target)
-> 0.9801885585527479

 
이번엔 Test_set이 Train_set에서의 점수보다 높게 나왔습니다.
잘 만들어진 model이라고 판단할 수 있습니다.
 
 

728x90