// PART 09 · ARTICLE 03 / 11
PITFALLS SAMPLE-SIZE L2

小規模データ問題(EPV・サンプルサイズ設計)

— 「N が少ない」だけでは語れない過大評価のメカニズム

8 min read· L2· 2026.05.22 update· by Editor

医療AI研究では、症例数が限られる一方で、説明変数や特徴量は増えやすいです。年齢・発症からの日数・FIM・SIAS・NIHSS・画像特徴量・歩行特徴量をすべて入れれば、見かけ上の性能は上がるかもしれません。しかし、少数例で候補変数が多いほど、モデルは偶然の関係を拾いやすくなります。小規模データ問題は、単に「N が少ない」ことではなく、アウトカム数・候補パラメータ数・モデル複雑度・検証設計のバランスの問題です。

// CONTEXT

本稿は第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図で理解する小規模データ問題

この落とし穴は、数式よりも「どこで性能が歪むか」を図で見た方が理解しやすいです。まず全体像を確認します。

// SMALL-N MAP · イベント数 × 候補変数のバランス LOW RISK 安定推定が期待できる events: 100+ 例 candidates: ≤ 10 個 EPV: > 10 + 戦略 • ロジスティック回帰 • 単純なベースライン • CV で性能確認 • 外部検証も可能 CAUTION 対策を入れて慎重に events: 30〜100 例 candidates: 10〜30 個 EPV: 3 〜 10 + 戦略 • L2 / Lasso 正則化 • 候補変数を事前に絞る • Repeated CV で SD 提示 • bootstrap optimism 補正 HIGH RISK 楽観バイアスが強く出る events: < 30 例 candidates: 数十〜数百 EPV: < 3 + 戦略 • 仮説生成として位置づけ • 探索的解析と明記 • 多施設化を検討 • 単一分割の AUC 不可 サンプルサイズは p 値の議論だけでなく、推定の安定性の議論でもある
図1: イベント数と候補パラメータ数のバランスから見た 3 ゾーン。低 EPV では、係数・特徴量重要度・AUC の不安定性が増すため、候補変数を絞る・正則化を使う・検証でばらつきを示す、という対策をセットで考えます。

次に、EPV が下がると AUC の見かけと真値の乖離(楽観バイアス)がどう増えるかを直感的に示します。

// OPTIMISM CURVE · EPV が下がるほど apparent AUC が真値から乖離 1.00 0.90 0.80 0.70 AUC EPV → 2 5 10 20 50 Apparent AUC(楽観) True / External AUC gap 大 HIGH RISK CAUTION RELATIVELY SAFE apparent AUC のみを報告すると、EPV が低いほど性能を過大評価する
図2: EPV と楽観バイアスの関係。訓練データで測った apparent AUC は EPV が低いほど真値(外部検証 AUC)から乖離します。bootstrap optimism 補正・繰り返し CV・外部検証で、この乖離を見える化することが小規模研究の基本姿勢です。

// 04 · CLINICAL医療・リハビリでの具体例

// CASE 1 · FIM 利得の回帰モデル

100 例で 30 変数を候補にすると、ある分割では高い R² が出ても、別分割では性能が落ちることがあります。係数の符号や重要変数が揺れる場合、臨床的解釈は慎重にします。Repeated CV で fold 間 SD を併せて報告するのが基本です。

// CASE 2 · 歩行自立の分類モデル

歩行自立 70 例・非自立 30 例で 20 変数を扱う場合、少数側イベント数は 30 です。EPV = 1.5 程度となり、非自立を説明する偶然の組み合わせを拾いやすくなります。候補変数を 5〜8 個に絞り、L2 正則化付き ロジスティック回帰 を出発点にします。

// CASE 3 · 画像・動作解析の特徴量

CT や動画から 100 個以上の特徴量を抽出すると、N が数十でもモデルは作れてしまいます。しかし、特徴量選択を全データで行うと リーケージ になり、fold 内で行っても選択結果の不安定性が残ります。まず PCA で次元を整理し、変数の意味を確認してから絞ります。

// CASE 4 · 多施設化で N を確保する

単施設で 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 間ばらつきを併せて出すパターンです。

PYTHON
# 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 では、読者が「どこで性能が歪む可能性があるか」を追跡できるようにします。

// METHODS CHECK
  • 対象症例数・イベント数・候補パラメータ数を明記する。
  • 事前のサンプルサイズ計算(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理解度チェック

  1. Q1EPV が低い研究で最も注意すべき解釈はどれですか。
    • AUC が高ければ臨床実装できる
    • 係数や重要度が不安定になり得る
    • 線形回帰なら問題ない
    • 外部検証は不要
    SHOW ANSWER
    B. イベント数に対して候補変数が多いと、性能だけでなく係数や重要度も不安定になります。
  2. Q2小規模データでまず行うべき対策はどれですか。
    • 特徴量をできるだけ増やす
    • test データを見ながら調整する
    • 候補変数を臨床的に絞る
    • 精度が高いモデルだけ報告する
    SHOW ANSWER
    C. 候補変数を事前に絞り、正則化と適切な検証を組み合わせます。
  3. Q3apparent AUC と corrected AUC を比較する目的はどれですか。
    • 計算量を減らすため
    • 楽観的バイアス(optimism)を見える化するため
    • 前処理を省略するため
    • サンプルサイズを増やす代わり
    SHOW ANSWER
    B. bootstrap optimism correction で apparent と corrected の差から楽観度を推定し、汎化性能の見通しを立てます。
  4. 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参考文献

  1. 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
  2. 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
  3. 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
  4. Steyerberg EW. Clinical Prediction Models: A Practical Approach to Development, Validation, and Updating. 2nd ed. Springer; 2019.
  5. Harrell FE Jr. Regression Modeling Strategies. 2nd ed. Springer; 2015.