【scikit-learn】線形回帰の正則化手法 ~ラッソ(Lasso)回帰、リッジ(Ridge)回帰、ElasticNet回帰~

Python の機械学習ライブラリである scikit-learn には線形回帰に正則化を適用した各種手法が実装されています。正則化が適用されている手法としてラッソ (Lasso) 回帰、リッジ (Ridge) 回帰、ElasticNet 回帰について使用方法を解説します。
目次
線形回帰と正則化
回帰分析とは、予測したいデータに対して、既に与えられているデータから関係性を予測することを言います。この時に $x^{2}$、$x^{3}$ のような累乗の形がない線形の式で予測する方法のことを線形回帰と言います。
機械学習の分野では、学習データに対して過度にモデルが適合してしまうことを過学習(overfitting)と言います。未知データに対する予測誤差を汎化誤差と言いますが、過学習が起こると汎化誤差が大きくなります。このような時、汎化誤差が大きくならないようにモデルに手を加えることを正則化と言います。
線形回帰にも正則化を適用した各種手法があり、L1 正則化を適用したものをラッソ (Lasso) 回帰、L2 正則化を適用したものをリッジ (Ridge) 回帰、L1 正則化と L2 正則化を組み合わせたものを ElasticNet 回帰と言います。
これらの各種正則化を適用した線形回帰手法は、Python の機械学習ライブラリである scikit-learn で既に実装されており、簡単に利用ができます。この記事では、各回帰手法の基本的な使い方を紹介します。
scikit-learn での正則化回帰手法の使い方
正則化回帰手法であるラッソ (Lasso) 回帰、リッジ (Ridge) 回帰、ElasticNet 回帰の基本的な使い方について解説していきます。
ラッソ (Lasso) 回帰
実装例
ラッソ (Lasso) 回帰は、L1 正則化で線形回帰を正則化する回帰モデルです。scikit-learnでは、sklearn.linear_model.Lasso で実装されています。
import numpy as np
from sklearn.datasets import make_regression
from sklearn.linear_model import Lasso
from sklearn.model_selection import train_test_split
def main():
"""メイン関数"""
np.random.seed(123)
np.set_printoptions(precision=3, suppress=True)
# ===== 線形回帰を行うためのデータを生成する
bias = 5.0
noise = 50.0
x, y, coef = make_regression(
n_samples=100,
n_features=10,
n_informative=5,
n_targets=1,
coef=True,
bias=bias,
noise=noise,
)
print(f"true coef: {coef}")
print(f"true bias: {bias:.3f}")
# 学習用データとテスト用データを分割する
train_x, test_x, train_y, test_y = train_test_split(x, y)
# ===== Lasso回帰モデルを生成する
model = Lasso(alpha=1.0)
# ===== モデルを学習する
model.fit(train_x, train_y)
# 推定結果の表示
print(f"coef: {model.coef_}")
print(f"bias: {model.intercept_:.3f}")
print(f"R2: {model.score(test_x, test_y):.3f}")
if __name__ == "__main__":
main()【実行結果】 true coef: [ 0. 79.45 0. 18.045 0. 22.194 74.221 0. 0. 69.981] true bias: 5.000 coef: [-1.322 78.107 5.754 25.559 -4.134 30.474 76.132 3.364 0. 69.677] bias: 6.504 R2: 0.844
実装内容の解説
上記で紹介した実装例の各部分ごとに内容を説明していきます。
必要モジュールのインポート
from sklearn.linear_model import Lasso
Lasso 回帰では、sklearn.linear_model から Lasso をインポートします。
データセットの用意
# ===== 線形回帰を行うためのデータを生成する
bias = 5.0
noise = 50.0
x, y, coef = make_regression(
n_samples=100,
n_features=10,
n_informative=5,
n_targets=1,
coef=True,
bias=bias,
noise=noise,
)
print(f"true coef: {coef}")
print(f"true bias: {bias:.3f}")
# 学習用データとテスト用データを分割する
train_x, test_x, train_y, test_y = train_test_split(x, y)今回は、sklearn.datasets.make_regression を使って線形回帰用のデータを用意します。各引数は以下の通りです。
n_samples: データ数n_features: 特徴数n_informative: 特徴のうち説明に寄与する変数の数n_targets: 目的値coef: データを生成した線形モデルの係数を返却するか否か(True: 返却)bias: バイアス値noise: データに加えるガウスノイズの標準偏差random_state: 乱数のシード
乱数のシードは np.random.seed で設定していますが、make_regression のrandom_state 引数で指定することも可能です。
また、train_test_split で学習用データとテスト用データを分割しています。
Lasso 回帰モデルの生成と学習
# ===== Lasso回帰モデルを生成する
model = Lasso(alpha=1.0)
# ===== モデルを学習する
model.fit(train_x, train_y)
# 推定結果の表示
print(f"coef: {model.coef_}")
print(f"bias: {model.intercept_:.3f}")
print(f"R2: {model.score(test_x, test_y):.3f}")上記の部分で Lasso 回帰モデルを生成して学習しています。alpha が正規化項の強さを決めるハイパーパラメータです。省略するとデフォルトで 1.0 が設定されます。このパラメータを変えつつ実行して結果を確認してみてください。
学習は fit メソッドで実行し、テストデータでの評価 (決定係数 $R^{2}$)は、score メソッドで計算しています。
リッジ回帰 (Ridge) 回帰
実装例
リッジ (Ridge) 回帰は、L2 正則化を用いて線形回帰を正則化する回帰モデルです。scikit-learnでは、sklearn.linear_model.Ridge で実装されています。
import numpy as np
from sklearn.datasets import make_regression
from sklearn.linear_model import Ridge
from sklearn.model_selection import train_test_split
def main():
"""メイン関数"""
np.random.seed(123)
np.set_printoptions(precision=3, suppress=True)
# ===== 線形回帰を行うためのデータを生成する
bias = 5.0
noise = 50.0
x, y, coef = make_regression(
n_samples=100,
n_features=10,
n_informative=5,
n_targets=1,
coef=True,
bias=bias,
noise=noise,
)
print(f"true coef: {coef}")
print(f"true bias: {bias:.3f}")
# 学習用データとテスト用データを分割する
train_x, test_x, train_y, test_y = train_test_split(x, y)
# ===== Ridge回帰モデルを生成する
model = Ridge(alpha=1.0)
# ===== モデルを学習する
model.fit(train_x, train_y)
# 推定結果の表示
print(f"coef: {model.coef_}")
print(f"bias: {model.intercept_:.3f}")
print(f"R2: {model.score(test_x, test_y):.3f}")
if __name__ == "__main__":
main()【実行結果】 true coef: [ 0. 79.45 0. 18.045 0. 22.194 74.221 0. 0. 69.981] true bias: 5.000 coef: [-2.864 78.568 7.093 25.949 -5.22 31.006 76.181 4.424 1.229 70.14 ] bias: 7.117 R2: 0.845
実装内容の解説
上記で紹介した実装例の各部分ごとに内容を説明していきます。Lasso 回帰で説明している部分については省略します。
必要モジュールのインポート
from sklearn.linear_model import Ridge
Ridge 回帰では、sklearn.linear_model から Ridge をインポートします。
Ridge 回帰モデルの生成と学習
# ===== Ridge回帰モデルを生成する
model = Ridge(alpha=1.0)上記の部分で Ridge 回帰モデルを生成しています。alpha が正規化項の強さを決めるハイパーパラメータです。省略するとデフォルトで 1.0 が指定されます。このパラメータを変えつつ実行して結果を確認してみてください。
学習 (fit) 等の実行方法については、Lasso のコードと全く同じです。
ElasticNet 回帰
実装例
ElasticNet 回帰は、L1 正則化と L2 正則化を組み合わせて正則化項を作るモデルです。scikit-learn では、sklearn.linear_model.ElasticNet で実装されています。
import numpy as np
from sklearn.datasets import make_regression
from sklearn.linear_model import ElasticNet
from sklearn.model_selection import train_test_split
def main():
"""メイン関数"""
np.random.seed(123)
np.set_printoptions(precision=3, suppress=True)
# ===== 線形回帰を行うためのデータを生成する
bias = 5.0
noise = 50.0
x, y, coef = make_regression(
n_samples=100,
n_features=10,
n_informative=5,
n_targets=1,
coef=True,
bias=bias,
noise=noise,
)
print(f"true coef: {coef}")
print(f"true bias: {bias:.3f}")
# 学習用データとテスト用データを分割する
train_x, test_x, train_y, test_y = train_test_split(x, y)
# ===== ElasticNet回帰モデルを生成する
model = ElasticNet(alpha=1.0, l1_ratio=0.7)
# ===== モデルを学習する
model.fit(train_x, train_y)
# 推定結果の表示
print(f"coef: {model.coef_}")
print(f"bias: {model.intercept_:.3f}")
print(f"R2: {model.score(test_x, test_y):.3f}")
if __name__ == "__main__":
main()【実行結果】 true coef: [ 0. 79.45 0. 18.045 0. 22.194 74.221 0. 0. 69.981] true bias: 5.000 coef: [ 2.5 60.05 2.82 18.707 -7.325 22.637 62.551 -0.551 -0.667 53.213] bias: -2.243 R2: 0.800
実装内容の解説
上記で紹介した実装例の各部分ごとに内容を説明していきます。Lasso 回帰や Ridge 回帰で説明している部分については省略します。
必要モジュールのインポート
from sklearn.linear_model import ElasticNet
ElasticNet 回帰は、sklearn.linear_model から ElasticNet をインポートします。
ElasticNet 回帰モデルの生成と学習
# ===== ElasticNet回帰モデルを生成する
model = ElasticNet(alpha=1.0, l1_ratio=0.7)上記の部分で ElasticNet 回帰モデルを生成しています。alpha が正規化項の強さを決めるハイパーパラメータです。省略するとデフォルトで 1.0 が指定されます。
ElasticNet では、l1_ratio を設定することで L1 正則化と L2 正則化項の効果の割合を指定することができます。例えば、l1_ratio=0.7 のように設定すると L1 正則化の割合が 70%、L2 正則化が 30% の強さで効果があるように設定ができます。なお、l1_ratio を指定しない場合は、l1_ratio=0.5 になります。つまりは L1 正則化が50%、L2 正則化が 50% という効果になります。
学習 (fit) 等の実行方法については、Lasso や Ridge のコードと全く同じです。
まとめ
Python の機械学習ライブラリである scikit-learn において正則化が適用されている回帰手法のラッソ (Lasso) 回帰、リッジ (Ridge) 回帰、ElasticNet 回帰について使用方法を解説しました。
Lasso 回帰が L1 正則化、Ridge 回帰が L2 正則化、ElasticNet 回帰は L1 と L2 を組み合わせたものです。この記事では、各手法の基本的な使い方を紹介しました。
L1 正則化は、重要なパラメータを残して不要なパラメータを 0 にする(スパースにする)効果があり、L2 正則化はパラメータを全体的に小さくする効果があります。目的に応じて Lasso 回帰、Ridge 回帰、ElasticNet 回帰を使いつつ比べてみてください。
上記で紹介しているソースコードについては GitHub にて公開しています。参考にしていただければと思います。


の使用方法.jpg)
.jpg)



