1. Polynomial Regression(다항회귀)

3. Polynomial Regression(다항 회귀)

이론

  • 단순 선형 회귀 : y = mx + b

  • 다중 선형 회귀 : y = b + m1x1 + m2x2 + … + mnxn

  • 다항 회귀 : y = b + m1x + m1x2 + … + mnxn

선형 회귀에서는 1차 방정식으로서 직선이였다면, 다항 회귀는 2차이상으로서 곡선을 표현

공부 시간에 따른 시험 점수 (우등생)

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
dataset = pd.read_csv('PolynomialRegressionData.csv')
X = dataset.iloc[:, :-1].values
y = dataset.iloc[:, -1].values

3-1. 단순 선형 회귀 (Simple Linear Regression)

from sklearn.linear_model import LinearRegression
reg = LinearRegression()
reg.fit(X, y) # 전체 데이터로 학습
LinearRegression()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.

데이터 시각화 (전체)

plt.scatter(X, y, color='blue') # 산점도
plt.plot(X, reg.predict(X), color='green') # 선 그래프
plt.title('Score by hours (genius)') # 제목
plt.xlabel('hours') # X 축 이름
plt.ylabel('score') # Y 축 이름
plt.show()

reg.score(X, y) # 전체 데이터를 통한 모델 평가
0.8169296513411765

3-2. 다항 회귀 (Polynomial Regression)

from sklearn.preprocessing import PolynomialFeatures
poly_reg = PolynomialFeatures(degree=4) # 4차
X_poly = poly_reg.fit_transform(X)
X_poly[:5] # [x] -> [x^0, x^1, x^2] -> x 가 3이라면 [1, 3, 9] 으로 변환
array([[1.0000e+00, 2.0000e-01, 4.0000e-02, 8.0000e-03, 1.6000e-03],
       [1.0000e+00, 5.0000e-01, 2.5000e-01, 1.2500e-01, 6.2500e-02],
       [1.0000e+00, 8.0000e-01, 6.4000e-01, 5.1200e-01, 4.0960e-01],
       [1.0000e+00, 9.0000e-01, 8.1000e-01, 7.2900e-01, 6.5610e-01],
       [1.0000e+00, 1.2000e+00, 1.4400e+00, 1.7280e+00, 2.0736e+00]])
X[:5]
array([[0.2],
       [0.5],
       [0.8],
       [0.9],
       [1.2]])
poly_reg.get_feature_names_out()
array(['1', 'x0', 'x0^2', 'x0^3', 'x0^4'], dtype=object)
lin_reg = LinearRegression()
lin_reg.fit(X_poly, y) # 변환된 X 와 y 를 가지고 모델 생성 (학습)
LinearRegression()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.

데이터 시각화 (변환된 X 와 y)

plt.scatter(X, y, color='blue')
plt.plot(X, lin_reg.predict(poly_reg.fit_transform(X)), color='green')
plt.title('Score by hours (genius)') # 제목
plt.xlabel('hours') # X 축 이름
plt.ylabel('score') # Y 축 이름
plt.show()

# 위의 선이 부드럽지 않아서 numpy 활용
X_range = np.arange(min(X), max(X), 0.1) # X 의 최소값에서 최대값까지의 범위를 0.1 단위로 잘라서 데이터를 생성
X_range
array([0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. , 1.1, 1.2, 1.3, 1.4,
       1.5, 1.6, 1.7, 1.8, 1.9, 2. , 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7,
       2.8, 2.9, 3. , 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4. ,
       4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7])
X_range.shape
(46,)
X[:5]
array([[0.2],
       [0.5],
       [0.8],
       [0.9],
       [1.2]])
X.shape
(20, 1)
# column 개수 맞추기
X_range = X_range.reshape(-1, 1) # row 개수는 자동으로 계산(-1), column 개수는 1개
X_range.shape
(46, 1)
X_range[:5]
array([[0.2],
       [0.3],
       [0.4],
       [0.5],
       [0.6]])
# 선이 더 부드러워 진것을 볼 수 있음
plt.scatter(X, y, color='blue')
plt.plot(X_range, lin_reg.predict(poly_reg.fit_transform(X_range)), color='green')
plt.title('Score by hours (genius)') # 제목
plt.xlabel('hours') # X 축 이름
plt.ylabel('score') # Y 축 이름
plt.show()

공부 시간에 따른 시험 성적 예측

reg.predict([[2]]) # 2시간을 공부했을 때 선형 회귀 모델의 예측
array([19.85348988])
lin_reg.predict(poly_reg.fit_transform([[2]])) # 2시간을 공부했을 때 다항 회귀 모델의 예측
array([8.70559135])
# 단순 선형 회귀보다 점수가 더 높은것을 알 수 있다.
lin_reg.score(X_poly, y)
0.9782775579000045

다항 회귀 - 과대 적합 현상

모델이 훈련 세트에 과하게 적합한 상태가 되어 일반성이 떨어지는 현상이다.

  • 우리가 사용한 훈련 세트의 점들에는 정말 높은 정확성을 보여주는데, 예측을 하려고 하면 정말 엉터리 값이 나올 수 있다.

  • 과대 적합의 예시로 아래에 Degree가 10차인 그래프를 참고

from sklearn.preprocessing import PolynomialFeatures
poly_reg = PolynomialFeatures(degree=10) # 10차
X_poly = poly_reg.fit_transform(X)
X_poly[:5] # [x] -> [x^0, x^1, x^2] -> x 가 3이라면 [1, 3, 9] 으로 변환
lin_reg = LinearRegression()
lin_reg.fit(X_poly, y) # 변환된 X 와 y 를 가지고 모델 생성 (학습)
# 위의 선이 부드럽지 않아서 numpy 활용
X_range = np.arange(min(X), max(X), 0.1) # X 의 최소값에서 최대값까지의 범위를 0.1 단위로 잘라서 데이터를 생성

# column 개수 맞추기
X_range = X_range.reshape(-1, 1) # row 개수는 자동으로 계산(-1), column 개수는 1개
# 선이 더 부드러워 진것을 볼 수 있음
plt.scatter(X, y, color='blue')
plt.plot(X_range, lin_reg.predict(poly_reg.fit_transform(X_range)), color='green')
plt.title('Score by hours (genius)') # 제목
plt.xlabel('hours') # X 축 이름
plt.ylabel('score') # Y 축 이름
plt.show()

lin_reg.predict(poly_reg.fit_transform([[2]])) # 2시간을 공부했을 때 다항 회귀 모델의 예측
array([29.89734668])
  • 이렇게 엉터리로 예측을 할 수 있음

  • 따라서 너무 훈련세트에만 의존하게 해서는 안된다.

참고자료 : 나도코딩-유튜브

추천!

댓글남기기