L1正則化とL2正則化
L1正則化とL2正則化とは?
L1正則化とL2正則化は、過学習を防ぎ、機械学習モデルの汎化性能を向上させるために使用されるテクニックです。これらは正則化(Regularization)の手法の一部で、モデルの複雑さにペナルティを課すことで訓練データに対するオーバーフィットを避けるのが目的です。
この記事では意図的にオーバーフィットしそうなデータを生成し、L1正則化とL2正則化を行なった結果を見てみたいと思います。
データの生成
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
X, y = make_regression(n_samples=50, n_features=100, n_informative=5, noise=0.2, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
データの生成はscikit-learnのmake_regressionを利用しています。
データのサンプル数に比べて特徴量の数を増やし、オーバーフィットを引き起こしそうなデータを生成しています。
正則化無しの線形回帰
最も基本的な線形回帰を適用してみます。
from sklearn.linear_model import LinearRegression
linear_model = LinearRegression()
linear_model.fit(X_train, y_train)
print("Training score:", linear_model.score(X_train, y_train))
print("Testing score:", linear_model.score(X_test, y_test))
結果は下記の通りとなりました。
テストデータに対しては0.525とうまく一般化できていなさそうです。
それでは、L1正則化、L2正則化の効果を比較してみます。
L1正則化(Lasso正則化)
L1正則化は、モデルの重みパラメータの絶対値の和に対してペナルティを課します。
from sklearn.linear_model import Lasso
lasso_model = Lasso(alpha=0.1)
lasso_model.fit(X_train, y_train)
print("Training score:", lasso_model.score(X_train, y_train))
print("Testing score:", lasso_model.score(X_test, y_test))
LassoはL1正則化を適用した線形回帰モデルです。
結果は下記の通りとなりました。テストデータに対しても高いパフォーマンスが出ています。
L2正則化(Ridge正則化)
L2正則化は、モデルの重みパラメータの二乗和に対してペナルティを課します。
from sklearn.linear_model import Ridge
ridge_model = Ridge(alpha=0.1)
ridge_model.fit(X_train, y_train)
print("Training score:", ridge_model.score(X_train, y_train))
print("Testing score:", ridge_model.score(X_test, y_test))
RidgeはL2正則化を適用した線形回帰モデルです。
それでは結果を見てみます。
やや通常の線形回帰よりも良いスコアとなりました。alphaは正則化の強さを制御する重要なハイパーパラメータですが、この値を最適化することによって予測性能をより最大化出来るかもしれません。これについては次の機会に実践してみたいと思います。
それでは最後に各モデルの係数をプロットしてみます。
import numpy as np
import matplotlib.pyplot as plt
linear_coeffs = linear_model.coef_
lasso_coeffs = lasso_model.coef_
ridge_coeffs = ridge_model.coef_
plt.figure(figsize=(15, 5))
plt.plot(np.abs(linear_coeffs), label='Linear Regression', marker='o')
plt.plot(np.abs(lasso_coeffs), label='Lasso Regression', marker='^')
plt.plot(np.abs(ridge_coeffs), label='Ridge Regression', marker='x')
plt.xlabel('Coefficient Index')
plt.ylabel('Coefficient Magnitude')
plt.yscale('log')
plt.title('Comparison of Coefficient Magnitudes')
plt.legend()
plt.grid(True)
plt.show()
このグラフは、通常の線形回帰モデル、L1正則化(Lasso回帰)を適用したモデル、そしてL2正則化(Ridge回帰)を適用したモデルの係数の絶対値を比較しています。係数の大きさ(絶対値)は対数スケールで表示されています。
線形回帰モデルでは、いくつかの係数が大きな値を持ち、他の係数も0ではない値を持っていることがわかります。
Lasso回帰モデルでは、多くの係数が実際に0になっていることがわかります。これはL1正則化が特徴選択のような役割を果たし、不要な特徴量をモデルから排除する効果があることを示しています。
Ridge回帰モデルでは、すべての係数が0にはならず、しかし係数の絶対値が全体的に小さく抑えられていることがわかります。これはL2正則化が係数の大きさを制限し、過学習を防ぐ効果があることを示しています。