K_DM Book
用語集
対象者 標準
対象者別の入口 →

対象者の設定はこのブラウザの中にだけ保存されます。

言語 JA

リッジ・ラッソ

中級

02.1.2

リッジ・ラッソ

最終更新 2020-02-12 読了時間 4 分
まとめ
リッジ回帰とラッソ回帰は、最小二乗法の残差二乗和に「係数が大きいほど増える罰則」を足して、係数が暴れるのを防ぐ線形回帰です。リッジは係数の 2 乗和(L2)を罰するので全部の係数をなだらかに縮め、ラッソは絶対値の和(L1)を罰するので不要な係数をちょうど 0 にして特徴量選択を兼ねます。罰則の強さ \(\alpha\) は RidgeCV / LassoCV が交差検証で選びます。このページでは 10 特徴量のうち 3 つだけが効く 200 件の人工データで、線形回帰・リッジ・ラッソの係数を棒グラフで並べ、\(\alpha\) を動かした正則化パスで両者の縮み方の違いを見ます。

先に 線形回帰 で最小二乗法が残差二乗和だけを最小にしていることを確認しておくと、このページで足すのが「罰則の項 1 つ」だけだと分かります。

直感 #

10 個の特徴量で 200 件を説明する最小二乗法は、本当は効かない 7 個の列にも小さな係数を付けます。説明変数どうしの相関が強いと、片方に +10、もう片方に −9 のような打ち消し合う係数が出ます。データが少し変わるだけで符号が入れ替わることもあります。リッジ回帰とラッソ回帰は、残差二乗和に \(\alpha \times\) 罰則を足し、「当てはまりを少し犠牲にしてでも係数を小さく保つ」方向に解をずらします。リッジは 10 本の係数すべてを比例的に縮め、ラッソは小さい係数から順にちょうど 0 にするので、下の棒グラフでは青→橙→緑の順に棒が低くなり、緑だけ消える棒が出ます。

flowchart LR A["入力データX, y"] --> B["SSE\n残差二乗和"] B --> C{"正則化の種類"} C -->|L2| D["リッジ\n係数を縮小"] C -->|L1| E["ラッソ\n係数を0に"] D --> F["安定した\n係数推定"] E --> F style A fill:#2563eb,color:#fff style C fill:#1e40af,color:#fff style F fill:#10b981,color:#fff

何が起きているか(ステップで見る) #

コードを読む前に、この手法が図の上で何をしているかを追ってみましょう。「再生」を押すか、スライダーを動かすと 1 手順ずつ進みます。

見るポイント:罰則 α を強めるほど係数が縮み、曲線が暴れなくなる。強すぎると当てはまりが悪くなる。下のコードでは、この α を RidgeCV と LassoCV が 5 分割交差検証で自動的に選びます。

式で書くと何を足しているか #

どちらも第 1 項は最小二乗法と同じ残差二乗和で、違いは第 2 項の罰則の測り方だけです。リッジ回帰は係数の 2 乗和 \(\lVert \boldsymbol\beta \rVert_2^2\) を罰します。

$$ \min_{\boldsymbol\beta, b} \sum_{i=1}^{n} \left(y_i - (\boldsymbol\beta^\top \mathbf{x}_i + b)\right)^2 + \alpha \lVert \boldsymbol\beta \rVert_2^2 $$

ラッソ回帰は係数の絶対値の和 \(\lVert \boldsymbol\beta \rVert_1\) を罰します。

$$ \min_{\boldsymbol\beta, b} \sum_{i=1}^{n} \left(y_i - (\boldsymbol\beta^\top \mathbf{x}_i + b)\right)^2 + \alpha \lVert \boldsymbol\beta \rVert_1 $$

\(\alpha\) を大きくすると係数はより強く抑えられ、\(\alpha = 0\) なら両方とも最小二乗法に戻ります。2 乗の罰則は係数が 0 に近づくほど弱くなるのでリッジの係数は 0 に届きませんが、絶対値の罰則は 0 の手前でも傾きが一定なので、ラッソでは \(\alpha\) がある閾値を超えた係数がちょうど 0 になります。

Pythonを用いた実験や説明 #

次のコードは、10 個の特徴量のうち先頭 3 個だけに係数 3 前後を置いた 200 件のデータを作り、線形回帰・RidgeCV・LassoCV の 3 モデルを同じ標準化パイプラインで学習します。係数の絶対値を 10 本の棒で並べ、最後に 5 分割交差検証の R² を印字して汎化性能を比べます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import Lasso, LassoCV, LinearRegression, Ridge, RidgeCV
from sklearn.model_selection import cross_val_score
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

# パラメータ
n_samples = 200
n_features = 10
n_informative = 3
rng = np.random.default_rng(42)

# 真の重み(スパース)
coef = np.zeros(n_features)
coef[:n_informative] = rng.normal(loc=3.0, scale=1.0, size=n_informative)

# 説明変数と目的変数を生成
X = rng.normal(size=(n_samples, n_features))
y = X @ coef + rng.normal(scale=5.0, size=n_samples)

# 各モデルを作成・学習
# with_mean=False にしているのは疎行列対応の書き方の名残かも
linear = make_pipeline(
    StandardScaler(with_mean=False),
    LinearRegression()
).fit(X, y)

ridge = make_pipeline(
    StandardScaler(with_mean=False),
    RidgeCV(alphas=np.logspace(-3, 3, 13), cv=5)
).fit(X, y)

lasso = make_pipeline(
    StandardScaler(with_mean=False),
    LassoCV(alphas=np.logspace(-3, 1, 9), cv=5, max_iter=50_000)
).fit(X, y)

models = {
    "Linear": linear,
    "Ridge": ridge,
    "Lasso": lasso,
}

# 係数の比較可視化
indices = np.arange(n_features)
width = 0.25
plt.figure(figsize=(10, 4))
plt.bar(indices - width, np.abs(linear[-1].coef_), width=width, label="Linear")
plt.bar(indices,         np.abs(ridge[-1].coef_),  width=width, label="Ridge")
plt.bar(indices + width, np.abs(lasso[-1].coef_),  width=width, label="Lasso")
plt.xlabel("特徴量インデックス")
plt.ylabel("|係数|")
plt.legend()
plt.grid(alpha=0.3)
plt.tight_layout()
plt.show()

# 汎化性能のスコア
for name, model in models.items():
    scores = cross_val_score(model, X, y, cv=5, scoring="r2")
    print(f"{name:>6}: R^2 = {scores.mean():.3f} ± {scores.std():.3f}")

係数の比較:Linear vs Ridge vs Lasso

実行結果の読み方 #

インデックス 0〜2 の 3 本は 3 色とも高く立ち、青(Linear)より橙(Ridge)が少し低く、緑(Lasso)はさらに少し低くなります。これが罰則による縮みです。インデックス 3〜9 では青に小さな棒が残り、橙はそれを縮め、緑は多くが消えて 0 になります。印字される 5 分割交差検証の R² は 3 手法で大きく違わないので、正則化の効果は「精度を上げる」より「不要な係数を消して解釈しやすくし、データが変わっても係数が安定する」点にあると読んでください。

正則化パスの可視化 #

\(\alpha\) を変化させたときの係数の軌跡を正則化パスと呼びます。リッジでは係数が滑らかに 0 に近づき、ラッソではある閾値で急に 0 になる様子が確認できます。

正則化パス:Ridge vs Lasso

リッジ回帰とラッソ回帰は特徴量のスケールに敏感です。標準化(StandardScaler)を適用せずに学習すると、スケールの大きい特徴量が過剰にペナルティを受け、正しい係数推定ができません。必ずパイプラインに標準化を含めてください。

リッジとラッソの使い分けに迷ったら、RidgeCVとLassoCVの両方を試して交差検証スコアを比較してください。特徴量が多く不要な変数が含まれている場合はラッソ、多重共線性が疑われる場合はリッジが有効です。両方の性質が欲しい場合はElastic Netを検討してください。

正則化係数と回帰曲線 #

スライダーで正則化係数 α を 0.01 から 100 まで変えると、多項式の回帰曲線が暴れた形から平らな形へ縮んでいく様子を確認できます。

Ridge の係数パス #

スライダーで正則化係数 α を大きくすると、10 本の係数がなだらかな曲線で 0 に近づいていきます。ラッソのようにぴたりと 0 に張り付く線がないことを確認してください。

まとめ #

リッジ回帰は L2 罰則で 10 本の係数をすべてなだらかに縮め、説明変数どうしの相関が強くても符号が入れ替わらない安定した推定を返します。ラッソ回帰は L1 罰則で不要な 7 本の係数をちょうど 0 にするので、特徴量選択とモデルの解釈を兼ねられます。罰則の強さ \(\alpha\) は RidgeCV / LassoCV に対数刻みの候補を渡して交差検証で選ぶのが実務の定番で、StandardScaler を make_pipeline に組み込まないと分散の大きい列だけ罰則が弱くなります。相関の強い列をグループで残したいときは、両方の罰則を混ぜた Elastic Net に進んでください。

参考文献 #

  • Hoerl, A. E., & Kennard, R. W. (1970). Ridge Regression: Biased Estimation for Nonorthogonal Problems. Technometrics, 12(1), 55–67.
  • Tibshirani, R. (1996). Regression Shrinkage and Selection via the Lasso. Journal of the Royal Statistical Society: Series B, 58(1), 267–288.
  • Zou, H., & Hastie, T. (2005). Regularization and Variable Selection via the Elastic Net. Journal of the Royal Statistical Society: Series B, 67(2), 301–320.