Lasso回帰とElastic Netの理論 — スパース推定の数理

数百の特徴量を持つデータセットがあるとき、本当に予測に寄与しているのはそのうちの一部だけかもしれません。不要な特徴量をモデルに残すと、ノイズに適合して過学習するリスクがあります。では、重要な特徴量を自動的に選別する方法はないでしょうか。

Lasso回帰(Least Absolute Shrinkage and Selection Operator)は、L1正則化によりパラメータを正確に0にすることで特徴量選択を自動化する手法です。正則化の理論で基礎を学びましたが、本記事ではLassoの最適化アルゴリズム(座標降下法)、統計的性質、そしてElastic Netとの組み合わせをより深く掘り下げます。

Lasso/Elastic Netを深く理解すると、以下のような場面で活用できます。

  • 高次元データの回帰: 特徴量数 $p$ がサンプル数 $n$ を上回る場面
  • 解釈可能なモデル: 非零の係数のみで予測の根拠を説明
  • 変数選択: 統計モデリングにおける重要な変数の特定
  • 圧縮センシング: スパース信号の復元

本記事の内容

  • Lassoの最適化アルゴリズム(座標降下法)
  • ソフト閾値演算子の導出
  • Lassoの統計的性質(一致性、オラクル性質)
  • Elastic Netの理論と利点
  • Pythonでの実装と正則化パスの可視化

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が深まります。

座標降下法によるLassoの解法

なぜ勾配降下法が直接使えないか

Lasso の目的関数 $J(\bm{w}) = \frac{1}{2n}\|\bm{y} – \bm{X}\bm{w}\|^2 + \lambda\|\bm{w}\|_1$ はL1ノルムの原点で微分不可能です。劣勾配法は使えますが収束が遅いため、実用的には座標降下法(coordinate descent)が使われます。

座標降下法のアルゴリズム

座標降下法は、1つのパラメータ $w_j$ ずつ最適化を行い、他のパラメータは固定します。

$w_j$ 以外を固定したときの目的関数は

$$ J(w_j) = \frac{1}{2n}\sum_{i=1}^n \left(y_i – \sum_{k \neq j} x_{ik}w_k – x_{ij}w_j\right)^2 + \lambda|w_j| + \text{const} $$

部分残差 $r_j = y_i – \sum_{k \neq j} x_{ik}w_k$ を定義すると、$w_j$ に関する1次元の最適化になります。

解はソフト閾値演算子(soft thresholding operator)で与えられます。

$$ \begin{equation} w_j^* = S\left(\frac{\bm{x}_j^T\bm{r}_j}{n}, \lambda\right), \quad S(z, \lambda) = \text{sign}(z)\max(|z| – \lambda, 0) \end{equation} $$

ここで $\bm{x}_j$ は特徴量 $j$ のベクトルです(標準化済みと仮定、$\|\bm{x}_j\|^2/n = 1$)。

ソフト閾値演算子の直感

ソフト閾値演算子は3つの場合分けに対応します。

  • $z > \lambda$: $w_j^* = z – \lambda$(正の値を $\lambda$ だけ縮小)
  • $|z| \leq \lambda$: $w_j^* = 0$(0に設定 — 特徴量選択!)
  • $z < -\lambda$: $w_j^* = z + \lambda$(負の値を $\lambda$ だけ縮小)

OLS推定値の絶対値が $\lambda$ 以下の特徴量は0に「閾値処理」され、自動的にモデルから除外されます。

Lassoの統計的性質

Sign-consistency(符号一致性)

Lassoが真のスパースパターンを正確に回復する条件は、Irrepresentable condition(不可表現条件)として知られています。この条件が満たされるとき、$n \to \infty$ で Lassoの非零パラメータの集合が真の非零パラメータの集合に一致します(符号一致性)。

予測性能 vs 変数選択

重要な注意点として、Lassoの予測性能が良くても、変数選択が正確とは限りません。予測に最適な $\lambda$ と変数選択に最適な $\lambda$ は一般に異なります。

Elastic Netの詳細

Elastic Net の目的関数

$$ \begin{equation} J(\bm{w}) = \frac{1}{2n}\|\bm{y} – \bm{X}\bm{w}\|^2 + \lambda\left[\alpha\|\bm{w}\|_1 + \frac{1-\alpha}{2}\|\bm{w}\|_2^2\right] \end{equation} $$

座標降下法での更新

Elastic Netの座標降下法の更新は

$$ w_j^* = \frac{S(\bm{x}_j^T\bm{r}_j/n, \lambda\alpha)}{1 + \lambda(1-\alpha)} $$

L2項の効果で分母に $1 + \lambda(1-\alpha)$ が加わり、追加の縮小(shrinkage)が行われます。

Lassoに対するElastic Netの利点

  1. グループ効果: 相関の高い特徴量を同時に選択/除外する
  2. $p > n$ の処理: Lassoは最大 $n$ 個の特徴量しか選択できないが、Elastic Netにはこの制限がない
  3. 安定性: 相関した特徴量間での選択結果が安定
import numpy as np
import matplotlib.pyplot as plt

# ソフト閾値演算子
def soft_threshold(z, lam):
    return np.sign(z) * np.maximum(np.abs(z) - lam, 0)

# 座標降下法によるLasso
def lasso_coordinate_descent(X, y, lam, max_iter=1000, tol=1e-6):
    n, d = X.shape
    w = np.zeros(d)
    for iteration in range(max_iter):
        w_old = w.copy()
        for j in range(d):
            # 部分残差
            r_j = y - X @ w + X[:, j] * w[j]
            # 更新
            z_j = X[:, j] @ r_j / n
            w[j] = soft_threshold(z_j, lam)
        if np.max(np.abs(w - w_old)) < tol:
            break
    return w

# Elastic Net の座標降下法
def elastic_net_cd(X, y, lam, alpha=0.5, max_iter=1000, tol=1e-6):
    n, d = X.shape
    w = np.zeros(d)
    for iteration in range(max_iter):
        w_old = w.copy()
        for j in range(d):
            r_j = y - X @ w + X[:, j] * w[j]
            z_j = X[:, j] @ r_j / n
            w[j] = soft_threshold(z_j, lam * alpha) / (1 + lam * (1 - alpha))
        if np.max(np.abs(w - w_old)) < tol:
            break
    return w

# テストデータ
np.random.seed(42)
n, d = 200, 20
X = np.random.randn(n, d)
# 標準化
X = (X - X.mean(axis=0)) / X.std(axis=0)
w_true = np.zeros(d)
w_true[:5] = [3, -2, 1.5, -1, 0.8]
y = X @ w_true + np.random.randn(n) * 0.5
y = y - y.mean()

# 正則化パスの計算
lambdas = np.logspace(-4, 1, 80)

lasso_coefs = np.array([lasso_coordinate_descent(X, y, lam) for lam in lambdas])
en_coefs = np.array([elastic_net_cd(X, y, lam, alpha=0.5) for lam in lambdas])

fig, axes = plt.subplots(1, 3, figsize=(16, 5))

# (a) ソフト閾値演算子
ax = axes[0]
z = np.linspace(-3, 3, 500)
for lam_val, color in [(0.5, "blue"), (1.0, "green"), (1.5, "red")]:
    ax.plot(z, soft_threshold(z, lam_val), color=color, linewidth=2,
            label=f"$\\lambda={lam_val}$")
ax.plot(z, z, "k--", linewidth=1, alpha=0.5, label="Identity")
ax.set_xlabel("$z$ (OLS estimate)", fontsize=12)
ax.set_ylabel("$S(z, \\lambda)$", fontsize=12)
ax.set_title("Soft Thresholding Operator", fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3)

# (b) Lasso正則化パス
ax = axes[1]
for j in range(d):
    lw = 2 if j < 5 else 0.5
    alpha_val = 1.0 if j < 5 else 0.3
    ax.plot(lambdas, lasso_coefs[:, j], linewidth=lw, alpha=alpha_val)
ax.set_xscale("log")
ax.set_xlabel("$\\lambda$", fontsize=12)
ax.set_ylabel("Coefficient", fontsize=12)
ax.set_title("Lasso Regularization Path", fontsize=13)
ax.axhline(0, color="gray", linewidth=0.5)
ax.grid(True, alpha=0.3)

# (c) 非零係数の数
ax = axes[2]
n_nonzero_lasso = np.sum(np.abs(lasso_coefs) > 1e-8, axis=1)
n_nonzero_en = np.sum(np.abs(en_coefs) > 1e-8, axis=1)
ax.plot(lambdas, n_nonzero_lasso, "b-", linewidth=2, label="Lasso")
ax.plot(lambdas, n_nonzero_en, "r--", linewidth=2, label="Elastic Net ($\\alpha=0.5$)")
ax.axhline(5, color="green", linestyle=":", linewidth=2, label="True sparsity (5)")
ax.set_xscale("log")
ax.set_xlabel("$\\lambda$", fontsize=12)
ax.set_ylabel("Number of non-zero coefficients", fontsize=12)
ax.set_title("Sparsity vs $\\lambda$", fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig("lasso_elastic_net.png", dpi=150, bbox_inches="tight")
plt.show()

このグラフから、Lasso/Elastic Netの特性が読み取れます。

  1. 左図(ソフト閾値演算子): $\lambda$ が大きいほど広い範囲の値が0にクリップされます。恒等関数(点線)からの乖離が正則化の強さを表しています

  2. 中央図(正則化パス): $\lambda$ の増加とともに係数が順次0になっていきます。太い線(真に非零の5つの係数)が最後まで残り、細い線(ノイズ特徴量)が先に消えることで、特徴量選択が正しく機能していることが確認できます

  3. 右図(スパース性): $\lambda$ が増加するにつれて非零係数の数が減少し、適切な $\lambda$ で真のスパース性(5個)に一致する領域があります。Elastic Netは同じ $\lambda$ でLassoより多くの係数を保持する傾向があり、グループ効果を反映しています

まとめ

本記事では、Lasso回帰とElastic Netの理論を深く掘り下げました。

  • 座標降下法はLassoの標準的な最適化アルゴリズムで、ソフト閾値演算子により各係数を更新する
  • Lassoは正確な変数選択を行うが、Irrepresentable conditionが必要
  • Elastic NetはL1とL2を組み合わせ、Lassoのグループ効果不足と $p > n$ の制限を解消する
  • 正則化パラメータ $\lambda$ は交差検証で選択し、予測性能と変数選択性能は別の $\lambda$ で最適化されることがある

次のステップとして、以下の記事も参考にしてください。