Validity 와 Predictive Value

Schulz & Grimes Ch.8.2 — Sensitivity, Specificity & PPV/NPV

진단·선별 검사의 핵심 4 측도 (Sn, Sp, PPV, NPV) 의 수식 유도, Bayes 변환을 통한 PPV 의 prevalence 의존, 그리고 같은 검사가 인구에 따라 다른 PPV 를 갖는 이유를 추상 → 일상어 → 반사실 3 단계 직관으로 풀어낸다. ROC 곡선과 cut-point 선택의 trade-off 도 함께 본다.

Experimentation
Epidemiology
저자

Kwangmin Kim

공개

2026년 05월 08일

1 4 측도의 수식 — 2x2 표에서 시작

질병 + (D+) 질병 - (D-)
검사 + (T+) True Positive (TP) False Positive (FP)
검사 - (T-) False Negative (FN) True Negative (TN)
정의: 4 측도

\[ \text{Sensitivity} = \frac{TP}{TP + FN} = P(T+ \mid D+) \] \[ \text{Specificity} = \frac{TN}{TN + FP} = P(T- \mid D-) \] \[ \text{PPV} = \frac{TP}{TP + FP} = P(D+ \mid T+) \] \[ \text{NPV} = \frac{TN}{TN + FN} = P(D- \mid T-) \]

1.1 두 짝의 직교성

직관 3 단계: Sn/Sp vs PPV/NPV
  • 추상: Sn/Sp 는 검사 자체의 특성 (검사가 양성 사례를 얼마나 잘 식별하는가). PPV/NPV 는 인구 + 검사 결합 (양성 결과의 진성 가능성).
  • 일상어 비유: 화재경보기의 “감도” 와 “특이도” 는 기기 특성. “이 알람이 진짜 화재일 가능성” 은 그 기기 + 그 빌딩의 화재 빈도 결합.
  • 반사실: Sn = 99%, Sp = 99% 검사도 prevalence 1% 면 PPV = 50% (이래서 99% 검사가 50% 진성 양성).

2 Sensitivity vs Specificity — Trade-off

가정 위반: 한 측도만 본다

Sn 과 Sp 는 cut-point 의 함수. 연속 검사값 (예: 혈당, troponin) 의 경우 cut-point 를 낮추면 Sn ↑ Sp ↓, 높이면 그 반대.

ROC 곡선 — 모든 cut-point 의 (1-Sp, Sn) 쌍.

3 단계 직관:

  • 추상: \(\text{Likelihood ratio}^+ = \text{Sn} / (1 - \text{Sp})\). ROC 곡선의 각 점.
  • 일상어 비유: 시험 합격 기준 점수를 낮추면 합격자 ↑ (Sn ↑) 이지만 부적격자도 합격 (Sp ↓).
  • 반사실: ROC 곡선의 area = AUC — cut-point 무관 검사 능력 측정.

3 Bayes 변환 — PPV 의 prevalence 의존

정의: PPV 의 Bayes 형식

\[ \text{PPV} = \frac{\text{Sn} \cdot P(D)}{\text{Sn} \cdot P(D) + (1 - \text{Sp}) (1 - P(D))} \]

또는 odds 형식: \[ \text{Posttest odds} = \text{Pretest odds} \cdot \text{LR}^+ \]

여기서 \(\text{LR}^+ = \text{Sn} / (1 - \text{Sp})\).

3.1 직관 3 단계 — 왜 prevalence 가 결정적인가

  • 추상: PPV 는 사후 확률 (Bayes posterior). 사전 확률 P(D) 가 변하면 같은 검사도 다른 사후 확률 산출.
  • 일상어 비유: 의심 진료가 “이 동네 결핵 환자 많은가” 에 따라 양성 결과 해석이 달라짐. 같은 X-ray 라도 인구 baseline 따라.
  • 반사실: Prevalence 0 이면 PPV 도 0 (모든 양성이 false). Prevalence 100% 면 PPV = 100% (모든 양성이 진성).

3.2 사례 — 99/99 검사의 PPV

Prevalence PPV (Sn=99%, Sp=99%)
0.001 (0.1%) 9% — 양성 결과의 91% 가 false
0.01 (1%) 50%
0.1 (10%) 92%
0.5 (50%) 99%

99% 정확도 검사라도 희귀병 인구 (0.1%) 에서는 양성 결과의 91% 가 거짓.

가정 위반: “99% 정확 검사 = 99% 진성”

가설: COVID 검사가 99% 정확. 양성 결과 = 99% 진성?

진성: prevalence 가 0.5% 라면 PPV = 33% — 양성 결과의 67% 가 거짓.

3 단계 직관:

  • 추상: 사전 확률을 계산식에 넣어야 진성 PPV 산출.
  • 일상어 비유: 적은 도둑 인구에서 보안 알람의 양성 신호는 다수 false alarm.
  • 반사실: High-risk pool (감염 의심자) 에서 검사 → prevalence ↑ → PPV ↑.

4 Likelihood Ratio — 인구 무관 측도

정의: LR+ 와 LR-

\[ \text{LR}^+ = \frac{\text{Sn}}{1 - \text{Sp}} = \frac{P(T+ \mid D+)}{P(T+ \mid D-)} \] \[ \text{LR}^- = \frac{1 - \text{Sn}}{\text{Sp}} = \frac{P(T- \mid D+)}{P(T- \mid D-)} \]

활용: \[ \text{Posttest odds} = \text{Pretest odds} \cdot \text{LR} \]

직관 3 단계: LR 의 강점
  • 추상: LR 은 검사 자체의 정보량 — prevalence 무관. 같은 검사가 모든 인구에서 같은 LR.
  • 일상어 비유: 카지노 게임의 ratio 는 게임 자체의 특성. 어느 도시에서 하든 같은 ratio.
  • 반사실: PPV 는 prevalence 따라 변하지만, LR 은 일관 → 다양한 인구에 적용 가능.

상세한 LR 분석은 SCH Ch.9 (B38~B42) 에서.

5 ROC 곡선 — Cut-point 의 trade-off

True Positive Rate (Sn)
1.0 │                         ← Random (0.5)
    │            curved shape
0.8 │      ↗
    │   ↗
0.6 │↗
    │
0.4 │
    │
0.2 │
    │
0.0 └────────────────────────→ False Positive Rate (1-Sp)
    0.0  0.2  0.4  0.6  0.8  1.0

AUC = ROC 곡선 아래 면적. - 0.5 = random. - 1.0 = perfect. - Hosmer 가이드: 0.7~0.8 = acceptable, 0.8~0.9 = excellent, > 0.9 = outstanding.

직관: ROC + Cut-point 선택
  • 추상: AUC 는 cut-point 무관 능력. 임상에서는 cut-point 를 정해야 — 비용·이익에 따라.
  • 일상어 비유: 시험 합격선 결정. 합격자 多 vs 부적격 합격자 ↓ 의 trade-off.
  • 반사실: 비용·이익이 비대칭이면 cut-point 도 비대칭. 예: 암 선별은 false negative 비용 ↑ → cut-point 낮춰 Sn ↑.

6 코드 — Sn/Sp/PPV/NPV/LR + ROC

import numpy as np
from sklearn.metrics import roc_auc_score, roc_curve
import matplotlib.pyplot as plt

np.random.seed(42)

# 가상 데이터: 1,000 명, prevalence 10%
n = 1000
D = np.random.binomial(1, 0.10, n)

# 검사 결과 (D+ 는 평균 ↑, D- 는 평균 ↓ 인 분포)
test_score = np.where(D == 1, np.random.normal(2, 1, n), np.random.normal(0, 1, n))

# Cut-point 1.0 적용
T = (test_score >= 1.0).astype(int)

# 2x2 표
TP = ((T == 1) & (D == 1)).sum()
FP = ((T == 1) & (D == 0)).sum()
FN = ((T == 0) & (D == 1)).sum()
TN = ((T == 0) & (D == 0)).sum()

Sn = TP / (TP + FN)
Sp = TN / (TN + FP)
PPV = TP / (TP + FP)
NPV = TN / (TN + FN)
LR_pos = Sn / (1 - Sp)
LR_neg = (1 - Sn) / Sp

print(f"Sn = {Sn:.3f}, Sp = {Sp:.3f}")
print(f"PPV = {PPV:.3f}, NPV = {NPV:.3f}")
print(f"LR+ = {LR_pos:.2f}, LR- = {LR_neg:.2f}")

# AUC
auc = roc_auc_score(D, test_score)
print(f"AUC = {auc:.3f}")

7 결론

Sn/Sp 는 검사 특성, PPV/NPV 는 검사 + 인구 결합. PPV 가 prevalence 에 강하게 의존하므로 양성 결과 해석은 인구 baseline 점검 후. LR 이 prevalence 무관 도구로 보완.

다음 글(B36)에서는 두 검사 결합 (sequential vs parallel) 의 통계를 본다.

8 관련 주제

Subscribe

Enjoy this blog? Get notified of new posts by email: