線形回帰やロジスティック回帰は、症例数に対して説明変数が多いと、推定が不安定になりやすく、過学習のリスクが高まります。リハビリテーション研究では、100例前後のデータに対して、年齢、発症からの日数、FIM、麻痺の重症度、併存疾患など、多くの候補変数を扱うことがあります。このような状況で何も対策をしないままモデルを作ると、学習データでは良く見えても、別のデータでは性能が大きく落ちることがあります。そこで用いられる代表的な方法が正則化(regularization)です。正則化は、目的関数に係数の大きさに対するペナルティを加え、係数が過度に大きくなることを抑える方法です。本記事では、症例数が限られる医学研究でよく使われるLasso(L1)、Ridge(L2)、Elastic Net(L1+L2)の3手法を説明します[1]。
本記事は 第3部 医療AI・機械学習アルゴリズム図鑑 第3記事です。線形回帰(03·01)・ロジスティック回帰(03·02)の発展形として、過学習を構造的に防ぐ正則化を扱います。第2部「特徴量選択」(02·05)にも関連します。
// 01 · LEARN OUTCOMESこの記事でわかること
- L1(Lasso)が変数選択のように働き、L2(Ridge)が係数を縮小することを直感的に理解できる
- Lasso、Ridge、Elastic Netの違いを図で理解できる
- 正則化強度λやC、Elastic Netの混合比をCVで調整する考え方がわかる
- 研究目的に応じて Lasso / Ridge / Elastic Net を使い分ける目安がわかる
// 02 · CONCLUSIONまず結論
// 03 · FIGURE直感的な図解
正則化の核心は、「誤差を小さくしつつ、係数が大きくなりすぎないようにする」というバランスです。幾何学的に見ると、LassoとRidgeの違いが直感的に理解しやすくなります。
次に、正則化強度 λ を変えたときの係数パスを見てみます。Lasso と Ridge では、係数の小さくなり方が異なります。
最後に、3手法の使い分けを整理します。研究目的とデータの性質から考えると、選択の方針が見えやすくなります。
// 04 · CLINICAL医療・リハビリでの具体例
3手法は、リハビリ領域などの医学研究でも目的によって使い分けます。ポイントは、データの構造と研究で何を示したいかを分けて考えることです。
脳卒中後のリハ予後予測で、年齢、性別、FIM小項目、検査値、既往歴、社会的要因など、30個程度の説明変数の候補があるとします。症例数が200例程度の場合、通常の回帰モデルでは学習が不安定になることがあります。Lassoを使うと、一部の係数が0になり、候補変数を絞り込める可能性があります。ただし、残った変数をそのまま「臨床的に重要」と判断するのではなく、交差検証での安定性や臨床的妥当性もあわせて確認する必要があります。Lassoは臨床所見などの説明変数が多く、モデルを簡潔にしたい研究で有用です。
例えば、FIM小項目の13項目をすべて個別の説明変数として入れると、項目間の相関が強くなります。これを多重共線性と言います。この場合、Lassoでは相関する項目の一部だけが残り、他の項目の係数が0になる場合があります。臨床的にはどの項目にも意味があるため、機械的に切り捨てると臨床的な解釈が難しくなります。Ridgeを使うと、全項目を残したまま係数を縮小できるため、「変数を削らずに推定を安定させたい」場合に使えます。
年齢などの患者背景、麻痺の重症度、FIM小項目によるADL所見など、多数の説明変数を用いて、脳卒中の予後予測モデルを学習する場面を考えます。このような場面では、相関する特徴量が多く(FIM小項目はお互いに相関する)、かつ最終的には使いやすいモデルにしたい(変数の候補は減らしたい)という場面がよくあります。Elastic Netは、Lassoの変数選択に近い性質とRidgeの安定化の性質を併せ持つため、相関する特徴量を扱いながら、モデルをある程度コンパクトにしたい場合に使えます。混合比αと正則化強度λは、固定せずCVで決めるのが基本です。実際、脳卒中患者のFIM予後予測の研究でも、このElastic Netが採用されています[2]。
Lassoでは、相関する変数群のうち一部だけが残ることがあります。たとえば「FIM運動とFIM認知が相関しており、最終的にFIM運動だけが残った」という結果が出ても、「認知機能は予後と無関係」とは言えないことに注意が必要です。RidgeやElastic Net で再評価したり、bootstrapなどで選択の安定性を確認したり、臨床的な知識で結果を補うことが重要です[3]。
候補変数が多く、相関の強い変数も含まれる医学研究では、Elastic Net + 5-fold CV は現実的な選択肢になります。Lasso寄りにするか、Ridge寄りにするかを混合比αで調整できるため、データの構造に合わせやすいからです。scikit-learn の ElasticNetCV や LogisticRegressionCV(penalty="elasticnet") を使うと、λ と α を同時に探索できます。最初に Elastic Net で全体像を確認し、そのうえで LassoやRidge と比較すると、判断しやすくなります。
// 05 · THEORY数式・理論
3手法の数学的な考え方を、目的関数、係数の性質、ハイパーパラメータの3点から整理します。
目的関数
# 通常の線形回帰(OLS)
β̂ = argmin_β Σᵢ (yᵢ − xᵢᵀβ)²
↑
損失関数のみ
# Ridge 回帰(L2)
β̂ = argmin_β Σᵢ (yᵢ − xᵢᵀβ)² + λ · Σⱼ βⱼ²
↑
L2 正則化項
# Lasso 回帰(L1)
β̂ = argmin_β Σᵢ (yᵢ − xᵢᵀβ)² + λ · Σⱼ |βⱼ|
↑
L1 正則化項
# Elastic Net(L1+L2)
β̂ = argmin_β Σᵢ (yᵢ − xᵢᵀβ)²
+ λ · [α · Σ|βⱼ| + (1-α) · Σβⱼ²]
↑ ↑ ↑
正則化強度 L1 比率(α=1でLasso寄り) L2比率
# 注: 切片には通常、正則化ペナルティをかけない
なぜ L1 では係数が 0 になりやすいか
幾何学的には Fig.1 で説明しましたが、単純化した設定では解析的にも理解できます。
# 説明変数が標準化され、互いに直交している単純な設定で考える
z = 通常の最小二乗法で得られる係数
# Lasso の解: soft-thresholding
β̂_L1 = sign(z) · max(|z| − λ, 0)
# Ridge の解: shrinkage
β̂_L2 = z / (1 + λ)
# Lasso の性質
|z| が λ より小さいと β̂_L1 = 0
→ 小さい係数が 0 になり、変数選択のように働く
# Ridge の性質
β̂_L2 は z をなめらかに縮小する
→ 有限の λ では通常 0 にはならない
# 注: λ の係数や定数は、損失関数の定義によって変わる
このため、L1はソフト閾値処理(soft thresholding)、L2は縮小推定(shrinkage)として説明されることがあります[4]。
多重共線性での違い
# 完全に同じ2変数 x₁ = x₂ がある場合
# Lasso の挙動
→ 片方だけが残ったり、解が不安定になったりしやすい
→ どちらが残るかはデータの分割や数値計算に影響されることがある
# Ridge の挙動
→ 対称な条件では両方に近い係数が割り当てられる
→ 多重共線性がある場合でも推定が比較的安定しやすい
# Elastic Net の挙動
→ 相関する変数群をある程度残しながら、不要な係数を0にしやすい
→ Lasso と Ridge の中間的な性質を持つ
標準化の重要性
正則化は 係数の大きさ に罰則を加えるため、変数のスケールに敏感です。
# 例: 年齢(0〜100)と FIM(13〜91)
スケールなし:
年齢の係数 β_age ≈ 0.05(年齢1歳ごとの効果)
FIM の係数 β_fim ≈ 0.5(FIM 1点ごとの効果)
→ 変数の単位によって係数の大きさが変わる
→ 同じ正則化をかけても、罰則の効き方が不公平になる
標準化後(z-score):
両者とも「1標準偏差増えた効果」として比較可能
→ 正則化の効果をそろえやすい
正則化を使うときは、原則として StandardScaler などで標準化する
// 06 · IMPLEMENTATION · PYTHON実装
scikit-learn での実装例です。標準化をPipelineに含めたうえで、CVによりλと混合比αを最適化します。こうすることで、標準化や変数選択が評価データに漏れることを防ぎやすくなります。
import numpy as np
import pandas as pd
from sklearn.linear_model import (
Lasso, Ridge, ElasticNet,
LassoCV, RidgeCV, ElasticNetCV,
LogisticRegression
)
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV, train_test_split
df = pd.read_csv("rehab_cohort.csv")
# 回帰タスク: 退院時FIM運動項目を予測する例
X = df.drop(columns=["fim_motor_discharge", "walk_independent"], errors="ignore")
y_reg = df["fim_motor_discharge"]
X_train, X_test, y_train, y_test = train_test_split(
X, y_reg, test_size=0.2, random_state=42
)
# ============================================
# ① Lasso(L1):変数選択+回帰
# ============================================
lasso_pipe = Pipeline([
("scaler", StandardScaler()), # 必須
("lasso", LassoCV(
alphas=np.logspace(-3, 1, 50), # 50候補で探索
cv=5, max_iter=10000
)),
])
lasso_pipe.fit(X_train, y_train)
print(f"Best α (=λ): {lasso_pipe['lasso'].alpha_:.4f}")
# 0でない係数 = Lassoで残った変数
coef = lasso_pipe["lasso"].coef_
selected = X_train.columns[coef != 0]
print(f"Non-zero coefficients: {len(selected)} / {len(coef)} variables")
print(selected.tolist())
# ============================================
# ② Ridge(L2):全変数残しつつ縮小
# ============================================
ridge_pipe = Pipeline([
("scaler", StandardScaler()),
("ridge", RidgeCV(alphas=np.logspace(-3, 3, 50), cv=5)),
])
ridge_pipe.fit(X_train, y_train)
print(f"Best α: {ridge_pipe['ridge'].alpha_:.4f}")
# 全変数の係数を確認
ridge_coef = pd.Series(
ridge_pipe["ridge"].coef_, index=X_train.columns
).sort_values(key=lambda s: s.abs(), ascending=False)
print(ridge_coef.head(10))
# ============================================
# ③ Elastic Net:両方の特性
# ============================================
enet_pipe = Pipeline([
("scaler", StandardScaler()),
("enet", ElasticNetCV(
l1_ratio=[0.1, 0.3, 0.5, 0.7, 0.9, 1.0], # α(L1比率)
alphas=np.logspace(-3, 1, 30),
cv=5, max_iter=10000
)),
])
enet_pipe.fit(X_train, y_train)
print(f"Best l1_ratio: {enet_pipe['enet'].l1_ratio_}")
print(f"Best α: {enet_pipe['enet'].alpha_:.4f}")
# ============================================
# ④ ロジスティック回帰での正則化(分類タスク)
# ============================================
# 例: 退院時歩行自立の有無を予測する場合
# scikit-learn の LogisticRegression は C = 1/λ
y_clf = df["walk_independent"] # 0/1 の二値アウトカムを想定
X_train_c, X_test_c, y_train_c, y_test_c = train_test_split(
X, y_clf, test_size=0.2, random_state=42, stratify=y_clf
)
log_pipe = Pipeline([
("scaler", StandardScaler()),
("clf", LogisticRegression(
penalty="elasticnet",
l1_ratio=0.5,
solver="saga", # elasticnet には saga が必要
C=0.1, # C が小さいほど正則化が強い
max_iter=10000
)),
])
# CV で C と l1_ratio をチューニング
param_grid = {
"clf__C": np.logspace(-2, 2, 10),
"clf__l1_ratio": [0.1, 0.5, 0.9],
}
log_grid = GridSearchCV(log_pipe, param_grid, cv=5, scoring="roc_auc")
log_grid.fit(X_train_c, y_train_c)
print(f"Best params: {log_grid.best_params_}")
# ============================================
# ⑤ 性能比較(同じデータで3モデル)
# ============================================
from sklearn.metrics import r2_score, mean_squared_error
models = {
"Lasso": lasso_pipe,
"Ridge": ridge_pipe,
"ElasticNet": enet_pipe,
}
for name, model in models.items():
y_pred = model.predict(X_test)
print(f"{name:12} R²: {r2_score(y_test, y_pred):.3f} "
f"RMSE: {np.sqrt(mean_squared_error(y_test, y_pred)):.2f}")
重要: scikit-learn の LogisticRegression ではハイパーパラメータが C = 1/λ なので注意します。C が小さいほど正則化は強くなります。一方、Lasso、Ridge、ElasticNet では alpha が正則化強度に相当し、alpha が大きいほど正則化が強くなります。同じ「α」という記号でも、Elastic Netの混合比 l1_ratio とは別物です[5]。
// 07 · MYTHSよくある誤解
- Lasso で選ばれなかった変数は「関係ない」変数
- 誤りです。Lassoでは、相関する変数群のうち一部だけが残ることがあります。しかし、残らなかった変数にも臨床的な関連がある可能性があります。Ridge・Elastic Net・ドメイン知識・bootstrapによる安定性確認を組み合わせて総合的に判断してください。
- 正則化は標準化なしでも使える
- 誤りです。正則化は係数の大きさに罰則をかけるため、変数の単位やスケールの影響を受けます。そのため、年齢、FIM、検査値のように単位が異なる変数を同時に扱う場合は、原則として StandardScaler などで標準化してから適用する必要があります。
- 正則化を強くするほど、外部検証性能が上がる
- 誤りです。λ には適切な範囲があります。弱すぎると過学習、強すぎるとunder-fitting になり、どちらも予測性能の低下につながります。CV で λ を最適化し、必要に応じて外部検証で確認する必要があります。
- Lasso の選択結果は「再現性のある変数選択」
- 不正確です。Lassoはサンプリングに敏感で、訓練データの分割が少し変わるだけで選ばれる変数が変わることがあります。安定性を示したい場合は、stability selection や bootstrap で、どの変数がどの程度の頻度で選ばれるかを確認します[6]。
// 08 · WRITING論文での書き方
Methods に記述すべき項目
- 選択した正則化手法(Lasso / Ridge / Elastic Net)とその理由
- 標準化を行ったこと(StandardScaler等)
- ハイパーパラメータ(λ、α)の最適化方法(CV、grid search)
- 探索した範囲(例: λ ∈ [10⁻³, 10¹] を 50 点で探索)
- 最終的な λ と選ばれた変数のリスト(Supplementary)
- ハイパーパラメータ選択や変数選択をCVの各fold内で行ったか(リーケージ防止)
Methodsの書き方の例
"To address potential overfitting given the moderate sample size
(N=210) relative to the number of candidate predictors (n=28), we
applied L1-regularized logistic regression (Lasso). Predictors
were standardized to zero mean and unit variance using
StandardScaler fit only on the training fold. The regularization
parameter λ was selected by 5-fold cross-validation on the
training set, optimizing AUC, with candidate values log-spaced
between 10⁻³ and 10¹. The optimal λ = 0.082 retained 11
predictors with non-zero coefficients (Supplementary Table S2).
Feature selection and model training were nested within each
cross-validation fold to prevent data leakage."
査読で指摘されやすい点
- 「正則化手法の選択理由が示されていない」
- 「λ の探索範囲・最適化方法が不明確」
- 「標準化を行ったか明記されていない」
- 「最終的に選ばれた変数のリストがない」
- 「CVの外側で λ や変数を選んでおり、データリーケージの可能性がある」
予測モデル研究として報告する場合は、TRIPOD+AI などのレポーティング規範を参照します。正則化を使った場合は、最終モデルの係数表、ハイパーパラメータ、CV戦略を本文または Supplementary に示すと、読者が再現しやすくなります[7]。
// 09 · CHECKLISTチェックリスト
正則化を使う前後に確認したい6項目です。
- 01研究目的(変数選択 / 過学習防止 / 両方)から手法を選択した
- 02標準化(StandardScaler)を Pipeline 内で適用している
- 03λと、必要に応じてElastic Netの混合比αをCVで最適化した
- 04λ の探索範囲を Methods に明記した
- 05変数選択を CV の各 fold 内で再実行している(リーケージ防止)
- 06最終モデルの係数表、λ、混合比αを本文またはSupplementaryに記載した
// 10 · QUIZミニクイズ
-
Q1「30変数から重要な変数を自動で絞り込みたい」研究で、最も適切な手法は?
- Lasso(L1)
- Ridge(L2)
- 通常の最小二乗法
- どれでも同じ
SHOW ANSWER
A. Lasso(L1)は一部の係数を0にしやすいため、変数選択に近い使い方ができます。Ridge は全変数を残しつつ係数を縮小します。通常の最小二乗法には正則化による過学習対策がありません。 -
Q2FIM 13項目すべてを変数として使ってロジスティック回帰したい。項目間相関が強い場合、最も適切な対処は?
- Lasso で項目を1つに絞る
- Ridge で全項目を残しつつ縮小
- 主成分分析で次元削減
- 何もしない
SHOW ANSWER
B. 多重共線性が強い変数群では、Lassoの選択結果が不安定になることがあります。Ridge は全項目を残しつつ係数を縮小するため、変数を削らずに推定を安定させたい場合に向いています。 -
Q3正則化を適用する際、最も避けるべき手順は?
- 標準化してから正則化を適用
- 標準化なしで正則化を適用
- CV で λ を最適化
- Pipeline で fit/transform 順序を保証
SHOW ANSWER
B. 正則化は係数の大きさに罰則をかけるため、変数の単位やスケールの影響を受けます。標準化なしでは、正則化の効き方が変数によって不公平になり、意図しない変数選択につながることがあります。
// REF参考文献
- Hastie T, Tibshirani R, Friedman J. The Elements of Statistical Learning. 2nd ed. Springer, 2009. — link
- Miyazaki Y, Oba J, Ishikawa T, Kawakami M, Kondo K, Hirabe A, et al. Explainable machine learning prediction of functional independence measure scores and gain in subacute stroke survivors. J Neuroeng Rehabil. 2026.
- Tibshirani R. Regression shrinkage and selection via the lasso. J R Stat Soc B 1996;58(1):267-288.
- Hastie T, Tibshirani R, Wainwright M. Statistical Learning with Sparsity: The Lasso and Generalizations. CRC Press, 2015.
- Pedregosa F, Varoquaux G, Gramfort A, et al. Scikit-learn: Machine learning in Python. JMLR 2011;12:2825-2830.
- Meinshausen N, Bühlmann P. Stability selection. J R Stat Soc B 2010;72(4):417-473.
- Collins GS, Moons KGM, et al. TRIPOD+AI statement. BMJ 2024;385:e078378.