LoginSignup
2
3

More than 3 years have passed since last update.

筑波大学の機械学習講座:課題のPythonスクリプト部分を作りながらsklearnを勉強する (4)

Last updated at Posted at 2020-05-24

筑波大学の機械学習講座:課題のPythonスクリプト部分を作りながらsklearnを勉強する (1)
筑波大学の機械学習講座:課題のPythonスクリプト部分を作りながらsklearnを勉強する (2)
筑波大学の機械学習講座:課題のPythonスクリプト部分を作りながらsklearnを勉強する (3)
https://github.com/legacyworld/sklearn-basic

課題 3.4 多項式単回帰の正則化

さて、今回はリッジ回帰である。
Youtubeの解説はないようにみえるが、一部結果が第4回(1) 9分45秒あたりにある。
ソースコードとしては課題 3.2とほぼほぼ同じである。
今回の課題では次数は30に固定している。
その代わりに正則化パラメータを[1e-30,1e-20,1e-10,1e-5, 1e-3,1e-2,1e-1, 1,10,100]で動かしていく。
ソースコード内では正則化パラメータはalphaとしている。Pythonのlambdaは予約されているので。

Homework_3.4.py
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures as PF
from sklearn import linear_model
from sklearn.pipeline import Pipeline
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import cross_val_score

DEGREE = 30

def true_f(x):
    return np.cos(1.5 * x * np.pi)

np.random.seed(0)
n_samples = 30

# 描画用のx軸データ
x_plot = np.linspace(0,1,100)
# 訓練データ
x_tr = np.sort(np.random.rand(n_samples))
y_tr = true_f(x_tr) + np.random.randn(n_samples) * 0.1
# Matrixへ変換
X_tr = x_tr.reshape(-1,1)
X_plot = x_plot.reshape(-1,1)
degree = DEGREE
alpha_list = [1e-30,1e-20,1e-10,1e-5, 1e-3,1e-2,1e-1, 1,10,100]
for alpha in alpha_list:
    plt.scatter(x_tr,y_tr,label="Training Samples")
    plt.plot(x_plot,true_f(x_plot),label="True")
    plt.xlim(0,1)
    plt.ylim(-2,2)
    filename = f"{alpha}.png"
    pf = PF(degree=degree,include_bias=False)
    linear_reg = linear_model.Ridge(alpha=alpha)
    steps = [("Polynomial_Features",pf),("Linear_Regression",linear_reg)]
    pipeline = Pipeline(steps=steps)
    pipeline.fit(X_tr,y_tr)
    plt.plot(x_plot,pipeline.predict(X_plot),label="Model")
    y_predict = pipeline.predict(X_tr)
    mse = mean_squared_error(y_tr,y_predict)
    scores = cross_val_score(pipeline,X_tr,y_tr,scoring="neg_mean_squared_error",cv=10)
    plt.title(f"Degree: {degree}, Lambda: {alpha}\nTrainErr: {mse:.2e} TestErr: {-scores.mean():.2e}(+/- {scores.std():.2e})")
    plt.legend()
    plt.savefig(filename)
    plt.clf()
    print(f"正則化パラメータ = {alpha}, 訓練誤差 = {mse}, テスト誤差 = {-scores.mean():.2e}")

変更しているのは

linear_reg = linear_model.Ridge(alpha=alpha)

だけである。
このプログラムを実行すると以下のようなWarningが出る。

/usr/local/lib64/python3.6/site-packages/sklearn/linear_model/_ridge.py:190: UserWarning: Singular matrix in solving dual problem. Using least-squares solution instead.
  warnings.warn("Singular matrix in solving dual problem. Using "

これはコレスキー分解というところで出ているようなのだがよくわからなかった。

linear_model/ridge.py
try:
   # Note: we must use overwrite_a=False in order to be able to
   #       use the fall-back solution below in case a LinAlgError
   #       is raised
   dual_coef = linalg.solve(K, y, sym_pos=True,overwrite_a=False)
except np.linalg.LinAlgError:
   warnings.warn("Singular matrix in solving dual problem. Using "
   "least-squares solution instead.")
   dual_coef = linalg.lstsq(K, y)[0]

連立方程式が解けないから最小二乗法でやるよ、ということのようだが・・・
1e-30,1e-20だけで出る理由は何なのかわからなかった。

実行結果

正則化パラメータ = 1e-30, 訓練誤差 = 0.002139325105436034, テスト誤差 = 5.11e+02
正則化パラメータ = 1e-20, 訓練誤差 = 0.004936191193133389, テスト誤差 = 5.11e+02
正則化パラメータ = 1e-10, 訓練誤差 = 0.009762751388489265, テスト誤差 = 1.44e+02
正則化パラメータ = 1e-05, 訓練誤差 = 0.01059565315043209, テスト誤差 = 2.79e-01
正則化パラメータ = 0.001, 訓練誤差 = 0.010856091742299396, テスト誤差 = 6.89e-02
正則化パラメータ = 0.01, 訓練誤差 = 0.012046102850453813, テスト誤差 = 7.79e-02
正則化パラメータ = 0.1, 訓練誤差 = 0.02351033489834412, テスト誤差 = 4.94e-02
正則化パラメータ = 1, 訓練誤差 = 0.11886509938269865, テスト誤差 = 2.26e-01
正則化パラメータ = 10, 訓練誤差 = 0.31077333649742883, テスト誤差 = 4.71e-01
正則化パラメータ = 100, 訓練誤差 = 0.41104732329314453, テスト誤差 = 5.20e-01
  • 最も小さい訓練誤差

    • 正則化パラメータ = 1e-30
    • 1e-30.png
  • 最も小さいテスト誤差

    • 正則化パラメータ = 0.1
    • 解説では0.01が一番良いとのことだがこのプログラムでは0.1の方がテスト誤差が小さかった 0.1.png

正則化が効きすぎると平均を取るだけになるし、効きが弱いと過学習になってしまう。
なのでリッジ回帰でも正則化パラメータのチューニングに交差検証は必要。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3