📋 このステップで学ぶこと
過学習とは何か(復習)
正則化の基本概念
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の選び方のコツ
広い範囲を対数スケールで探索 (例:[0.001, 0.01, 0.1, 1, 10, 100, 1000])
交差検証で評価 (単一の分割では不安定)
学習曲線を確認 (訓練スコアとテストスコアの差を見る)
複数の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. 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で標準化してから正則化を適用しましょう。
×
artnasekai
#artnasekai #学習メモ