【scikit-learn】ElasticNetの意味と使い方について

はるか
はるか
ElasticNetは、LassoとRidgeを組み合わせたもの。
ふゅか
ふゅか
そうそう!両方のいいとこ取りがElasticNetなんだ!

1. ElasticNetとは?

ElasticNetは、回帰分析において使用される正則化手法の一つです。ElasticNetは、Lasso回帰(L1正則化)とRidge回帰(L2正則化)の両方を組み合わせたモデルで、それぞれのメリットを活かしながら、欠点を補完します。

1.1. 背景:回帰分析と正則化

回帰分析では、モデルがデータに過剰に適合する(過学習)問題を防ぐために「正則化」という技術が使われます。正則化は、モデルの複雑さを制限することで、汎化性能を高める手法です。以下の2つが代表的な正則化手法です。

  • Lasso回帰(L1正則化)特徴量の中から不要なものを完全に「ゼロ」にすることで特徴量選択が可能になります。ただし、相関の強い特徴量がある場合、どちらか一方しか選ばれない傾向があります。
  • Ridge回帰(L2正則化)すべての特徴量を残しつつ、モデルの重みの2乗をペナルティとして与えます。

1.2. ElasticNetの数式

ElasticNetの目的関数は以下のように定義されます。

minβ{12nyXβ22+λ1β1+λ2β22} \min_{\beta} \left\{ \frac{1}{2n} \|y – X\beta\|_2^2 + \lambda_1 \|\beta\|_1 + \lambda_2 \|\beta\|_2^2 \right\}

ここで

  • y y は目的変数(予測したい値)
  • X X は説明変数(特徴量)
  • β \beta は回帰係数
  • λ1β1 \lambda_1 \|\beta\|_1 がLasso回帰のペナルティ項
  • λ2β22 \lambda_2 \|\beta\|_2^2 がRidge回帰のペナルティ項
  • λ1 \lambda_1 λ2 \lambda_2 はハイパーパラメータ(調整値)
ふゅか
ふゅか
ElasticNetの目的関数って、L1とL2が混ざってるよね!

2. ElasticNetの実装例

ElasticNetは、Pythonscikit-learnライブラリで次のように実装できます。

from sklearn.linear_model import ElasticNet
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.datasets import load_diabetes
# データの準備
diabetes= load_diabetes()
X,y = diabetes.data,diabetes.target

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# モデルの定義と学習
elastic_net = ElasticNet(alpha=1.0, l1_ratio=0.5, random_state=42)
elastic_net.fit(X_train, y_train)

# モデルの予測
y_pred = elastic_net.predict(X_test)

# モデル評価
mse = mean_squared_error(y_test, y_pred)
print(f"Mean Squared Error: {mse}")
  • alpha: 全体の正則化の強さを制御します。
  • l1_ratio: L1正則化(Lasso)の割合を設定します。0でRidge、1でLasso、間でElasticNet。

2.1. ハイパーパラメータの調整方法

ElasticNetには主に2つのハイパーパラメータがあります:

  • alpha(正則化の強さ)
  • l1_ratio(L1とL2のバランス)

これらを最適化するには、グリッドサーチを利用します。

from sklearn.model_selection import GridSearchCV

param_grid = {
    'alpha': [0.1, 0.5, 1.0, 2.0],
    'l1_ratio': [0.1, 0.5, 0.7, 1.0]
}

grid_search = GridSearchCV(ElasticNet(random_state=42), param_grid, cv=5, scoring='neg_mean_squared_error')
grid_search.fit(X_train, y_train)

print(f"Best Parameters: {grid_search.best_params_}")

実際に動かすと、次のようになります。