## はじめに
ROC(Receiver Operating Characteristic)解析は、二値分類モデルの性能を評価する標準的な手法です。医学研究では診断テストの精度評価、疫学研究ではリスク予測モデルの評価に広く用いられています。
Hosmer & LemeshowのStata標準データセット「lbw」を使用して、ROC解析の基本とYouden Indexを用いた最適カットオフ値の決定方法を実践的に解説します。
## データセットの概要
lbwデータセットは、低出生体重児(出生時体重2500g未満)の出産に関連する要因を調査した研究データです。189人の妊婦のデータが含まれており、母親の年齢、体重、喫煙歴、高血圧歴などの情報から低出生体重児出産のリスクを予測することが目的です。
主要な変数は以下の通りです:
- `low`: 低出生体重(1=2500g未満、0=2500g以上)- 目的変数
- `age`: 母親の年齢
- `lwt`: 最終月経時の体重
- `race`: 人種(1=白人、2=黒人、3=その他)
- `smoke`: 妊娠中の喫煙(1=あり、0=なし)
- `ht`: 高血圧歴(1=あり、0=なし)
- `ui`: 子宮収縮異常(1=あり、0=なし)
## ROC解析の理論的背景
ROC解析は、二値分類問題において様々なカットオフ値での分類性能を評価する手法です。
### 基本概念
**感度(Sensitivity)**: 真陽性率。実際に陽性のケースのうち、正しく陽性と判定された割合
```
感度 = 真陽性 / (真陽性 + 偽陰性)
```
**特異度(Specificity)**: 真陰性率。実際に陰性のケースのうち、正しく陰性と判定された割合
```
特異度 = 真陰性 / (真陰性 + 偽陽性)
```
**ROC曲線**: 横軸に(1-特異度)、縦軸に感度をプロットした曲線。様々なカットオフ値での分類性能を視覚化
**AUC(Area Under the Curve)**: ROC曲線下の面積。0.5から1.0の値を取り、1.0に近いほど優れた分類性能を示す
## Youden Indexとは
Youden Indexは、感度と特異度のバランスを考慮した最適カットオフ値を決定する指標です。
```
Youden Index = 感度 + 特異度 - 1
```
この指標は-1から1の値を取り、1に近いほど優れた分類性能を示します。Youden Indexを最大化するカットオフ値が、感度と特異度のバランスを最適化する点として推奨されます。
## 実践:Stataによる解析
### データの読み込みと基本統計
```stata
clear all
webuse lbw, clear
* データの確認
describe
```
まず、データの構造を確認します。この段階でデータセットの変数名、型、ラベルなどを把握し、以降の解析の準備を行います。
### ロジスティック回帰モデルの構築
```stata
* 母親の年齢を用いた単変量ロジスティック回帰
logistic low age
* 多変量モデル(必要に応じて)
logistic low age lwt smoke ht ui
```
母親の年齢を説明変数とした単純なロジスティック回帰モデルから始めます。単変量解析で基本的な関連を確認した後、複数の要因を含めた多変量解析により、より現実的な予測モデルを構築します。
### ROC曲線の描画
```stata
* ROC曲線の描画
lroc, aspectratio(1) msymbol(none) name(g1, replace)
```
`lroc`コマンドでROC曲線を描画し、AUC値も表示されます。`aspectratio(1)`により正方形のグラフが作成され、対角線(AUC=0.5)との比較が容易になります。`msymbol(none)`でマーカーを非表示にし、滑らかな曲線のみを表示します。
### 感度・特異度の計算とYouden Indexの算出
```stata
* 感度・特異度の計算
lsens, genprob(prob) gensens(sens) genspec(spec) name(g2, replace)
* Youden indexの計算
gen youden = sens + spec - 1
* Youden indexの最大値とその時のカットオフ値を特定
gsort -youden
list prob sens spec youden in 1/10
```
`lsens`コマンドは、予測モデルから得られる各予測確率値に対して感度と特異度を計算し、新しい変数として保存します。これが重要なポイントで、単に画面に結果を表示するだけでなく、**操作可能なデータとして保存**されます。
- `genprob(prob)`: 各観測値の予測確率を`prob`変数に保存
- `gensens(sens)`: 各カットオフ値での感度を`sens`変数に保存
- `genspec(spec)`: 各カットオフ値での特異度を`spec`変数に保存
Youden Indexを計算し、その最大値を与えるカットオフ値を特定します。上位10個の結果を表示することで、最適値周辺の状況も把握できます。
### 最適カットオフ値の詳細確認
```stata
* 最適カットオフ値の表示
display "最適カットオフ値: " prob[1]
display "最大Youden index: " youden[1]
* より詳しい確認
gsort -youden
local optimal_cutoff = prob[1]
display "実際のカットオフ値: " `optimal_cutoff'
display "その時の感度: " sens[1]
display "その時の特異度: " spec[1]
display "実行されるコマンド: estat class, cutoff(" `optimal_cutoff' ")"
```
`prob[1]`は具体的な数値(例:0.234)であり、この値が後続の`estat class`コマンドで実際に使用されます。
### 分類性能の詳細評価
```stata
* 異なるカットオフ値での分類性能比較
estat class, cutoff(0.5)
estat class, cutoff(0.3)
estat class, cutoff(`=prob[1]')
```
カットオフ値として指定している数値(0.5、0.3など)は、ロジスティック回帰モデルから算出された各症例の陽性確率(低出生体重児出産の予測確率)に対する閾値です。これらは、ロジスティック回帰モデルから算出された各症例の陽性確率(低出生体重児出産の予測確率)に対する閾値です。
例えば、`cutoff(0.5)`は「予測確率が0.5(50%)以上の症例を陽性(低出生体重児出産あり)と分類し、0.5未満を陰性(低出生体重児出産なし)と分類する」という意味です。同様に、`cutoff(0.3)`では予測確率30%以上で陽性と判定するため、より多くの症例が陽性に分類され、感度が高くなる傾向があります。
最後の`cutoff(`=prob[1]')`について詳しく説明すると、例えば`prob[1]`の値が0.234だった場合、実際に実行されるコマンドは:
```stata
estat class, cutoff(0.234)
```
となります。つまり、``=prob[1]'`の部分が、Youden Indexを最大化する具体的な数値(この例では0.234)に置き換わって実行されます。この値は統計的に感度と特異度のバランスが最も良い点を表しています。
各カットオフ値における混同行列、感度、特異度、陽性的中率、陰性的中率が表示され、カットオフ値の変更が分類性能に与える影響を具体的に確認できます。
## 結果の解釈と臨床的意義
### Youden Indexの限界と臨床的判断
Youden Indexは感度と特異度のバランスを取った一つの指標として有用ですが、実際の臨床現場では必ずしも最適な選択とは限りません。臨床的な判断では、以下のような状況に応じて感度または特異度を優先する必要があります。
### 感度を優先すべき場面
**スクリーニング検査**: がんの早期発見など、見逃しが致命的な結果をもたらす可能性がある場合
**感染症の初期対応**: COVID-19のような感染拡大防止が重要な疾患では、偽陰性を最小化することが公衆衛生上重要
**救急医療**: 心筋梗塞や脳梗塞など、迅速な診断と治療が予後を左右する場合
これらの場面では、偽陽性が増加しても、真の陽性ケースを見逃すリスクを最小化することが優先されます。
### 特異度を優先すべき場面
**確定診断**: 侵襲的な検査や治療を決定する前段階では、偽陽性による不必要な介入を避けることが重要
**希少疾患の診断**: 有病率が低い疾患では、特異度が低いと偽陽性が多発し、陽性的中率が極端に低下
**高コストな検査**: MRIやPET検査など、費用対効果を考慮する必要がある場合
**心理的影響**: がんの疑いなど、偽陽性が患者に重大な心理的負担をもたらす場合
これらの場面では、感度がある程度犠牲になっても、偽陽性を最小化することが重要です。
## 留意点
**サンプルサイズ**: 小さなサンプルサイズではAUC値の信頼区間が広くなり、推定が不安定になる可能性があります
**過適合**: 説明変数が多すぎる場合、訓練データに過適合し、新しいデータでの性能が低下する可能性があります
**外部妥当性**: 開発したモデルが他の集団でも同様の性能を示すかの検証が重要です
## 参考コード(完全版)
```stata
clear all
webuse lbw, clear
* データの確認
describe
* 母親の年齢を用いた単変量ロジスティック回帰
logistic low age
* 多変量モデル(必要に応じて)
logistic low age lwt smoke ht ui
* ROC曲線の描画
lroc, aspectratio(1) msymbol(none) name(g1, replace)
* 感度・特異度の計算
lsens, genprob(prob) gensens(sens) genspec(spec) name(g2, replace)
* Youden indexの計算
gen youden = sens + spec - 1
* Youden indexの最大値とその時のカットオフ値を特定
gsort -youden
list prob sens spec youden in 1/10
* 最適カットオフ値の表示
display "最適カットオフ値: " prob[1]
display "最大Youden index: " youden[1]
* より詳しい確認(オプション)
local optimal_cutoff = prob[1]
display "実際のカットオフ値: " `optimal_cutoff'
display "その時の感度: " sens[1]
display "その時の特異度: " spec[1]
* 異なるカットオフ値での分類性能比較
estat class, cutoff(0.5)
estat class, cutoff(0.3)
estat class, cutoff(`=prob[1]')
```