【Python】scikit-learn ~ 重回帰 / ロッソ回帰・エラスティックネット ~

■ はじめに

https://dk521123.hatenablog.com/entry/2020/03/02/233902
https://dk521123.hatenablog.com/entry/2020/03/08/113356
https://dk521123.hatenablog.com/entry/2020/07/04/000000
https://dk521123.hatenablog.com/entry/2020/04/25/174503

の続き。

 重回帰分析の
「ロッソ回帰」「エラスティックネット」について扱う。

目次

【1】用語整理
 1)リッジ回帰 (Ridge Regression)
 2)ロッソ回帰 (Lasso Regression)
 3)エラスティックネット (Elastic Net)
【2】サンプル
 例1)ロッソ回帰
 例2)エラスティックネット

【1】用語整理

1)リッジ回帰 (Ridge Regression)
2)ロッソ回帰 (Lasso Regression)
3)エラスティックネット (Elastic Net)

1)リッジ回帰 (Ridge Regression)

* 詳細は、以下の関連記事を参照のこと。

https://dk521123.hatenablog.com/entry/2020/04/25/174503

2)ロッソ回帰 (Lasso Regression)

* 最小二乗コスト関数に対して、重みの合計を足したもの(L1正則化項)
* 不要と判断される説明変数の係数(重み)を0にする性質がある
 => 過学習を防ぐことに加えて、不要な特徴量を無効化(削除)してくれる

※ 自分なりのざっくりした解釈

リッジ回帰もロッソ回帰も、過学習を防ぐための正則化項をもっていて
その正則化項の違い(L1がロッソ回帰、L2がリッジ回帰)

3)エラスティックネット (Elastic Net)

* リッジ回帰とロッソ回帰を組み合わせたもの
* ハイパーパラメータγ(0≤γ≤1)で リッジ・ラッソ回帰の比率を指定
 => γ=0:リッジ回帰と一致
 => γ=1:ラッソ回帰と一致

【2】サンプル

* 使用するデータセットは、
 scikit-learnに付いてるがんの診断結果データセット

https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_breast_cancer.html

例1:ロッソ回帰

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.linear_model import ElasticNet
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import PolynomialFeatures
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.datasets import load_breast_cancer

# がんの診断結果データセットのダウンロード
breast_cancer_dataset = load_breast_cancer()
x = breast_cancer_dataset.data
y = breast_cancer_dataset.target

# 訓練データとテストデータに分割
x_train, x_test, y_train, y_test = \
  train_test_split(x, y, test_size=0.2, random_state=1)

# 特徴量を2次多項式に変換
polynomial_feature = PolynomialFeatures(
  degree=2, include_bias=False)

x_train_poly = polynomial_feature.fit_transform(x_train)
x_test_poly = polynomial_feature.transform(x_test)

# 特徴量を標準化する
standard_scaler = StandardScaler()
x_train_std = standard_scaler.fit_transform(x_train_poly)
x_test_std = standard_scaler.transform(x_test_poly)

# エラスティックネットインスタンス作成
# alpha(α)は、ハイパーパラメータで大きいと正則化が強くなる
# max_iter は、訓練データを何周させるか
# l1_ratio は、L1ロスの分配率
elastic_net = ElasticNet(
  alpha=0.1, max_iter=2000, l1_ratio=0.6)
# モデルの訓練
elastic_net.fit(x_train_std, y_train)

y_train_prd = elastic_net.predict(x_train_std)
y_test_prd = elastic_net.predict(x_test_std)

print("*平均二乗誤差 (MSE, Mean Squared Error))************************")
# 実際の値と予測値の絶対値の 2 乗を平均したもの
#  => 値が大きいほど誤差の多い
print('MSE train: {}, test: {}'.format(
  mean_squared_error(y_train, y_train_prd),
  mean_squared_error(y_test, y_test_prd)))
print("*************************")

出力結果

*平均二乗誤差 (MSE, Mean Squared Error))************************
MSE train: 0.06709808776543863, test: 0.08827289367162726
*************************

例2)エラスティックネット

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.linear_model import ElasticNet
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import PolynomialFeatures
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.datasets import load_breast_cancer

# がんの診断結果データセットのダウンロード
breast_cancer_dataset = load_breast_cancer()
x = breast_cancer_dataset.data
y = breast_cancer_dataset.target

# 訓練データとテストデータに分割
x_train, x_test, y_train, y_test = \
  train_test_split(x, y, test_size=0.2, random_state=1)

# 特徴量を2次多項式に変換
polynomial_feature = PolynomialFeatures(
  degree=2, include_bias=False)

x_train_poly = polynomial_feature.fit_transform(x_train)
x_test_poly = polynomial_feature.transform(x_test)

# 特徴量を標準化する
standard_scaler = StandardScaler()
x_train_std = standard_scaler.fit_transform(x_train_poly)
x_test_std = standard_scaler.transform(x_test_poly)

# エラスティックネットインスタンス作成
elastic_net = ElasticNet(alpha=0.1, l1_ratio=0.6)
# モデルの訓練
elastic_net.fit(x_train_std, y_train)

y_train_prd = elastic_net.predict(x_train_std)
y_test_prd = elastic_net.predict(x_test_std)

print("*平均二乗誤差 (MSE, Mean Squared Error))************************")
# 実際の値と予測値の絶対値の 2 乗を平均したもの
#  => 値が大きいほど誤差の多い
print('MSE train: {}, test: {}'.format(
  mean_squared_error(y_train, y_train_prd),
  mean_squared_error(y_test, y_test_prd)))
print("*************************")

出力結果

*平均二乗誤差 (MSE, Mean Squared Error))************************
MSE train: 0.06709808776543863, test: 0.08827289367162726
*************************

関連記事

scikit-learn ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2020/03/02/233902
scikit-learn ~ 基本編 ~
https://dk521123.hatenablog.com/entry/2020/03/08/113356
scikit-learn ~ 線形回帰 ~
https://dk521123.hatenablog.com/entry/2020/07/04/000000
scikit-learn ~ 重回帰/リッジ回帰 ~
https://dk521123.hatenablog.com/entry/2020/04/25/174503
scikit-learn ~ 決定木 / ランダムフォレスト ~
https://dk521123.hatenablog.com/entry/2020/04/04/021413
Matplotlib ~ グラフ描画ライブラリ ~
https://dk521123.hatenablog.com/entry/2020/03/01/000000