본문 바로가기
데이터관련공부/Machine Learning

[분석알고리즘] 회귀 | 3. 다항 회귀 (Polynomial Regression)

by 자유롭고 싶은 키털트 2023. 12. 21.

이번 포스팅에서는 다항 회귀에 대해 정리해 보겠습니다.

 

1차항을 가진 일차함수식 (단순 선형 회귀) 으로 설명할 수 없는 복잡한 데이터를 다항식으로 선형 회귀식을 만들면 모델이 좀 더 복잡한 구조를 갖게 되어 예측력을 높일 수 있습니다. 


다항 회귀란? Polynomial Regression (다항 회귀 분석)

 

- 두 변수 간의 관계를 선형 관계를 곡선으로 설명하는 알고리즘 이며, 이 때 2차 이상의 다항 함수를 사용합니다. 

 

- 데이터가 단순한 직선 형태가 아닌 비선형 형태를 가지고 있을 때변수의 거듭 제곱새로운 변수로 추가 하면서 특성을 확장시켜 데이터를 훈련 시켜 볼 수 있습니다.

 

: 하기 스크린샷은 4차 다항함수식을 가진 다항 회귀의 예시 입니다. 

 

 

- 하기 그림은 단순 선형 회귀와 다항 회귀의 차이를 보여주는 이미지 입니다. 다항 회귀(Polynomial Regression) 은 주로 단순 선형 회귀 모델(Simple Linear Regression) 이 주어진 데이터셋을 설명하지 못할 때 (데이터가 직선 형태가 아니기 때문에) 사용됩니다.

출처: https://medium.com/analytics-vidhya/understanding-polynomial-regression-5ac25b970e18

 

 

- 또, 다항 회귀식을 만들 때 주어진 차수까지 모든 교차항을 추가할 수 있습니다.  예를 들어 변수 a 와 변수 b 가 있을 때 degree = 3 으로 다항 회귀식을 만들면 a², b², a³, b³  외에도 ab, a²b, ab² 또한 변수로 추가할 수 있습니다. 이런식으로 고차 다항 회귀를 적용시 훈련 데이터에 적합한 모델을 만들 수는 있으나 과적합의 위험이 있습니다.

 

다항 회귀 예시: 출처: https://www.analyticsvidhya.com/blog/2021/10/understanding-polynomial-regression-model/

 

 

다항 회귀식 만들기

 

- 다항 회귀 분석은 먼저 1) 다항 변수를 생성 후, 2) LinearRegression 함수에 적용하면 됩니다.

 

- Linear Regression 과 프로세스는 거의 동일하되 사이킷런의 Polynomial Feature (degree = d) 를 활용해 다항 변수를 생성하는 차이만 있습니다. 여기서 degree 값은 몇 차항인지를 의미합니다. degree = 2 로 지정하면 2차항의 다항 회귀식을 생성하게 됩니다. 

 

다항 변수 생성

 

- 다항 변수 생성하는 과정을 살펴 보겠습니다. 다항 변수를 생성하기 위해선, Polynomial Feature (degree = d) 함수를 활용합니다.

 

Polynomial Feature 파라미터

  • degree: 다항식의 차수를 결정합니다. default 값은 2 입니다.
  • interaction_only: True 또는 False 입력, default = False, True 일 경우 교차항만 생성,  False 일 경우 교차항과 함께 동일한 변수의 2제곱 이상의 항도 추가됩니다.

- Polynomial Feature 속성

  • fit_tranform:  데이터를 적합시킨 뒤 다항 함수로 변환, 이 때 입력값은 2차원 array 로 입력 되어야 한다. 
  • transform:     데이터를 다항 함수로 변환, 이 때 입력값은 2차원 array 로 입력 되어야 한다. 
from sklearn.preprocessing import PolynomialFeatures
poly_reg = PolynomialFeatures(degree=2)

 

 

Polynomial Feature 코드 예시

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, mean_squared_error
 
 
# 2차 다항식 변환
pf = PolhynomialFeatures(degree=2)
 
X_train_poly = pf.fit_transform(X_train)
 
# 2차 다항식 변환 데이터셋으로 선형 회귀 모델 학습
lr = LinearRegression()
 
lr.fit(X_train_poly, y_train)
 
# 테스트 데이터로 예측 및 평가
 
X_test_poly = pf.transfrom(X_test)
y_test_pred = lr.predict(X_test_poly)
 
mse = mean_squared_error(y_test, y_test-pred)
 
print('MSE: %.4f'% mse)
cs

 

다항 회귀식 실제 사용 예시1 (Sugars, rating)

 

- 예시 데이터로 케글의 cereal 데이터를 불러오겠습니다.

https://www.kaggle.com/datasets/crawford/80-cereals

 

80 Cereals

Nutrition data on 80 cereal products

www.kaggle.com

 

- 변수 중 데이터타입이 object 는 제외 (name, mfr, type 열 제외) 하고 숫자형 데이터만 불러오면, 총 77행 13열의 구조 입니다. 

 

- 각 변수는 시리얼별 영양 정보를 담고 있습니다. 타겟 변수는 rating 변수 입니다. 각 영양정보와 rating 의 관계를 보여주는 회귀식을 도출해 보겠습니다. 

 

- 우선 sugar 변수와 rating 의 관계를 산점도로 그려 보겠습니다. X와 y 의 변수의 각각 cereal 데이터의 sugars, rating 열을 넣고, plt.scatter 를 적용합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# sugars 와 rating 변수를 추출한 뒤, sugars 변수 기준으로 정렬
 
cereal2 = cereal.loc[:, ['sugars''rating']].sort_values(by='sugars', ascending=False)
 
cereal2.reset_index(drop=True, inplace=True)
 
# 산점도 그리기 
 
import matplotlib.pyplot as plt
 
= cereal2['sugars'].values
= cereal2['rating'].values
 
plt.scatter(x, y)
plt.show()
cs

Sugar 함유량이 많을수록 rating 이 낮음을 알 수 있다. 직선 관계일까?

 

 

- Regression 에 훈련을 시켜야 하므로 Train, Test 데이터를 분할합니다. 훈련, 검증 데이터의 비율을 7대 3으로 하겠습니다.

1
2
3
4
5
6
from sklearn.model_selection import train_test_split
 
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size= 0.3, random_state = 1)
 
print(X_train.shape, y_train.shape)
print(X_test.shape, y_test.shape)
cs

 

- PolynomialFeature 를 사용하여 Sugar 열에 대한 다항 변수를 생성합니다. 

  • 우선 2차항을 생성하는 PolynomialFeatures 를 불러와서 poly_reg 에 지정합니다.
  • X_train 데이터를 fit 후 2차항으로 변환 시킵니다. 이를 위해 fit_transform 속성을 이용합니다. X_train.reshape(-1, 1) 를 하는 이유는 X_train 값을 2차원 배열로 변환한 후 fit_transform 하기 위함입니다. 그 반환값을 X_poly 에 지정합니다.
  • 나머지는 LinearRegression 프로세스와 동일하되 훈련 데이터로서 다항 변수로 변환한 X_poly 값을 입력해 줍니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
from sklearn.preprocessing import PolynomialFeatures
 
poly_reg = PolynomialFeatures(degree=2)
 
# X_train 데이터를 fit_transform 으로 변환해서 X_poly
 
X_poly = poly_reg.fit_transform(X_train.reshape(-11))
 
from sklearn.linear_model import LinearRegression
 
reg = LinearRegression()
 
reg.fit(X_poly, y_train)
cs

 

 

- predict 속성을 위해 X_test 를 입력하여 y_test 에 대한 예측값을 구합니다. 이 때! 중요한 점은 역시 X_test 도 다항 변수로 변환합니다.  X_train 으로 fit 한 poly_reg 인스턴스를 그대로 적용해야 하므로 transform 만 적용합니다. 

1
2
3
4
5
6
7
8
9
10
# X_test 다항 형태로 변환
 
X_test_poly = poly_reg.transform(X_test.reshape(-11))
 
# X_test_poly 를 이용해 종속 변수 예측
 
y_test_pred = reg.predict(X_test_poly)
 
print(y_test)
print(y_test_pred)
cs

 

- 실제 y 값과 예측 y 값에 대한 비교입니다.

 

 

- 예측 y 값과 실제 y 값을 나란히 비교할 수 있는 포맷으로 변경해 보겠습니다. 

 

1
2
3
4
5
6
7
8
9
# y_test 와 y_test_pred 를 나란히 비교하기 위함..
 
import numpy as np
 
# 소수점 둘째 자리 까지 표현
np.set_printoptions(precision=2)
 
print(np.concatenate((y_test_pred.reshape(len(y_test), 1),
                     y_test.reshape(len(y_test), 1)),1))
cs

 

- 회귀 분석 관련 모델 성능 평가 지표를 불러와서 모델을 평가해 보겠습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np
 
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
 
mse = mean_squared_error(y_test, y_test_pred)
mae = mean_absolute_error(y_test, y_test_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_test_pred)
acc = reg.score(poly_reg.transform(X_test.reshape(-11)), y_test)
 
print(round(mse, 3))
print(round(mae, 3))
print(round(rmse, 3))
print(round(r2, 3))
print(round(acc, 3))
cs

 

 

 

다항 회귀식 실제 사용 예시2 (여러 변수, rating)

 

- 위에서는 Sugars 변수만 가지고 다항 회귀식을 만들었다면, 이번엔 여러 변수를 같이 포함하여 다항 회귀식을 만들어 보겠습니다. 동일하게 캐글에서 불러 cereal 데이터를 사용하겠습니다.

 

rating 이 타겟변수이다. 각 변수는 개별 씨리얼의 영양 정보를 담고 있다.

 

- 독립 변수로 calories 부터 cups 열까지 모두 선택합니다. 타겟 변수는 rating 입니다. 그리고, Train test split 을 이용하여  훈련 데이터 및 검증 데이터를 7대 3 으로 분할합니다. 

 

1
2
3
4
5
6
7
8
9
= cereal.iloc[:, :-1].values # calories 열 부터 cups 열까지 선택
= cereal.iloc[:, -1].values  # rating 열만 선택
 
from sklearn.model_selection import train_test_split
 
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1)
 
print(X_train.shape, X_test.shape)
print(y_train.shape, y_test.shape)
cs

 

 

- 독립 변수들을 비슷한 스케일로 스케일링 합니다. 훈련 데이터 및 테스트 데이터에 모두 적용합니다. 이 때에도, 훈련 데이터와 동일한 규모의 스케일링이 적용될 수 있도록 Test 데이터에는 transform 메소드만 적용합니다. 

1
2
3
4
5
6
7
8
9
from sklearn.preprocessing import StandardScaler
 
scaler = StandardScaler()
 
# 훈련 데이터 스케일링
X_train = scaler.fit_transform(X_train)
 
# 테스트 데이터 스케일링
X_test = scaler.transform(X_test)
cs

 

 

- 다항 변수 생성을 위해 Polynomial Feature 모듈을 불러오되 2차항으로 지정합니다. poly_reg 변수에 모듈을 지정하고 X_train 데이터를 입력시켜 다항 변환을 합니다. 

 

- LinearRegression 을 불러와 훈련을 시키되 위에서 다항변환된 훈련데이터인 X_poly 와 y_train 을 입력합니다.

 

- 검증 데이터 (X_test) 역시 다항 변수로 생성 한 후 (X_poly_test, transform 메소드만 사용)  predict 메소드를 사용하여 예측을 합니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# PolynomialFeatures 모듈 불러오고 X_train 데이터 다항변수 변환
 
from sklearn.preprocessing import PolynomialFeatures
 
poly_reg = PolynomialFeatures(degree=2)
 
X_poly = poly_reg.fit_transform(X_train)
 
 
# linear regression 모델을 불러온 후
from sklearn.linear_model import LinearRegression
 
lr = LinearRegression()
 
# 위에서 다항변수로 변환한 X_train 데이터, y_train 을 이용해 훈련 시킨다
lr.fit(X_poly, y_train)
 
# X_test 데이터 다항 변수 변환
X_poly_test = poly_reg.transform(X_test)
 
# 모델로 에측
y_test_pred = lr.predict(X_poly_test)
 
 
cs

 

- 모델 성능을 평가합니다. Sugars 변수 하나만 포함했을 때보다 실제 y 값과 예측 y 값의 편차가 줄어들었습니다.

1
2
3
4
5
6
7
8
9
10
11
12
from sklearn.metrics import mean_absolute_error, mean_squared_error
import numpy as np
 
mae = mean_absolute_error(y_test, y_test_pred)
mse = mean_squared_error(y_test, y_test_pred)
rmse = np.sqrt(mse)
 
print('MAE\t{}'.format(round(mae, 3)))
print('MSE\t{}'.format(round(mse, 3)))
print('RMSE\t{}'.format(round(rmse, 3)))
 
 
cs

 

 


 

참고자료>>

 

https://www.coursera.org/learn/machine-learning-with-python/lecture/5SxtZ/evaluation-metrics-in-regression-models

 

Evaluation Metrics in Regression Models - Regression | Coursera

Video created by IBM 기술 네트워크 for the course "Python을 통한 머신 러닝". In this module, you will get a brief intro to regression. You learn about Linear, Non-linear, Simple and Multiple regression, and their applications. You apply all th

www.coursera.org

 

https://medium.com/analytics-vidhya/understanding-polynomial-regression-5ac25b970e18

 

Understanding Polynomial Regression!!!

Polynomial Regression is a special case of Linear Regression where we fit the polynomial equation on the data with a curvilinear…

medium.com

 

책:  빅데이터 분석기사 책 한권으로 끝내기 (SD 에듀, 시대고시기획)

책:  파이썬 딥러닝 머신러닝 입문 (정보 문화사, 저자: 오승환)

반응형