쓰쿠바 대학의 기계 학습 강좌 : 과제의 Python 스크립트 부분을 만들면서 sklearn 공부 (2)

지난 번부터 계속
쓰쿠바 대학의 기계 학습 강좌 : 과제의 파이썬 스크립트 부분을 만들면서 sklearn 공부 (1)
htps : // 기주 b. 이 m / ぇ가 cy를 rld / sk

과제 3.1 다항식 회귀의 제곱 오차



이것은 $y =\sin(x)$ 에 $N(0,1)\times0.1$ 의 오차를 실은 훈련 데이터를 만들어, 그것을 다항식으로 회귀시키는 문제.
해설은 제3회(1) 56분 40초당

Homework_3.1.py
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import copy
from sklearn.preprocessing import PolynomialFeatures as PF
from sklearn import linear_model
from sklearn.metrics import mean_squared_error
# 訓練用データの数
NUM_TR = 6
np.random.seed(0)
rng = np.random.RandomState(0)

# 描画用のx軸データ
x_plot = np.linspace(0,10,100)
# 訓練データ
tmp = copy.deepcopy(x_plot)
rng.shuffle(tmp)
x_tr = np.sort(tmp[:NUM_TR])
y_tr = np.sin(x_tr) + 0.1*np.random.randn(NUM_TR)

# Matrixへ変換
X_tr = x_tr.reshape(-1,1)
X_plot = x_plot.reshape(-1,1)

# 多項式用のデータ
# 次数決め打ち
degree = 1
pf = PF(degree=degree)
X_poly = pf.fit_transform(X_tr)
X_plot_poly = pf.fit_transform(X_plot)

model = linear_model.LinearRegression()
model.fit(X_poly,y_tr)
fig = plt.figure()
plt.scatter(x_tr,y_tr,label="training Samples")
plt.plot(x_plot,model.predict(X_plot_poly),label=f"degree = {degree}")
plt.legend()
plt.ylim(-2,2)
fig.savefig(f"{degree}.png")

# 多項式用のデータ
# 全ての次数
fig = plt.figure()
plt.scatter(x_tr,y_tr,label="Training Samples")

for degree in range(1,NUM_TR):
    pf = PF(degree=degree)
    X_poly = pf.fit_transform(X_tr)
    X_plot_poly = pf.fit_transform(X_plot)
    model = linear_model.LinearRegression()
    model.fit(X_poly,y_tr)
    plt.plot(x_plot,model.predict(X_plot_poly),label=f"degree {degree}")
    plt.legend()
    mse = mean_squared_error(y_tr,model.predict(X_poly))
    print(f"degree = {degree} mse = {mse}")

plt.xlim(0,10)
plt.ylim(-2,2)
fig.savefig('all_degree.png')

회귀의 계산을 시키기 위한 데이터( x_tr )와 그래프 묘화용( x_plot )로 2개 준비하고 있다.
단순히 x_tr = x_plot 그렇게하면 실제 데이터가 복사되지 않습니다.
그대로 하면 x_tr = np.sort(tmp[:NUM_TR]) 의 부분에서 묘화용 데이터의 수도 NUM_TR 가 되어 버려, 그래프 묘화가 이상해진다.
그래서 deepcopy를 이용하고 있다.

원 데이터로서 0-10 사이를 100 등분한 것을 준비하고 있다.
훈련용 데이터는 그 중 NUM_TR 만 랜덤으로 선택한다(강좌에서는 6개)
오차로서 0-1 사이에서 발생시킨 난수에 1/10을 곱한 것을 sin(x_tr)에 더하고 있다.
처음에 seed를 고정하고 있기 때문에, 어느 환경에서 몇번 실행해도 같은 결과가 나온다.
준비된 데이터는


지금까지와 다른 것은 PolynomialFeatures라는 부분이다.
이것은 다항식의 차수만큼 $x,x^2,x^3,x^4$로 훈련 데이터를 준비하는 부분이 된다.
예를 들면 차수 = 3이라고 한다.
degree = 3
pf = PF(degree=degree)
X_poly = pf.fit_transform(X_tr)
print(f"degree = {degree}\nX_Tr = {X_tr}\nX_poly = {X_poly}")

실행 결과는
degree = 3
X_Tr = [[0.2020202 ]
 [2.62626263]
 [5.55555556]
 [7.57575758]
 [8.68686869]
 [9.39393939]]
X_poly = [[1.00000000e+00 2.02020202e-01 4.08121620e-02 8.24488122e-03]
 [1.00000000e+00 2.62626263e+00 6.89725538e+00 1.81140040e+01]
 [1.00000000e+00 5.55555556e+00 3.08641975e+01 1.71467764e+02]
 [1.00000000e+00 7.57575758e+00 5.73921028e+01 4.34788658e+02]
 [1.00000000e+00 8.68686869e+00 7.54616876e+01 6.55525771e+02]
 [1.00000000e+00 9.39393939e+00 8.82460973e+01 8.28978490e+02]]

첫 번째 데이터라면 원래의 훈련 데이터는 $x = 2.020202\times10^{-1}$로, $x^2=4.08\times10^{-2}$이다.
요점은 $x^2,x^3$를 다른 특징량으로 취급하는 것이다.

다음으로 1차(직선)로 회귀시켜 보자. 결과는 이것.

마지막으로 차수를 1-5로 변화시켜 각각 그래프에 그려 보자.


오차는 이것. degree=5만 숫자가 맞지 않았다.
degree = 1 mse = 0.33075005001856256
degree = 2 mse = 0.3252271169458752
degree = 3 mse = 0.30290034474812344
degree = 4 mse = 0.010086018410257538
degree = 5 mse = 3.1604543144050787e-22

좋은 웹페이지 즐겨찾기