Ch 4. Polynomial Regression (다항회귀)
지난 포스팅에서 선형회귀에 대한 예제를 알아보았습니다.
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이라고 판단할 수 있습니다.