Python/Python X 머신러닝

다항 회귀(python with sklearn)

힘법사 2020. 10. 16. 20:29
728x90

  이 포스팅에서는 핸즈온 머신러닝 교재에 나오는 다항회귀에 대해서 논하겠습니다. C++로 회귀하는 작업을 보고싶은신 분은 아래 게시물을 참고해 주세요.( C++에서 회귀 코드를 보시면 정확하게 회귀가 어떤 원리로 일어나는지 확인하실 수 있습니다.)

himbopsa.tistory.com/6

 

1차 선형 회귀 예제 경사하강법 사용(C++)

 1. 1차 선형 회귀란? 1차 선형 회귀는 데이터에 대해 최대한 일치하는 y = ax + b를 찾는 것 입니다. 이번 포스팅에서는 C++에서 데이터를 이용해 a와 b 값을 찾아 데이터에 fitting 하는 것을 예시를 ��

himbopsa.tistory.com

0) 사용한 라이브러리

import numpy as np
import numpy.random as rnd
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import SGDRegressor
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

 제가 해당 ipynb에서 다른 것들도 여러개 시도해서 이번 게시물에 안쓰는 라이브러리도 있습니다.  이번 포스팅에 사용되는 라이브러리가 포함되어있고 다음 포스팅에 차후 사용될 라이브러리도 포함되어 있습니다.

 

 1) 간단한 비선형 데이터 생성하기.

  먼저 python에서 학습을할 data를 만들어 줘야 합니다. data는 아래식에서 약간의 잡음을 섞어서 만들도록 하겠습니다.

그림. 생성할 함수

 이를 python으로 구현하는 코드를 보이겠습니다.

m = 100
X = 6 * np.random.rand(m, 1) - 3 
y = 0.5 * X**2 + X + 2 +np.random,randn(m,1)

#이하 데이터 시각화를 위한 code
plt.plot(X, y, "b.")
plt.xlabel("$x_1$", fontsize=18)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.axis([-3, 3, 0, 10])
plt.show()

 np.random,rand(m,1)은 0 ~ 1 사이의 난수를 생성해 m by 1 matrix를 만들어 줍니다. 고로 두번 째 줄에서 X의 범위는 다음과 같습니다. -3 < X < 3

 이를 Y에 원하는 식으로 표현해서 저장해 주었습니다. 데이터 시각화 코드를 통해서 생성하면 다음과 같은 결과를 얻을 수 있습니다.

그림. data image with gaussian random noise

2) 데이터 이차 다항 회귀

 이제 다음 이차식 + noise의 데이터를 이용해 2차 회귀를 해보겠습니다. 이를 위해서 2차 회귀를 위한 객체를 생성하겠습니다.

poly_features = PolynomialFeatures(degree=2, include_bias=False) 
X_poly = poly_features.fit_transform(X)

 degree = 2로 다음과 같이 설정해줘 2차 회귀를 위한 준비를 했습니다.  fit_transform은 데이터를 fitting 해주고 transform을 동시에 해주는 명령으로 fit을 해준 후 transform을 해줄 수도 있습니다. 하지만, fit_transform이 최적화 되어있어 더 빨리 코드가 동작할 수도 있습니다.

 이제 그래프를 만들어 보겠습니다. 이를 위해 추가적으로 코드를 더 적겠습니다.

lin_reg = LinearRegression()
lin_reg.fit(X_poly, y) 
lin_reg.intercept_, lin_reg.coef_
X_new=np.linspace(
-3, 3, 100).reshape(100, 1)

X_new_poly = poly_features.transform(X_new)
print(X_poly)
print(X_new)
y_new = lin_reg.predict(X_new_poly)

plt.plot(X, y, "b.")
plt.plot(X_new, y_new, "r-", linewidth=2, label="Predictions")
plt.xlabel("$x_1$", fontsize=18)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.legend(loc="upper left", fontsize=14)
plt.axis([-3, 3, 0, 10])
plt.show()

회귀를 위해서 lin_reg라는 선형 회귀 객체를 만들어 줍니다. 그리고 이를 압서 만든 X_poly, y에 대해 fitting 시켜주고 reshape을 통해서 우리가 원하는 데이터 어레이로 변환을 시켜 줍니다.(reshape 100개의 rows 1 columns로 바꾸겠다는 의미입니다.)

이렇게 완성된 X_new를 다시 transform 시켜주고 predict을 이용해 출력할 y_new 값을 최종적으로 생성해줍니다. 이를 통해 그래프를 그려주면 다음과 같은 그림을 얻을 수 있습니다.

 이런 방식으로 데이터에 대해서 다항 회귀를 진행하실 수 있습니다. 이 게시물에서는 대표적으로 2차 회귀만을 다뤘는데 교제에서는 50차 다항회귀도 하는 것도 보여줍니다. 하지만, 그 방법은 2차 다항회귀와 다를 바가 거의 없습니다. 다음에는 다른 주제로 찾아오도록 하겠습니다. 감사합니다. 

그림. 2차 선형회귀된 이미지

728x90