医療AI研究では、症例数が限られる一方で、説明変数や特徴量は増えやすいです。年齢・発症からの日数・FIM・SIAS・NIHSS・画像特徴量・歩行特徴量をすべて入れれば、見かけ上の性能は上がるかもしれません。しかし、少数例で候補変数が多いほど、モデルは偶然の関係を拾いやすくなります。小規模データ問題は、単に「N が少ない」ことではなく、アウトカム数・候補パラメータ数・モデル複雑度・検証設計のバランスの問題です。
本稿は第9部の第3記事です。前記事 09·02 データリーケージ が情報の漏れを扱ったのに対し、本稿では、漏れがなくても性能が過大評価される構造を扱います。EPV は入口として有用ですが、現在はそれだけで十分とは考えず、予測モデル研究では shrinkage(正則化)・楽観度・予測の安定性・外部検証可能性まで含めて設計します。09·01 過学習 と 14·01 過学習デモ・14·02 交差検証デモ も合わせて読むと、ばらつきの見方が掴みやすくなります。
// 01 · LEARN OUTCOMESこの記事で学ぶこと
- EPV(events per variable)を、機械的な基準ではなく不安定性の目安として理解する。
- 症例数・イベント数・候補パラメータ数・モデル複雑度の関係を説明できる。
- 小規模データで AUC や R² が過大評価される理由(楽観的バイアス)を整理する。
- Methods でサンプルサイズの根拠と限界を書く観点を整理できる。
// 02 · CONCLUSIONまず結論
// 03 · FIGURE図で理解する小規模データ問題
この落とし穴は、数式よりも「どこで性能が歪むか」を図で見た方が理解しやすいです。まず全体像を確認します。
次に、EPV が下がると AUC の見かけと真値の乖離(楽観バイアス)がどう増えるかを直感的に示します。
// 04 · CLINICAL医療・リハビリでの具体例
100 例で 30 変数を候補にすると、ある分割では高い R² が出ても、別分割では性能が落ちることがあります。係数の符号や重要変数が揺れる場合、臨床的解釈は慎重にします。Repeated CV で fold 間 SD を併せて報告するのが基本です。
歩行自立 70 例・非自立 30 例で 20 変数を扱う場合、少数側イベント数は 30 です。EPV = 1.5 程度となり、非自立を説明する偶然の組み合わせを拾いやすくなります。候補変数を 5〜8 個に絞り、L2 正則化付き ロジスティック回帰 を出発点にします。
CT や動画から 100 個以上の特徴量を抽出すると、N が数十でもモデルは作れてしまいます。しかし、特徴量選択を全データで行うと リーケージ になり、fold 内で行っても選択結果の不安定性が残ります。まず PCA で次元を整理し、変数の意味を確認してから絞ります。
単施設で EPV を上げられない場合、多施設化が選択肢です。ただし、施設間で測定方法・記録ルール・患者集団が異なると、単純に N が増えても性能は安定しません。施設差を考慮した GroupKFold や、施設効果を入れる混合モデルが候補になります。
// 05 · THEORY理論の最小限
EPV(events per variable)
EPV は、候補パラメータ 1 個あたりに使えるアウトカムイベント数です。二値分類なら、少数側クラスのイベント数を候補変数の数で割ります。
EPV = (少数側イベント数) / (候補パラメータ数)
例: 自宅退院 60 例 / 非自宅 40 例、候補 12 変数
→ 少数側 = 40, EPV = 40 / 12 ≈ 3.3
古典的な「EPV ≥ 10」という経験則は知られていますが、Riley らは現在この基準だけでは不十分とし、想定 C 統計量・アウトカム頻度・許容 shrinkage を組み合わせた現代的な計算枠組みを提案しています[1]。
楽観的バイアス(apparent vs true performance)
訓練データで測った性能(apparent performance)は、真の汎化性能より高く出ます。この差を楽観度(optimism)と呼びます。
optimism = apparent_AUC − expected_external_AUC
Bootstrap optimism correction:
1. 元データで apparent AUC を計算
2. bootstrap 標本でモデルを再学習し
元データ上の AUC との差(fold 楽観度)を測る
3. これを B 回繰り返し平均 → optimism 推定
4. corrected AUC = apparent AUC − mean(optimism)
shrinkage(縮小推定)
少数例で推定した係数は、ゼロから離れすぎる傾向があります。L2 や Lasso による shrinkage は、係数を縮める方向に働き、楽観度を下げる効果があります。ロジスティック回帰の場合、heuristic shrinkage factor を使って事前にスケール調整する方法もあります。
サンプルサイズ設計の現代的枠組み
Riley 2020 では、4 つの基準を満たす最小 N を計算します[1]:
Riley 2020 (binary outcome):
(i) shrinkage ≥ 0.9(係数の歪みを 10% 以下に抑える)
(ii) apparent − adjusted R² ≤ 0.05
(iii) prevalence の絶対誤差 ≤ 0.05
(iv) C 統計量の絶対誤差 ≤ 0.05
これらを満たす最小 N を解析的に求める。
R: pmsampsize パッケージで実装。
この枠組みは、p 値検定のためのサンプルサイズではなく、予測モデルとしての安定性のための設計です。検出力計算とは別物として整理します。
// 06 · IMPLEMENTATION · PYTHON実装・解析の考え方
実装では、解析の便利さよりも、評価データを守ることを優先します。前処理・補完・特徴量選択・リサンプリング・ハイパーパラメータ探索は、いずれも検証設計の中に入れて考えます。下記は Repeated CV で fold 間ばらつきを併せて出すパターンです。
# Educational example only.
# Use de-identified data and follow IRB / facility policies.
import numpy as np
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import RepeatedStratifiedKFold, cross_val_score
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.utils import resample
RANDOM_STATE = 42
df = pd.read_csv("example_rehab_dataset.csv")
target = "home_discharge"
numeric_features = [
"age", "days_from_onset", "fim_motor_admission",
"fim_cognition_admission", "sias_total",
]
categorical_features = ["sex", "stroke_type"]
X = df[numeric_features + categorical_features]
y = df[target].astype(int)
# Step 1: count events and check EPV
n_events = min((y == 1).sum(), (y == 0).sum())
n_params = len(numeric_features) + len(categorical_features) * 2 # rough one-hot expansion
epv = n_events / n_params
print(f"events (少数側): {n_events}, candidate params: {n_params}, EPV: {epv:.2f}")
# Step 2: Pipeline with L2 regularization (shrinkage)
preprocess = ColumnTransformer([
("num", Pipeline([
("imputer", SimpleImputer(strategy="median")),
("scaler", StandardScaler()),
]), numeric_features),
("cat", Pipeline([
("imputer", SimpleImputer(strategy="most_frequent")),
("onehot", OneHotEncoder(handle_unknown="ignore")),
]), categorical_features),
])
pipe = Pipeline([
("preprocess", preprocess),
("model", LogisticRegression(
penalty="l2", C=1.0,
class_weight="balanced",
max_iter=2000, random_state=RANDOM_STATE,
)),
])
# Step 3: Repeated CV — show mean AND std
cv = RepeatedStratifiedKFold(
n_splits=5, n_repeats=20, random_state=RANDOM_STATE
)
scores = cross_val_score(pipe, X, y, cv=cv, scoring="roc_auc")
print(f"CV AUC: {scores.mean():.3f} ± {scores.std():.3f}")
print(f" range: [{scores.min():.3f}, {scores.max():.3f}]")
# Step 4: Bootstrap optimism correction (Harrell)
def bootstrap_optimism(X, y, pipe, n_boot=200, random_state=42):
rng = np.random.RandomState(random_state)
pipe.fit(X, y)
apparent = roc_auc_score(y, pipe.predict_proba(X)[:, 1])
optimism = []
n = len(X)
for _ in range(n_boot):
idx = rng.randint(0, n, n)
X_b = X.iloc[idx]; y_b = y.iloc[idx]
pipe.fit(X_b, y_b)
boot_auc = roc_auc_score(y_b, pipe.predict_proba(X_b)[:, 1])
orig_auc = roc_auc_score(y, pipe.predict_proba(X)[:, 1])
optimism.append(boot_auc - orig_auc)
corrected = apparent - np.mean(optimism)
return apparent, corrected, np.mean(optimism)
app, corr, opt = bootstrap_optimism(X, y, pipe, n_boot=200)
print(f"apparent AUC : {app:.3f}")
print(f"optimism : {opt:.3f}")
print(f"corrected AUC: {corr:.3f}")
# Report apparent, corrected, CV mean ± SD together.
# Do NOT report only apparent AUC for small-N studies.
このコードでは、(1) EPV を計算して読者に提示、(2) Repeated CV で fold 間 SD を報告、(3) Harrell 流の bootstrap optimism 補正で apparent と corrected の両方を並べる、という流れを示しています。R では pmsampsize パッケージで Riley 2020 の必要 N を計算できます。
// 07 · MYTHSよくある誤解
- 誤解: EPV 10 を満たせば安全
- 古典的な経験則ですが、現在は十分とは見なされません。想定 C 統計量・アウトカム頻度・許容 shrinkage を組み合わせた Riley 2020 の枠組みで必要 N を見積もるのが標準的になりつつあります。
- 誤解: AUC が高ければサンプルサイズは関係ない
- 少数例で得られた高 AUC は楽観バイアスを含みます。fold 間ばらつき・bootstrap optimism・外部検証を併せて見ないと、汎化性能を見誤ります。
- 誤解: 機械学習は線形モデルより少ない N でうまくいく
- 逆の傾向が多く報告されています。木系・NN は柔軟な分、少数例では過学習リスクが大きく、線形モデルと正則化が安定する場面が増えます。
- 誤解: 単一 fold の AUC を最終評価にしてよい
- fold の選び方で値が動くため、単一 fold の AUC は不安定です。Repeated CV の平均 ± SD を提示し、外部検証も計画します。
// 08 · WRITING論文 Methods / Results に書くこと
Methods と Discussion では、読者が「どこで性能が歪む可能性があるか」を追跡できるようにします。
- 対象症例数・イベント数・候補パラメータ数を明記する。
- 事前のサンプルサイズ計算(Riley 2020 / pmsampsize 等)の根拠と仮定を書く。
- 候補変数を絞った基準(臨床知識・先行研究)を書く。
- shrinkage / 正則化の方法とパラメータ選択を書く。
- Repeated CV の fold 数・繰り返し回数・seed を書く。
- bootstrap optimism correction の有無と方法を書く。
- 外部検証の計画(時期・施設・前向き)の有無を書く。
- 探索的研究か検証研究かを Discussion で明記する。
Results では、apparent performance だけでなく、Repeated CV の平均 ± SD、bootstrap-corrected AUC、可能なら外部検証 AUC を並べます。TRIPOD+AI は予測モデルの透明な報告枠組みです[2]。PROBAST+AI はバイアスと適用可能性の評価で参考になります[3]。
Discussion では、N とイベント数の制約から、研究を「仮説生成」「探索的」「検証研究」のどこに位置づけるかを明確にします。AUC が高くても、サブグループや外部施設で同じ性能が再現する保証がない、と素直に書く方が長期的な信頼につながります。
EPV 計算と sample size justification の Methods 文面は、13·04 論文の Methods を書くプロンプト のテンプレ A(9 サブセクション骨子生成)で扱います。
// 09 · CHECKLIST解析前チェックリスト
- 01目的変数のイベント数と候補パラメータ数を数えた
- 02EPV だけでなく、想定 C 統計量・shrinkage・楽観度を検討した(Riley 2020)
- 03候補変数を解析前に臨床的に絞った
- 04特徴量選択・前処理を CV の各 fold 内で行った
- 05AUC や R² だけでなく fold 間のばらつき(SD)も示した
- 06bootstrap optimism correction を実施した
- 07外部検証(時期・施設・前向き)を計画または実施した
- 08探索研究か検証研究かを Discussion で明記した
// 10 · QUIZ理解度チェック
-
Q1EPV が低い研究で最も注意すべき解釈はどれですか。
- AUC が高ければ臨床実装できる
- 係数や重要度が不安定になり得る
- 線形回帰なら問題ない
- 外部検証は不要
SHOW ANSWER
B. イベント数に対して候補変数が多いと、性能だけでなく係数や重要度も不安定になります。 -
Q2小規模データでまず行うべき対策はどれですか。
- 特徴量をできるだけ増やす
- test データを見ながら調整する
- 候補変数を臨床的に絞る
- 精度が高いモデルだけ報告する
SHOW ANSWER
C. 候補変数を事前に絞り、正則化と適切な検証を組み合わせます。 -
Q3apparent AUC と corrected AUC を比較する目的はどれですか。
- 計算量を減らすため
- 楽観的バイアス(optimism)を見える化するため
- 前処理を省略するため
- サンプルサイズを増やす代わり
SHOW ANSWER
B. bootstrap optimism correction で apparent と corrected の差から楽観度を推定し、汎化性能の見通しを立てます。 -
Q4Riley 2020 のサンプルサイズ計算で考慮しない要素はどれですか。
- 想定 C 統計量
- アウトカム頻度
- 許容 shrinkage
- 著者の人数
SHOW ANSWER
D. Riley 2020 は C 統計量・アウトカム頻度・shrinkage・apparent と adjusted の差などモデル統計的な要素から必要 N を導きます。
// 11 · FAQよくある質問
- EPV 10 という目安はそのまま使ってよいですか?
- 古典的な経験則として知られていますが、現在は十分とは考えられていません。Riley 2020 の枠組みでは、アウトカム頻度・候補パラメータ数・想定 C 統計量・許容 shrinkage を組み合わせて必要 N を計算します。EPV 10 はあくまで入口の目安として扱います。
- 小規模データで AUC が高く出たら信用してよいですか?
- 単一分割の AUC は楽観的バイアス(apparent performance)を含みます。bootstrap optimism correction、k-fold CV の繰り返し、fold 間ばらつきの提示、可能なら外部検証で確認します。AUC が高い fold だけ報告するのは避けます。14·02 交差検証デモ で fold が入れ替わる様子も体感できます。
- 候補変数を絞るのは「データを見てから」でよいですか?
- アウトカムを見ながら絞ると、選択そのものが楽観バイアスを生みます。臨床知識・先行研究・測定可能性から事前に絞るのが原則です。データ駆動の特徴量選択を行う場合は、各 CV fold の訓練データ内で完結させます(09·02 データリーケージ 参照)。
// REF参考文献
- Riley RD, Ensor J, Snell KIE, Harrell FE Jr, Martin GP, Reitsma JB, et al. Calculating the sample size required for developing a clinical prediction model. BMJ 2020;368:m441. — doi
- Collins GS, Moons KGM, Dhiman P, Riley RD, Beam AL, Van Calster B, et al. TRIPOD+AI statement: updated guidance for reporting clinical prediction models that use regression or machine learning methods. BMJ 2024;385:e078378. — doi
- Moons KGM, Wolff RF, Riley RD, et al. PROBAST+AI: an updated quality, risk of bias, and applicability assessment tool for prediction models using regression or artificial intelligence methods. BMJ 2025;388:e082505. — doi
- Steyerberg EW. Clinical Prediction Models: A Practical Approach to Development, Validation, and Updating. 2nd ed. Springer; 2019.
- Harrell FE Jr. Regression Modeling Strategies. 2nd ed. Springer; 2015.