勾配ブースティングは、小さな決定木を順に足し合わせるモデルです。前の木が外した部分を、次の木が少しずつ補います。XGBoost・LightGBM・CatBoost は、その代表的な実装です[1][2][3][4]。リハビリテーション研究では、FIM・SIAS・NIHSS・歩行速度・認知機能・検査値などの表形式データで使われます。
本記事では、勾配ブースティングを「性能が出やすいモデル」としてではなく、残差を順に補う木系モデルとして理解します。比較の基準には、 ロジスティック回帰・ 正則化線形モデル・ ランダムフォレスト を置きます。 過学習とリーケージは、09·01 過学習と正則化 と 09·02 データリーケージ も参照してください。Early Stopping の意味は 14·01 過学習デモ、臨床的有用性の評価は 14·04 DCA デモ で体感できます。
// 01 · LEARN OUTCOMESこの記事で学ぶこと
- 勾配ブースティングが、前のモデルの誤差を順に補う仕組みを説明できる。
- XGBoost・LightGBM・CatBoost の違いを、欠測・カテゴリ変数・速度の観点で整理できる。
- learning_rate、n_estimators、max_depth、subsample、colsample_bytree の意味を理解できる。
- early stopping、calibration、SHAP、GroupKFold を Methods に書ける粒度で確認できる。
// 02 · CONCLUSIONまず結論
表形式データで性能が出やすいというだけで「常に最良」ではありません。症例数やイベント数が少ない、施設差が強い、欠測の構造が偏る場合は、線形モデルの方が安定することもあります。
リハ研究で大切なのは、モデル名ではなく比較の設計です。同じ目的変数、同じ説明変数、同じ分割、同じ評価指標で比べる。AUC だけでなく、Brier score・calibration・感度・特異度・外部検証での性能も確認します。
SHAP などの説明手法は便利です[5]。ただし、SHAP は予測への寄与を示すものであって、予後因子の因果効果を直接示すものではありません。この区別を Methods と Discussion で明確にしておくと、査読での誤解を減らせます。
実務では、勾配ブースティングを最初から本命にしない方が整理しやすくなります。まず ロジスティック回帰 で説明変数とアウトカムの基本的な関係を確認し、次に 正則化線形 で多変数・小標本への耐性を見ます。そのうえで ランダムフォレスト と勾配ブースティングを比較すると、非線形性を加える意味が見えやすくなります。
勾配ブースティングで性能が上がった場合も、その理由を分解して考えます。入院時 FIM の非線形な効果なのか、SIAS と認知機能の交互作用なのか、施設 ID や評価時期を拾っているだけなのかで、解釈は変わります。この確認を行わないと、高い AUC だけが一人歩きしやすくなります。
// 03 · FIGURE図で理解する勾配ブースティング
図1では、1 本目の木だけで結論を出さない点に注目します。1 本目は入院時 FIM や年齢などの大まかな傾向を拾い、2 本目以降は、その予測が外れた症例のパターンを少しずつ補います。この積み重ねにより、非線形な関係や交互作用を扱いやすくなります。
図2では、ライブラリごとの得意分野を分けて見ます。XGBoost・LightGBM・CatBoost は同じ勾配ブースティング系ですが、前処理・速度・カテゴリ変数・欠測の扱いが異なります。医療データでは、性能だけでなく、再現性・説明性・施設の実装環境も選択理由になります。
// 04 · CLINICALリハ研究での使いどころ
入院時 FIM・年齢・発症から入院までの日数・SIAS・認知機能・栄養指標を使い、退院時 FIM や歩行自立を予測する場面です。XGBoost は、入院時 FIM と年齢の交互作用、重症度によって変わる効果を拾うことがあります。ただし、まず 正則化線形 や ロジスティック回帰 を作り、AUC・calibration・Brier score・SHAP の解釈を並べて比較します。
N=500 程度の自宅退院予測では、木を増やすほど訓練データへの適合は進みます。しかし、検証性能は途中で頭打ちになります。early stopping を使うと、検証セットで改善が止まった時点で学習を止められます。報告時には、何を検証セットにしたかを明記します。
多施設データでは、施設 ID・病棟種別・評価時期・退院支援の運用がアウトカムと結びつくことがあります。CatBoost はカテゴリ変数を扱いやすい一方で、施設 ID が施設固有の退院調整を代理する可能性があります。GroupKFold で施設単位に分割し、未知施設での性能を別に確認します。
検査値・処方・併存疾患・リハ単位数・看護必要度などを含む大規模 EHR では、LightGBM の速度が役立つことがあります。ただし、時系列情報を単純な集計値にすると、発症後の未来情報が混入する可能性があります。予測時点より後の情報を説明変数に入れない設計が必要です。
// 05 · THEORY仕組みを少し詳しく見る
1. 残差を順に補う
勾配ブースティングは、最初から複雑な木を作る方法ではありません。浅い木を順に追加し、予測を少しずつ修正していきます。直感的には、前回の予測で外れた症例に注目し、次の木でその外れ方を学ぶ、という流れです。
F_m(x) = F_{m-1}(x) + nu * h_m(x)
h_m = argmin_h sum_i L(y_i, F_{m-1}(x_i) + h(x_i))
nu: learning rate
nu は learning_rate です。1 本の木の影響を弱める係数で、小さくすると慎重に学習しますが、多くの木が必要になります。大きくすると速く学習しますが、検証性能が悪化しやすくなります。
2. XGBoost の考え方
XGBoost は、勾配ブースティングを実用的にした代表的な実装です[2]。損失を小さくするだけでなく、葉の数や葉の重みに対するペナルティを入れます。そのため、木が複雑になりすぎることを抑えやすくなります。
XGBoost objective:
obj = sum_i L(y_i, yhat_i) + sum_k Omega(f_k)
Omega(f) = gamma * number_of_leaves + 0.5 * lambda * sum_j w_j^2
max_depth は木の深さ、min_child_weight は葉を作るために必要な重みの下限、subsample は症例の一部を使う割合、colsample_bytree は特徴量の一部を使う割合です。これらは、過学習を抑える方向に働きます。
3. LightGBM の特徴
LightGBM は、大規模データで高速に学習しやすい実装です[3]。木の成長では leaf-wise という方式を使い、損失を大きく減らせる葉を優先して伸ばします。そのため速く高性能になりやすい一方、小データでは深くなりすぎることがあります。
医療データでは N が大きくないことも多いため、LightGBM を使うなら num_leaves・min_data_in_leaf・learning_rate・n_estimators を慎重に調整します。特に num_leaves が大きすぎると、訓練データに寄りすぎることがあります。
4. CatBoost の特徴
CatBoost は、カテゴリ変数を扱う工夫が特徴です[4]。通常のターゲットエンコーディングは目的変数の情報が前処理に漏れる危険がありますが、CatBoost は順序付きの処理により、この漏れを抑える設計を持ちます。
ただし、カテゴリ変数を使いやすいことと、施設差を安全に扱えることは別問題です。施設 ID が強い予測因子として出た場合、それは診療体制や退院調整を反映している可能性があります。その結果を、患者個人の医学的な予後因子として読むのは危険です。
5. ハイパーパラメータを臨床研究の言葉で読む
learning_rate は、1 回の修正をどれくらい控えめにするかを表します。小さい値は慎重ですが、木の本数を増やす必要があります。max_depth は、何段階の条件分岐まで許すか。深くすると FIM・年齢・認知機能・麻痺重症度の複雑な組み合わせを拾えますが、症例数が少ないと偶然の組み合わせを覚えます。
subsample と colsample_bytree は、症例と特徴量を少し間引く設定です。すべての症例と全特徴量を毎回使うより、モデルのばらつきを抑えられる場合があります。リハデータでは入院時 FIM のように強い変数があるため、特徴量サンプリングにより他の変数の寄与が見えることもあります。ただし、重要度の順位は設定に依存します。
6. calibration を別に見る理由
勾配ブースティングは、識別性能が高くても確率がずれることがあります。「自宅退院確率 0.80」と出ても、同じ確率帯の症例が実際に 80% 自宅退院するとは限りません。退院支援や研究説明で確率を扱うなら、calibration plot や Brier score を併せて確認します。必要に応じて Platt scaling や isotonic regression による較正も検討します。
// 06 · IMPLEMENTATIONPython 実装の型
以下は教育用の仮想データを使った例です。実患者データでは、個人情報保護・倫理審査・施設ルール・データ利用契約を確認します。予測時点より後の情報を説明変数に入れないことも重要です。前処理は Pipeline に入れ、交差検証の train fold 内で fit します。
# 教育用コードです。実患者データでは、倫理審査、施設ルール、
# 個人情報保護、データ利用契約、ライブラリ利用条件を確認します。
# example_rehab_dataset.csv は仮想データ名です。
import numpy as np
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.metrics import roc_auc_score, brier_score_loss
from sklearn.model_selection import train_test_split, StratifiedKFold, RandomizedSearchCV
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder
from sklearn.calibration import CalibratedClassifierCV
from xgboost import XGBClassifier
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_lower_limb",
"nihss_total",
"albumin",
"tug_seconds",
]
categorical_features = [
"sex",
"stroke_type",
"ward_type",
]
X = df[numeric_features + categorical_features]
y = df[target].astype(int)
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.20,
stratify=y,
random_state=RANDOM_STATE,
)
numeric_pipe = Pipeline(
steps=[("imputer", SimpleImputer(strategy="median"))]
)
categorical_pipe = Pipeline(
steps=[
("imputer", SimpleImputer(strategy="most_frequent")),
("onehot", OneHotEncoder(handle_unknown="ignore")),
]
)
preprocess = ColumnTransformer(
transformers=[
("num", numeric_pipe, numeric_features),
("cat", categorical_pipe, categorical_features),
]
)
xgb = XGBClassifier(
objective="binary:logistic",
eval_metric="logloss",
tree_method="hist",
random_state=RANDOM_STATE,
n_jobs=-1,
)
pipe = Pipeline(
steps=[
("preprocess", preprocess),
("model", xgb),
]
)
param_dist = {
"model__n_estimators": [200, 400, 800],
"model__learning_rate": [0.01, 0.03, 0.05, 0.1],
"model__max_depth": [2, 3, 4],
"model__min_child_weight": [1, 3, 5, 10],
"model__subsample": [0.7, 0.85, 1.0],
"model__colsample_bytree": [0.7, 0.85, 1.0],
"model__reg_lambda": [1, 3, 10],
}
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=RANDOM_STATE)
search = RandomizedSearchCV(
estimator=pipe,
param_distributions=param_dist,
n_iter=30,
scoring="roc_auc",
cv=cv,
n_jobs=-1,
random_state=RANDOM_STATE,
refit=True,
)
search.fit(X_train, y_train)
best_model = search.best_estimator_
prob_test = best_model.predict_proba(X_test)[:, 1]
auc = roc_auc_score(y_test, prob_test)
brier = brier_score_loss(y_test, prob_test)
print("Best params:", search.best_params_)
print("Test AUC:", round(auc, 3))
print("Test Brier:", round(brier, 3))
calibrated = CalibratedClassifierCV(best_model, method="isotonic", cv=3)
calibrated.fit(X_train, y_train)
prob_cal = calibrated.predict_proba(X_test)[:, 1]
print("Calibrated Brier:", round(brier_score_loss(y_test, prob_cal), 3))
この例では、XGBoost を Pipeline の中に入れています。数値変数は中央値で補完し、カテゴリ変数は最頻値で補完して OneHot 化。木系モデルなので標準化は不要ですが、補完や OneHotEncoder を全データで先に fit するとリーケージになります。
early stopping を使う場合は、さらに注意が必要です。検証セットを別に切り出し、その検証セットで改善が止まった時点を使います。交差検証と early stopping を同時に扱うなら、fold ごとに検証セットを作るか、学習用データ内で明確に分けます。テストデータを early stopping に使ってはいけません。
LightGBM と CatBoost では、カテゴリ変数の扱いが変わります。LightGBM はカテゴリ変数を指定でき、CatBoost はカテゴリ列をそのまま扱いやすい設計です。実装を変えると前処理も変わるため、Methods にはライブラリ名・バージョン・カテゴリ処理を記載します。
// 07 · MYTHSよくある誤解
- 誤解: XGBoost は何でも勝つ
- 線形関係が中心で症例数が少ない場合、正則化線形やロジ回帰の方が安定することがあります。性能差が小さい場合は、解釈性や calibration も比較します。
- 誤解: n_estimators を大きくすればよい
- 木を増やすと訓練データには合いやすくなります。learning_rate と組み合わせ、early stopping で検証性能を確認します。
- 誤解: カテゴリ変数は何もしなくてよい
- XGBoost では通常 OneHot などが必要です。LightGBM と CatBoost はカテゴリ処理を持ちますが、リーケージ と施設差の問題は別に確認します。
- 誤解: SHAP で上位なら予後因子
- SHAP はモデル予測への寄与であり、因果効果や介入効果を示すものではありません。予後因子として論じる場合は、研究デザインと交絡の検討が必要です。
// 08 · WRITING論文 Methods に書くこと
勾配ブースティングを論文で使う場合、モデル名だけでは不十分です。XGBoost・LightGBM・CatBoost のどれを使ったかを明記します。さらに、ライブラリのバージョン、目的関数、評価指標、ハイパーパラメータ探索、early stopping の方法を書きます。
- 01目的変数の定義を明記したか。例: 退院時 FIM 歩行 6 点以上。
- 02予測時点を明記したか。例: 入院時情報のみを使用。
- 03欠測補完とカテゴリ変数処理を Pipeline 内で行ったか。
- 04比較モデルとしてロジ回帰、正則化線形、RF を含めたか。
- 05チューニング範囲と探索方法を記載したか。
- 06early stopping に使った検証セットを明記したか。
- 07AUC だけでなく、Brier score と calibration も報告したか。
- 08SHAP は予測寄与であり、因果効果ではないと説明したか。
査読で指摘されやすいのは、テストデータの扱いです。テストデータをチューニング・early stopping・しきい値選択に使うと、性能が高く見えます。その場合、独立した評価データでは性能が落ちる可能性があります。
TRIPOD+AI は、予測モデル研究の報告透明性を高める枠組みです[6]。PROBAST+AI は、バイアスと適用可能性を確認する枠組みです[7]。勾配ブースティングのような複雑なモデルでは、これらの視点が特に重要です。
もう 1 つ重要なのは、比較表の作り方です。勾配ブースティングだけを提示すると、モデル選択の妥当性が伝わりません。Methods には候補モデルを列挙し、Results では同じ分割での性能を並べます。AUC が少し高いだけで採用するのではなく、信頼区間・calibration・説明性・外部検証での安定性を合わせて判断します。
Discussion では、モデルが拾った関係を臨床知識と照合します。SHAP で入院時 FIM が上位に出ることは自然ですが、施設 ID・評価年度・欠測の有無が強い場合は、臨床的な予後因子ではなく運用やデータ収集過程を反映している可能性があります。この点を限界として書くと、結果の読み過ぎを避けられます。
// 09 · CHECKLIST実務チェックリスト
- 01線形・ロジ・正則化・RF と同じデータ分割で比較した。
- 02予測時点より後の情報を説明変数から除外した。
- 03欠測補完とカテゴリ処理を Pipeline 内で行った。
- 04learning_rate と n_estimators をセットで調整した。
- 05early stopping にテストデータを使っていない。
- 06施設差がある場合、GroupKFold や施設別評価を検討した。
- 07AUC、Brier score、calibration を併せて見た。
- 08SHAP の結果を因果効果として書いていない。
// 10 · QUIZ確認クイズ
-
Q1勾配ブースティングの直感として最も近いものはどれですか。
- 多数の木を完全に独立に作って多数決する
- 前のモデルの誤差を次のモデルが補う
- すべての特徴量を標準化して距離を測る
- 目的変数を使わずにクラスタを作る
SHOW ANSWER
B. Bagging は A に近く、勾配ブースティングは逐次的に誤差を補います。 -
Q2early stopping で避けるべきことはどれですか。
- 学習データ内から検証セットを作る
- 検証性能が止まった時点を記録する
- テストデータを学習打ち切りに使う
- n_estimators を大きめに設定する
SHOW ANSWER
C. テストデータは最終評価に残します。 -
Q3CatBoost の特徴として適切なのはどれですか。
- カテゴリ変数処理に工夫がある
- 線形回帰だけを高速にする
- 標準化しないと学習できない
- SHAP を因果効果に変換する
SHOW ANSWER
A. ただし施設 ID のような変数は、解釈に注意が必要です。 -
Q4SHAP の結果を読むときの注意として正しいものはどれですか。
- 上位の変数は治療標的と判断できる
- 上位の変数は予測寄与が大きいと読む
- 交絡の影響は自動で消える
- 外部検証は不要になる
SHOW ANSWER
B. SHAP は予測寄与であり、因果効果ではありません。
// 11 · FAQよくある質問
- 勾配ブースティングは常にロジスティック回帰より良いですか?
- いいえ。症例数が少ない、イベント数が少ない、関係が線形に近い場合は、ロジスティック回帰 や 正則化線形 のほうが安定することがあります。同じ分割で AUC・Brier score・calibration を並べて判断します。
- XGBoost、LightGBM、CatBoost はどう使い分けますか?
- XGBoost は正則化と安定性、LightGBM は大規模データでの速度、CatBoost はカテゴリ変数処理に特徴があります。リハ研究のような中規模・表形式データではまず XGBoost、N が大きい EHR では LightGBM、施設 ID など高カード変数を扱う場合は CatBoost が候補です。
- early stopping にテストデータを使ってよいですか?
- いけません。テストデータを early stopping に使うと、独立した評価でなくなり、性能が楽観的に評価されます。学習用データから検証セットを切り出すか、fold ごとに検証セットを作ります。
// REF参考文献
- Friedman JH. Greedy function approximation: a gradient boosting machine. Annals of Statistics 2001;29(5):1189-1232.
- Chen T, Guestrin C. XGBoost: a scalable tree boosting system. KDD 2016:785-794.
- Ke G, Meng Q, Finley T, Wang T, Chen W, Ma W, et al. LightGBM: a highly efficient gradient boosting decision tree. NeurIPS 2017;30.
- Prokhorenkova L, Gusev G, Vorobev A, Dorogush AV, Gulin A. CatBoost: unbiased boosting with categorical features. NeurIPS 2018;31.
- Lundberg SM, Lee SI. A unified approach to interpreting model predictions. NeurIPS 2017;30.
- 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.
- Wolff RF, Moons KGM, Riley RD, Whiting PF, Westwood M, Collins GS, et al. PROBAST+AI: a tool to assess the risk of bias and applicability of prediction model studies that use artificial intelligence. BMJ 2025;388:e082505.