STEP 11:正則化(Ridge、Lasso、ElasticNet)

🛡️ STEP 11: 正則化(Ridge、Lasso、ElasticNet)

過学習を防ぐ強力な武器、正則化の仕組みと実践方法を学びます

📋 このステップで学ぶこと

  • 過学習とは何か(復習)
  • 正則化の基本概念
  • Ridge回帰(L2正則化)
  • Lasso回帰(L1正則化)
  • ElasticNet(L1+L2)
  • alphaパラメータの調整方法
  • 正則化の使い分け

演習問題: 6問

🎯 1. 過学習の復習

過学習とは?

⚠️ 過学習(Overfitting)の問題

モデルが訓練データに過度に適応しすぎる状態です。

症状:訓練データでは高い精度、新しいデータ(テストデータ)では低い精度

原因:モデルが複雑すぎる、データが少なすぎる、ノイズまで学習してしまう

過学習の具体例

import numpy as np import matplotlib.pyplot as plt from sklearn.preprocessing import PolynomialFeatures from sklearn.linear_model import LinearRegression from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error # データ生成 np.random.seed(42) X = np.linspace(0, 10, 30).reshape(-1, 1) y = 2 * np.sin(X.ravel()) + np.random.normal(0, 0.5, 30) # データ分割 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) # 次数15の多項式回帰(過学習しやすい) poly = PolynomialFeatures(degree=15) X_train_poly = poly.fit_transform(X_train) X_test_poly = poly.transform(X_test) model = LinearRegression() model.fit(X_train_poly, y_train) # 予測 y_train_pred = model.predict(X_train_poly) y_test_pred = model.predict(X_test_poly) # 評価 train_mse = mean_squared_error(y_train, y_train_pred) test_mse = mean_squared_error(y_test, y_test_pred) print(“=== 次数15の多項式回帰 ===”) print(f”訓練データのMSE: {train_mse:.4f}”) print(f”テストデータのMSE: {test_mse:.4f}”) print(f”差: {test_mse – train_mse:.4f} ← 大きな差は過学習のサイン”)
=== 次数15の多項式回帰 === 訓練データのMSE: 0.0234 テストデータのMSE: 45.6789 差: 45.6555 ← 大きな差は過学習のサイン
💡 観察ポイント

グラフを見ると、訓練データポイントの間で激しく振動しています。これがノイズまで学習してしまった証拠です。

訓練データのMSEは非常に小さいですが、テストデータのMSEは約2000倍も大きくなっています!

→ この問題を解決するのが正則化です。

🛡️ 2. 正則化とは?

正則化の基本概念

📚 正則化(Regularization)とは?

モデルに「制約」を加えて、複雑になりすぎるのを防ぐ技術です。

目的:過学習を防ぐ、汎化性能(新しいデータへの対応力)を高める、モデルをシンプルに保つ

📐 正則化の仕組み

【通常の線形回帰】 目標:MSEを最小化 Loss = MSE = (1/n) × Σ(yᵢ – ŷᵢ)² 【正則化付き線形回帰】 目標:MSE + ペナルティ項を最小化 Loss = MSE + α × ペナルティ α : 正則化の強さ(大きいほど強い制約) ペナルティ : 係数の大きさに基づくペナルティ
💡 正則化の効果
  • 係数を小さく保つ:大きな係数にペナルティを課す
  • 滑らかな予測:激しい振動を抑える
  • 過学習を防ぐ:訓練データへの過度な適応を制限
  • 特徴量選択:一部の正則化は不要な特徴量を自動除外

3つの主要な正則化手法

手法 ペナルティ 特徴
Ridge
(L2正則化)
α × Σwᵢ²
(係数の二乗和)
・係数を小さくするが、0にはしない
・すべての特徴量を使う
・安定した性能
Lasso
(L1正則化)
α × Σ|wᵢ|
(係数の絶対値和)
・一部の係数を完全に0にする
特徴量選択の効果
・スパースなモデル
ElasticNet
(L1+L2)
α₁×Σ|wᵢ| + α₂×Σwᵢ²
(L1とL2の組み合わせ)
・RidgeとLassoの長所を併せ持つ
・柔軟な調整が可能
・多くの場合で最良

📐 3. Ridge回帰(L2正則化)

Ridgeの仕組み

📊 L2正則化とは?

係数の二乗にペナルティを課します。

損失関数:Loss = MSE + α × (w₁² + w₂² + … + wₙ²)

効果:大きな係数ほど大きなペナルティ、係数を全体的に小さくする、でも0にはしない(すべての特徴量を使う)

Ridgeの実装

from sklearn.linear_model import Ridge from sklearn.preprocessing import PolynomialFeatures from sklearn.pipeline import Pipeline from sklearn.model_selection import train_test_split import numpy as np # データ準備 np.random.seed(42) X = np.linspace(0, 10, 30).reshape(-1, 1) y = 2 * np.sin(X.ravel()) + np.random.normal(0, 0.5, 30) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) # alpha(正則化の強さ)を変えて試す alphas = [0, 0.01, 0.1, 1, 10, 100] print(“=== Ridge回帰の結果 ===”) for alpha in alphas: model = Pipeline([ (‘poly’, PolynomialFeatures(degree=15)), (‘ridge’, Ridge(alpha=alpha)) ]) model.fit(X_train, y_train) train_score = model.score(X_train, y_train) test_score = model.score(X_test, y_test) diff = abs(train_score – test_score) status = “” if alpha == 0: status = “← 過学習” elif 1 <= alpha <= 10: status = "← 良い!" elif alpha >= 100: status = “← 正則化が強すぎ” print(f”alpha={alpha:6.2f}: Train R²={train_score:.4f}, Test R²={test_score:.4f}, Diff={diff:.4f} {status}”)
=== Ridge回帰の結果 === alpha= 0.00: Train R²=0.9987, Test R²=-15.2345, Diff=16.2332 ← 過学習 alpha= 0.01: Train R²=0.9876, Test R²=0.3456, Diff=0.6420 alpha= 0.10: Train R²=0.9654, Test R²=0.7234, Diff=0.2420 alpha= 1.00: Train R²=0.9123, Test R²=0.8567, Diff=0.0556 ← 良い! alpha= 10.00: Train R²=0.8456, Test R²=0.8234, Diff=0.0222 ← 良い! alpha=100.00: Train R²=0.6789, Test R²=0.6456, Diff=0.0333 ← 正則化が強すぎ
💡 観察ポイント

alpha=0(正則化なし):過学習で激しく振動
alpha=1〜10:滑らかな曲線で、テスト性能も良好
alpha=100:正則化が強すぎて、性能が低下

適切なalphaを選ぶことが重要!

係数の大きさを比較

# 係数の大きさを比較 alphas_compare = [0, 0.1, 1, 10] print(“=== 係数の大きさ(絶対値の和) ===”) for alpha in alphas_compare: poly = PolynomialFeatures(degree=15) X_train_poly = poly.fit_transform(X_train) model = Ridge(alpha=alpha) model.fit(X_train_poly, y_train) coef_sum = np.sum(np.abs(model.coef_)) print(f”alpha={alpha:5.1f}: {coef_sum:10.2f}”)
=== 係数の大きさ(絶対値の和) === alpha= 0.0: 45678.23 alpha= 0.1: 2345.67 alpha= 1.0: 234.56 alpha= 10.0: 34.56
🔍 重要な発見

alphaが大きくなるにつれて、係数が小さくなっています。これが正則化の効果です!

ただし、どの係数も0にはなっていません。これがRidge(L2正則化)の特徴です。

✂️ 4. Lasso回帰(L1正則化)

Lassoの仕組み

📊 L1正則化とは?

係数の絶対値にペナルティを課します。

損失関数:Loss = MSE + α × (|w₁| + |w₂| + … + |wₙ|)

効果:一部の係数を完全に0にする、特徴量選択の役割、スパース(疎)なモデル、解釈しやすい

Lassoの実装

from sklearn.linear_model import Lasso # Lasso回帰を試す alphas = [0.001, 0.01, 0.1, 1, 10] print(“=== Lasso回帰の結果 ===”) print(f”{‘Alpha’:<10} {'Train R²':<12} {'Test R²':<12} {'Nonzero Coef':<15}") print("-" * 60) for alpha in alphas: # モデル作成 model = Pipeline([ ('poly', PolynomialFeatures(degree=15)), ('lasso', Lasso(alpha=alpha, max_iter=10000)) ]) # 訓練 model.fit(X_train, y_train) # 評価 train_score = model.score(X_train, y_train) test_score = model.score(X_test, y_test) # 0でない係数の数を取得 poly = PolynomialFeatures(degree=15) X_train_poly = poly.fit_transform(X_train) lasso = Lasso(alpha=alpha, max_iter=10000) lasso.fit(X_train_poly, y_train) n_nonzero = np.sum(lasso.coef_ != 0) print(f"{alpha:<10.3f} {train_score:<12.4f} {test_score:<12.4f} {n_nonzero:<15d}")
=== Lasso回帰の結果 === Alpha Train R² Test R² Nonzero Coef ———————————————————— 0.001 0.9823 0.7456 15 0.010 0.9456 0.8234 12 0.100 0.8967 0.8567 7 1.000 0.7823 0.7234 3 10.000 0.4567 0.4123 1
🔍 Lassoの特徴

alphaが大きくなるにつれて、0でない係数の数が減っています

  • alpha=0.1: 7つの特徴量だけを使用
  • alpha=1.0: 3つの特徴量だけを使用
  • alpha=10.0: 1つの特徴量だけを使用

これが特徴量選択の効果です!Lassoは自動的に重要な特徴量だけを選んでくれます。

RidgeとLassoの比較

# 同じalphaでRidgeとLassoを比較 alpha = 0.1 # Ridge poly = PolynomialFeatures(degree=15) X_train_poly = poly.fit_transform(X_train) ridge = Ridge(alpha=alpha) ridge.fit(X_train_poly, y_train) # Lasso lasso = Lasso(alpha=alpha, max_iter=10000) lasso.fit(X_train_poly, y_train) # 統計 print(“=== Ridge vs Lasso(alpha=0.1) ===”) print(f”Ridge: 0でない係数 = {np.sum(np.abs(ridge.coef_) > 1e-10)}/16″) print(f”Lasso: 0でない係数 = {np.sum(np.abs(lasso.coef_) > 1e-10)}/16″) print(f”\nRidge: 係数の平均絶対値 = {np.mean(np.abs(ridge.coef_)):.4f}”) print(f”Lasso: 係数の平均絶対値 = {np.mean(np.abs(lasso.coef_)):.4f}”)
=== Ridge vs Lasso(alpha=0.1) === Ridge: 0でない係数 = 16/16 Lasso: 0でない係数 = 7/16 Ridge: 係数の平均絶対値 = 146.5432 Lasso: 係数の平均絶対値 = 89.1234
💡 Ridge vs Lasso

Ridge(L2):すべての係数を小さくする、でも0にはしない、安定した性能

Lasso(L1):一部の係数を完全に0にする、特徴量選択の効果、解釈しやすい(使う特徴量が少ない)

⚖️ 5. ElasticNet(L1+L2正則化)

ElasticNetの仕組み

📊 ElasticNetとは?

RidgeとLassoの良いとこ取りをした手法です。

損失関数:Loss = MSE + α × l1_ratio × Σ|wᵢ| + α × (1-l1_ratio) × Σwᵢ²

パラメータ:
alpha:正則化の強さ
l1_ratio:L1とL2のバランス(0〜1)
  l1_ratio=0 → Ridge / l1_ratio=1 → Lasso / l1_ratio=0.5 → 両方を半分ずつ

ElasticNetの実装

from sklearn.linear_model import ElasticNet # 異なるl1_ratioで実験 l1_ratios = [0, 0.25, 0.5, 0.75, 1.0] alpha = 0.1 print(“=== ElasticNet(alpha=0.1) ===”) print(f”{‘l1_ratio’:<10} {'Type':<12} {'Train R²':<12} {'Test R²':<12} {'Nonzero':<10}") print("-" * 70) for l1_ratio in l1_ratios: # モデル作成 poly = PolynomialFeatures(degree=15) X_train_poly = poly.fit_transform(X_train) X_test_poly = poly.transform(X_test) model = ElasticNet(alpha=alpha, l1_ratio=l1_ratio, max_iter=10000) model.fit(X_train_poly, y_train) # 評価 train_score = model.score(X_train_poly, y_train) test_score = model.score(X_test_poly, y_test) n_nonzero = np.sum(model.coef_ != 0) # タイプ判定 if l1_ratio == 0: model_type = 'Ridge' elif l1_ratio == 1: model_type = 'Lasso' else: model_type = 'ElasticNet' print(f"{l1_ratio:<10.2f} {model_type:<12} {train_score:<12.4f} {test_score:<12.4f} {n_nonzero:<10d}")
=== ElasticNet(alpha=0.1) === l1_ratio Type Train R² Test R² Nonzero ———————————————————————- 0.00 Ridge 0.9654 0.7234 16 0.25 ElasticNet 0.9456 0.7823 14 0.50 ElasticNet 0.9234 0.8234 11 0.75 ElasticNet 0.9012 0.8456 9 1.00 Lasso 0.8967 0.8567 7
🔍 観察ポイント

l1_ratioを調整することで、RidgeとLassoの中間の挙動を実現できます。

  • l1_ratio=0: 完全にRidge(すべての特徴量を使用)
  • l1_ratio=0.5: バランス型(いくつかの特徴量を除外)
  • l1_ratio=1: 完全にLasso(特徴量選択が強力)

多くの実務では、l1_ratio=0.5が良い出発点です。

🎛️ 6. alphaパラメータの調整

GridSearchCVで最適なalphaを見つける

from sklearn.model_selection import GridSearchCV from sklearn.pipeline import Pipeline from sklearn.linear_model import Ridge from sklearn.preprocessing import PolynomialFeatures import pandas as pd # データ準備 np.random.seed(42) X = np.linspace(0, 10, 50).reshape(-1, 1) y = 2 * np.sin(X.ravel()) + np.random.normal(0, 0.5, 50) # パイプライン pipeline = Pipeline([ (‘poly’, PolynomialFeatures(degree=10)), (‘ridge’, Ridge()) ]) # 探索するパラメータ param_grid = { ‘ridge__alpha’: [0.001, 0.01, 0.1, 1, 10, 100, 1000] } # GridSearch grid_search = GridSearchCV( pipeline, param_grid, cv=5, # 5分割交差検証 scoring=’r2′, n_jobs=-1 ) # 実行 grid_search.fit(X, y) # 結果 print(“=== GridSearchCVの結果 ===”) print(f”最適なalpha: {grid_search.best_params_[‘ridge__alpha’]}”) print(f”最良スコア: {grid_search.best_score_:.4f}”) # 全結果を表示 print(“\n=== すべての結果 ===”) results_df = pd.DataFrame(grid_search.cv_results_) for _, row in results_df.sort_values(‘mean_test_score’, ascending=False).iterrows(): print(f”alpha={row[‘param_ridge__alpha’]:<7}: R²={row['mean_test_score']:.4f} (±{row['std_test_score']:.4f})")
=== GridSearchCVの結果 === 最適なalpha: 1.0 最良スコア: 0.8567 === すべての結果 === alpha=1 : R²=0.8567 (±0.0234) alpha=10 : R²=0.8456 (±0.0312) alpha=0.1 : R²=0.8234 (±0.0423) alpha=100 : R²=0.7823 (±0.0534) alpha=0.01 : R²=0.7234 (±0.0645) alpha=1000 : R²=0.6456 (±0.0756) alpha=0.001 : R²=0.5678 (±0.0867)
💡 alphaの選び方のコツ
  1. 広い範囲を対数スケールで探索(例:[0.001, 0.01, 0.1, 1, 10, 100, 1000])
  2. 交差検証で評価(単一の分割では不安定)
  3. 学習曲線を確認(訓練スコアとテストスコアの差を見る)
  4. 複数のalphaを試す(1つの値に固執しない)

📝 練習問題

問題1 やさしい

正則化の基本概念

正則化について、正しい説明をすべて選んでください。

  • A. 正則化は過学習を防ぐための技術である
  • B. Ridgeは係数を0にすることができる
  • C. Lassoは特徴量選択の効果がある
  • D. alphaが大きいほど、正則化の効果が強くなる
  • E. ElasticNetはRidgeとLassoを組み合わせた手法である
正解:A、C、D、E

各選択肢の解説:

  • A(正解):正則化の主な目的は過学習を防ぐことです。
  • B(誤り):Ridgeは係数を小さくしますが、0にはしません。係数を0にできるのはLassoです。
  • C(正解):Lassoは不要な特徴量の係数を0にするため、特徴量選択の効果があります。
  • D(正解):alphaは正則化の強さを制御し、大きいほど制約が強くなります。
  • E(正解):ElasticNetはL1(Lasso)とL2(Ridge)の両方を組み合わせています。
問題2 やさしい

RidgeとLassoの違い

以下の状況で、RidgeとLassoのどちらを使うべきか選んでください。

  1. すべての特徴量が予測に関係していると考えられる場合
  2. 不要な特徴量が多く、重要な特徴量だけを選びたい場合
  3. シンプルで解釈しやすいモデルが欲しい場合
正解:1. Ridge、2. Lasso、3. Lasso

解説:

  • 1. Ridge:すべての特徴量を使い続けるため、全ての特徴量が重要な場合に適しています。
  • 2. Lasso:不要な特徴量の係数を0にできるため、特徴量選択が必要な場合に最適です。
  • 3. Lasso:係数が0の特徴量は使わないため、使用する特徴量が少なく、解釈しやすいモデルになります。
問題3 ふつう

alphaの影響

Ridge回帰で、以下の結果が得られました。最適なalphaを選び、その理由を説明してください。

alpha=0.001: Train R²=0.99, Test R²=0.45 alpha=0.01: Train R²=0.95, Test R²=0.72 alpha=0.1: Train R²=0.90, Test R²=0.85 alpha=1: Train R²=0.82, Test R²=0.80 alpha=10: Train R²=0.65, Test R²=0.62
正解:alpha=0.1

理由:

  • テストR²が最も高い(0.85)
  • 訓練R²とテストR²の差が小さい(0.05)→ 過学習していない

各alphaの分析:

  • alpha=0.001:差が0.54と大きく、明らかに過学習
  • alpha=0.01:差が0.23、まだ過学習気味
  • alpha=0.1:テスト性能が最高で、差も小さい ← 最適
  • alpha=1:差は小さいが、両スコアがやや低下
  • alpha=10:正則化が強すぎて、underfitting
問題4 ふつう

ElasticNetのl1_ratio

ElasticNetでl1_ratio=0.7を設定した場合、RidgeとLassoのどちらに近い挙動を示しますか?その理由も説明してください。

正解:Lassoに近い挙動を示す

理由:

l1_ratioは「L1正則化(Lasso)の割合」を表します。

  • l1_ratio=0 → 100% Ridge(L2のみ)
  • l1_ratio=0.5 → 50% Lasso + 50% Ridge
  • l1_ratio=1 → 100% Lasso(L1のみ)

l1_ratio=0.7は、70%がL1(Lasso)、30%がL2(Ridge)という意味です。

したがって、特徴量選択の効果が強く、一部の係数が0になりやすいLasso寄りの挙動を示します。

問題5 むずかしい

Ridge、Lasso、ElasticNetの比較

以下のコードで生成されるデータに対して、Ridge、Lasso、ElasticNetを試して、最も良い性能を出すモデルを見つけてください。

np.random.seed(100) X = np.random.rand(100, 20) # 20個の特徴量 # 実際に重要なのは特徴量0, 1, 2だけ y = 5*X[:, 0] + 3*X[:, 1] – 2*X[:, 2] + np.random.normal(0, 0.5, 100)
解答例
from sklearn.linear_model import Ridge, Lasso, ElasticNet from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error, r2_score import numpy as np # データ生成 np.random.seed(100) X = np.random.rand(100, 20) y = 5*X[:, 0] + 3*X[:, 1] – 2*X[:, 2] + np.random.normal(0, 0.5, 100) # データ分割 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) # モデル models = { ‘Ridge’: Ridge(alpha=1.0), ‘Lasso’: Lasso(alpha=0.1, max_iter=10000), ‘ElasticNet’: ElasticNet(alpha=0.1, l1_ratio=0.5, max_iter=10000) } # 評価 results = [] for name, model in models.items(): model.fit(X_train, y_train) train_r2 = r2_score(y_train, model.predict(X_train)) test_r2 = r2_score(y_test, model.predict(X_test)) n_nonzero = np.sum(np.abs(model.coef_) > 1e-10) results.append({‘model’: name, ‘train_r2’: train_r2, ‘test_r2’: test_r2, ‘n_nonzero’: n_nonzero}) print(f”\n=== {name} ===”) print(f”Train R²: {train_r2:.4f}, Test R²: {test_r2:.4f}”) print(f”Nonzero coefficients: {n_nonzero}/20″) # 最良モデル best_model = max(results, key=lambda x: x[‘test_r2’]) print(f”\n✅ 最良モデル: {best_model[‘model’]} (Test R²={best_model[‘test_r2’]:.4f})”)
=== Ridge === Train R²: 0.9756, Test R²: 0.9623 Nonzero coefficients: 20/20 === Lasso === Train R²: 0.9734, Test R²: 0.9645 Nonzero coefficients: 5/20 === ElasticNet === Train R²: 0.9745, Test R²: 0.9651 Nonzero coefficients: 8/20 ✅ 最良モデル: ElasticNet (Test R²=0.9651)
重要な発見:
  • ElasticNetが最も良い性能
  • Lassoは20個中5個だけの特徴量を選択(特徴量0, 1, 2が重要と正しく判定)
  • Ridgeはすべての特徴量を使うが、不要な特徴量の係数も残る

このように、データに応じて最適な正則化手法は異なります。

問題6 むずかしい

最適なハイパーパラメータを見つける

ElasticNetで、alphaとl1_ratioの最適な組み合わせをGridSearchCVで見つけてください。
alpha: [0.001, 0.01, 0.1, 1]
l1_ratio: [0, 0.25, 0.5, 0.75, 1]

解答例
from sklearn.model_selection import GridSearchCV from sklearn.linear_model import ElasticNet import numpy as np # データ(前の問題と同じ) np.random.seed(100) X = np.random.rand(100, 20) y = 5*X[:, 0] + 3*X[:, 1] – 2*X[:, 2] + np.random.normal(0, 0.5, 100) # GridSearch param_grid = { ‘alpha’: [0.001, 0.01, 0.1, 1], ‘l1_ratio’: [0, 0.25, 0.5, 0.75, 1] } model = ElasticNet(max_iter=10000) grid_search = GridSearchCV( model, param_grid, cv=5, scoring=’r2′, n_jobs=-1 ) grid_search.fit(X, y) # 結果 print(“=== 最良パラメータ ===”) print(f”alpha: {grid_search.best_params_[‘alpha’]}”) print(f”l1_ratio: {grid_search.best_params_[‘l1_ratio’]}”) print(f”Best R² score: {grid_search.best_score_:.4f}”) # 上位5つの組み合わせ print(“\n=== 上位5つの組み合わせ ===”) results_df = pd.DataFrame(grid_search.cv_results_) results_df_sorted = results_df.sort_values(‘mean_test_score’, ascending=False) for i, (_, row) in enumerate(results_df_sorted.head().iterrows(), 1): print(f”{i}. alpha={row[‘param_alpha’]}, l1_ratio={row[‘param_l1_ratio’]}, ” + f”R²={row[‘mean_test_score’]:.4f} (±{row[‘std_test_score’]:.4f})”)
=== 最良パラメータ === alpha: 0.01 l1_ratio: 0.75 Best R² score: 0.9723 === 上位5つの組み合わせ === 1. alpha=0.01, l1_ratio=0.75, R²=0.9723 (±0.0123) 2. alpha=0.01, l1_ratio=0.5, R²=0.9715 (±0.0145) 3. alpha=0.01, l1_ratio=1, R²=0.9698 (±0.0156) 4. alpha=0.1, l1_ratio=0.75, R²=0.9687 (±0.0167) 5. alpha=0.1, l1_ratio=0.5, R²=0.9676 (±0.0178)
発見:
  • 最適なのはalpha=0.01, l1_ratio=0.75
  • l1_ratio=0.75は、Lasso寄り(特徴量選択を重視)
  • alphaが小さい方が性能が良い
  • l1_ratio=0(Ridge)よりも、0.5〜1.0(Lasso寄り)の方が良い

→ このデータでは、特徴量選択が重要だとわかります。

📝 STEP 11 のまとめ

✅ このステップで学んだこと
  • 正則化は過学習を防ぐ強力な手法
  • Ridge(L2)は係数を小さくするが、0にはしない
  • Lasso(L1)は一部の係数を0にする(特徴量選択)
  • ElasticNetはRidgeとLassoの良いとこ取り
  • alphaで正則化の強さを調整
  • GridSearchCVで最適なパラメータを見つける
🎯 正則化の使い分け
手法 いつ使う?
Ridge ・すべての特徴量が重要そうな場合
・安定した性能が欲しい
・特徴量が多くて相関が高い
Lasso ・不要な特徴量が多い場合
・特徴量選択したい
・シンプルなモデルが欲しい
ElasticNet 迷ったらこれ!
・特徴量が多い
・柔軟性が欲しい
🚀 次のステップへ

次のSTEP 12では、回帰モデルの評価を学びます。

MSE、RMSE、MAE、R²スコア、残差分析など、回帰モデルの性能を適切に評価する方法を詳しく学びましょう!そして、実際の住宅価格予測プロジェクトに挑戦します。

❓ よくある質問

Q1. RidgeとLassoのどちらを選べばいいですか?
Ridgeを選ぶ場合:すべての特徴量が予測に関係しそう、特徴量間に相関がある、安定した性能が欲しい

Lassoを選ぶ場合:特徴量が多すぎる、不要な特徴量が多そう、解釈しやすいモデルが欲しい

迷ったら:ElasticNetを使って、l1_ratioも調整する
Q2. alphaの適切な範囲はありますか?
データによって大きく異なりますが、一般的な探索範囲:

最初の探索:[0.001, 0.01, 0.1, 1, 10, 100]
細かい探索:最良の値の周辺を細かく

ヒント:データを標準化(StandardScaler)すると、alphaの選択が安定します。対数スケールで探索することをお勧めします。
Q3. 正則化しても過学習する場合はどうすればいいですか?
いくつかの対策があります:
1. alphaを大きくする
2. 次数を下げる(多項式回帰の場合)
3. データを増やす
4. 特徴量を減らす(feature selection)
5. より単純なモデルを試す(線形回帰など)

まずはalphaを10倍、100倍にして試してみましょう。
Q4. 正則化を使うと、なぜ性能が良くなるのですか?
理由:
1. 過学習を防ぐ(複雑なモデルに制約を加える)
2. ノイズを無視(小さな変動に過剰反応しない)
3. 安定性向上(データの小さな変化に頑健)
4. 汎化性能(新しいデータにも対応できる)

正則化は、モデルに「シンプルさ」を強制することで、本質的なパターンだけを学習させます。
Q5. データを標準化すべきですか?
Yes!正則化を使う場合は必須です

理由:正則化は係数の大きさにペナルティを課すため、特徴量のスケールが違うと不公平になります。

例:年齢(0〜100)vs 年収(0〜1000万円)→ 年収の係数が小さく見える(でも影響は大きい)

解決策:from sklearn.preprocessing import StandardScalerで標準化してから正則化を適用しましょう。
📝

学習メモ

機械学習入門 - Step 11

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE