ロジスティック回帰はリハビリ領域の研究で広く使われるアルゴリズムの一つです。「自宅退院できるか」「歩行自立に至るか」「再入院するか」── これらの可/不可のような2値分類問題で、ロジスティック回帰が使われます。線形回帰(03·01)の線形予測子をシグモイド関数に通し、確率を出力するシンプルな構造ですが、係数 → オッズ比 → 臨床的意義へと解釈ができるため、医療領域で広く使われてきました。
本稿は 第3部 医療AI・機械学習アルゴリズム図鑑 第2記事。線形回帰(03·01)の発展形として、2値分類への拡張を説明します。リハビリ・医学領域の予後予測モデルを確立する上で、ロジスティック回帰を理解することは重要です。
// 01 · LEARN OUTCOMESこの記事でわかること
- シグモイド関数が「実数 → 確率」への変換だと直感的に理解できる
- 係数 β を「オッズ比 exp(β)」として解釈し、臨床的に解釈できる
- 決定境界の意味と、しきい値 0.5 が常に最適とは限らないことを理解できる
- 線形回帰との違い・XGBoost との使い分けの判断基準を持てる
// 02 · CONCLUSIONまず結論
// 03 · FIGURE直感的な図解
まず、ロジスティック回帰の心臓部であるシグモイド関数を可視化します。「実数全体(-∞〜+∞)を確率(0〜1)に押し込む」変換がロジスティック回帰の原理です。
続いて、ロジスティック回帰の係数 β とオッズ比 exp(β) の関係を可視化。臨床的解釈で最も重要な対応関係です。
表中のFIM motorとLives w/ familyのように、β が正で OR が 1 を超える変数は促進因子。Ageのように β が負で OR が 1 を下回る変数は抑制因子。Sexのように β が 0 付近(OR ≈ 1)であれば、そのアウトカムへの寄与はほぼないと解釈できます。臨床的解釈と統計的な係数の符号がここで一直線につながるのが、ロジスティック回帰最大の魅力です。
// 04 · CLINICAL医療・リハビリでの具体例
ロジスティック回帰は、リハビリ領域の研究の2値分類タスクで広く使われます。代表的な予測を見ていきます。
y = 1(歩行自立 FIM歩行小項目≥6)/ 0(介助歩行・歩行不能 FIM歩行小項目<6)で退院時歩行自立可否の予後予測ができます。入院時の年齢やFIM小項目、麻痺の重症度などから、退院時のFIM予後予測を行った論文を報告されています。ロジスティック回帰の特徴であるオッズ比により予測モデルに体幹機能が最も寄与することが報告されています。
症例数が限られるリハビリ領域の研究では、ロジスティック回帰の予測精度が 他の機械学習と同程度となることも多いです。ロジスティック回帰は、(1) 説明変数の臨床的解釈が直接可能、(2) 学習が高速、(3) 査読者にとっても馴染みがあるということから、現在でも使われています。
// 05 · THEORY数式・理論
ロジスティック回帰の数学的構造を、シグモイド関数 → 対数オッズ → 最尤法の3点で整理します。
モデルの定義
# 予測確率
P(y=1 | x) = σ(β₀ + β₁x₁ + β₂x₂ + ... + β_p x_p)
= σ(z)
= 1 / (1 + e⁻ᶻ)
# z は線形回帰そのもの
z = β₀ + Σⱼ βⱼ xⱼ
# 予測クラス(しきい値0.5の場合)
ŷ = 1 if P(y=1|x) ≥ 0.5
= 0 otherwise
対数オッズ(logit)変換
シグモイドの逆関数を取ると、「対数オッズ」と呼ばれる量が得られます。これがロジスティック回帰を「線形モデル」と呼ぶ理由です。
# オッズ
odds = P(y=1) / P(y=0)
= P(y=1) / (1 − P(y=1))
# 対数オッズ(logit)
logit(P) = log( P / (1−P) )
# ロジスティック回帰の核心
logit( P(y=1|x) ) = β₀ + β₁x₁ + β₂x₂ + ...
= z(線形)
→ 「対数オッズが特徴量の線形和」となるのがこのモデル
→ だから線形モデルの仲間
係数 β とオッズ比 OR の関係
係数 β を exp() 変換すると、オッズ比(Odds Ratio; OR) になります。これが臨床的解釈の鍵です。
# x_j を1単位増やしたときのオッズ変化
odds_after / odds_before = exp(βⱼ)
# 解釈の例
β = +0.1 → exp(0.1) = 1.11 → OR 1.11倍(11%増)
β = −0.5 → exp(−0.5) = 0.61 → OR 0.61倍(39%減)
β = +1.2 → exp(1.2) = 3.32 → OR 3.32倍(232%増)
# 臨床解釈テンプレート
「{x_j}が{1単位}増えると、{y=1}のオッズが{exp(β)}倍になる」
最尤推定(Maximum Likelihood Estimation; MLE)
線形回帰と違い、ロジスティック回帰は解析解がありません。代わりに、観測データの「尤度」を最大化する β を、勾配降下法(03·13)で反復探索します。
# 尤度関数(全症例での観測確率の積)
L(β) = Πᵢ P(yᵢ | xᵢ; β)
= Πᵢ [ σ(z_i)^yᵢ · (1−σ(z_i))^(1−yᵢ) ]
# 計算上は対数尤度を使う(積 → 和 で扱いやすい)
log L(β) = Σᵢ [ yᵢ log σ(z_i) + (1−yᵢ) log(1−σ(z_i)) ]
# 最大化(または負の対数尤度を最小化)
β̂ = argmax_β log L(β)
# これが交差エントロピー損失と等価
NLL = − log L(β) = − Σᵢ [ yᵢ log p̂_i + (1−yᵢ) log(1−p̂_i) ]
= 交差エントロピー
scikit-learn の LogisticRegression はデフォルトで L2 正則化が入っており、純粋な MLE ではなく罰則付き最尤推定です。これが 過学習を抑える役割を果たします。正則化の詳細は 03·03 正則化 で扱います。
// 06 · IMPLEMENTATION · PYTHON実装
scikit-learn と statsmodels の使い分け。「予測精度」目的なら sklearn、「オッズ比と CI」が必要なら statsmodels。
import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import (
roc_auc_score, classification_report, confusion_matrix
)
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
# ============================================
# データ準備
# ============================================
df = pd.read_csv("rehab_cohort.csv")
X = df[["fim_motor_admission", "age", "onset_days",
"lives_with_family", "mmse"]]
y = df["discharge_home"] # 1=自宅, 0=施設・転院
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=42
)
# ============================================
# ① scikit-learn:予測精度が目的
# ============================================
pipeline = Pipeline([
("scaler", StandardScaler()), # 標準化(係数の比較に有用)
("clf", LogisticRegression(
penalty="l2", C=1.0, max_iter=1000)),
])
pipeline.fit(X_train, y_train)
# 確率を出力(分類前に確認)
y_proba = pipeline.predict_proba(X_test)[:, 1]
print(f"AUC: {roc_auc_score(y_test, y_proba):.3f}")
# しきい値 0.5 で分類
y_pred = (y_proba >= 0.5).astype(int)
print(classification_report(y_test, y_pred))
# ============================================
# ② statsmodels:係数の信頼区間とオッズ比
# ============================================
import statsmodels.api as sm
X_train_const = sm.add_constant(X_train)
logit_model = sm.Logit(y_train, X_train_const).fit()
# 係数とオッズ比を表示
params = logit_model.params
conf = logit_model.conf_int()
conf["OR"] = np.exp(params)
conf.columns = ["2.5%", "97.5%", "OR"]
conf[["OR", "2.5%", "97.5%"]] = (
np.exp(conf[["OR", "2.5%", "97.5%"]])
if False else # 既に exp 済みなので
conf[["OR", "2.5%", "97.5%"]]
)
# 正しい計算:
or_table = pd.DataFrame({
"OR": np.exp(params),
"2.5%": np.exp(logit_model.conf_int()[0]),
"97.5%": np.exp(logit_model.conf_int()[1]),
"p-value": logit_model.pvalues,
})
print(or_table.round(3))
# → OR 2.5% 97.5% p-value
# → fim_motor_admission 1.11 1.05 1.18 0.000
# → age 0.61 0.45 0.83 0.002
# ============================================
# ③ しきい値の調整(臨床コストで決める)
# ============================================
from sklearn.metrics import precision_recall_curve
precision, recall, thresholds = precision_recall_curve(y_test, y_proba)
# 例:感度 80% を確保しつつ精度を最大化するしきい値
target_recall = 0.80
idx = np.argmax(recall >= target_recall)
optimal_threshold = thresholds[idx]
print(f"Optimal threshold for recall={target_recall}: "
f"{optimal_threshold:.3f}")
y_pred_adjusted = (y_proba >= optimal_threshold).astype(int)
# → しきい値を下げると感度↑、特異度↓
# ============================================
# ④ Calibration(確率の信頼性)を確認
# ============================================
from sklearn.calibration import calibration_curve
import matplotlib.pyplot as plt
prob_true, prob_pred = calibration_curve(
y_test, y_proba, n_bins=10
)
plt.plot(prob_pred, prob_true, marker='o', label='Logistic')
plt.plot([0, 1], [0, 1], '--', color='gray', label='Perfect')
plt.xlabel("Predicted probability")
plt.ylabel("Observed frequency")
plt.title("Calibration plot")
# → 対角線に乗っていれば「予測確率=実際の頻度」で信頼できる
重要: ロジスティック回帰は確率を出力することが大きな利点です。0/1 だけでなく確率を見ることで、「ぎりぎりの症例(P=0.45)」と「ほぼ確実な症例(P=0.95)」を区別できます。Calibration plot で確率の信頼性も検証することを忘れずに(第8部で詳述)。
// 07 · MYTHSよくある誤解
- ロジスティック回帰は「古い」アルゴリズムなので、他の機械学習を使うべき
- 誤りです。臨床データのようなサンプル数が少ない場合には他の機械学習は過学習する場合もあり、ロジスティック回帰が同程度の予測精度となることも多い。解釈性・安定性でロジスティック回帰が使われることも多い。
- しきい値は常に 0.5 を使う
- 誤りです。0.5 はクラス比が 50:50 の前提です。不均衡データ(自宅退院 70% : 施設退院 30%)なら 0.5 は不適切となることが多いです。臨床コスト(偽陽性 vs 偽陰性のどちらが問題か)で決めます。
- 係数 β がそのまま「変数の重要度」を表す
- 不正確です。β は変数のスケールに依存する(年齢[0-100]と FIM[13-91]では同じ重要度でも β の絶対値が違う)。標準化してから比較するか、オッズ比を見るのが正しいです。
- 多重共線性があってもロジスティック回帰は使える
- 「使える」が、係数の解釈は破綻します。VIF > 10 の変数があると、係数が大きく揺らぎ、p値も不安定になることが多いです。VIF(多重共線性) を確認し、相関の強い変数の片方を削るか、Lasso(03·03)で対処した方が良い場合があります。
// 08 · WRITING論文での書き方
Methods に記述すべき項目
- ロジスティック回帰の使用理由(解釈性 / ベースライン / リハ研究の標準)
- 正則化(L1 / L2 / なし)の選択と λ(あるいは C)の決定方法
- 標準化の有無と、係数比較を行ったか
- しきい値の決定方法(Youden's J、感度80%固定、Cost-sensitive など)
- 評価指標(AUC、感度、特異度、PPV、NPV、Calibration、95%CI)
- VIF・Hosmer-Lemeshow test など仮定の検証
査読者が刺してくる点
- 「オッズ比とその 95%CI が示されていない」
- 「Calibration plot や Hosmer-Lemeshow test がない」
- 「しきい値の決定根拠が示されていない(0.5 を当然視)」
- 「VIF / 多重共線性の検証がない」
- 「クラス不均衡への対処が示されていない(class_weight='balanced'等)」
// 09 · CHECKLISTチェックリスト
ロジスティック回帰の使い方を点検する6項目。
- 01y が2値で、確率予測を伴う分類タスクである
- 02EPV ≥ 10(イベント数 ÷ 変数数)を満たしている
- 03VIF などで多重共線性を確認した
- 04係数を OR + 95%CI で報告している
- 05しきい値の決定根拠を Methods に記述した
- 06Calibration plot または Hosmer-Lemeshow test で確率の信頼性を確認した
// 10 · QUIZミニクイズ
-
Q1ロジスティック回帰で得られた係数 β = +0.69 を「臨床的解釈」に翻訳すると?
- 「変数1単位で y が 0.69 増える」
- 「変数1単位で y=1 のオッズが exp(0.69) ≈ 2倍」
- 「変数1単位で y=1 の確率が 0.69 倍」
- 「変数のp値が 0.69」
SHOW ANSWER
B. 係数 β はオッズ比 exp(β) として解釈する。β = +0.69 → exp(0.69) ≈ 2 → 「変数1単位増えると y=1 のオッズが約2倍」。これがロジスティック回帰の臨床解釈の核心。 -
Q2「自宅退院の見逃しを最小化したい」リハ研究で、しきい値の調整は?
- 0.5 のままにする(デフォルト)
- 0.5 より低く設定(感度↑)
- 0.5 より高く設定(特異度↑)
- しきい値は予測精度と無関係
SHOW ANSWER
B. 「見逃さない」=「偽陰性を減らす」=「感度を上げる」ためにはしきい値を下げる(0.3〜0.4 など)。その代わり偽陽性(特異度低下)も増えるトレードオフを受け入れる。臨床コストで決める。 -
Q3サンプル数 N=200、自宅退院 100例、変数 30個。最も適切な対処は?
- そのまま 30変数でロジスティック回帰
- EPV=3.3 で過学習リスク大、Lasso で変数選択
- XGBoost なら問題ないので XGBoost に切り替える
- サンプルを増やすしかない
SHOW ANSWER
B. EPV = 100/30 = 3.3 で経験則(EPV ≥ 10)を大きく下回る。Lasso(L1 正則化、03·03)で変数選択して 10 変数程度に絞るのが王道。XGBoost に切り替えてもサンプル数の根本問題は解決しない。
// REF参考文献
- Miyazaki Y, Kawakami M, Kondo K, Hirabe A, Kamimoto T, Akimoto T, et al. Logistic regression analysis and machine learning for predicting post-stroke gait independence: a retrospective study. Sci Rep 2024;14(1):21273.