생존 곡선 비교와 경쟁 위험 — Log-Rank·CIF·Fine-Gray

Woodward Ch.5.5~5.6 — Comparison of Survival Curves & Competing Risks

두 KM 곡선의 통계적 차이를 검정하는 Log-Rank 검정(Mantel-Haenszel)의 수식과 직관, 그리고 KM 의 핵심 가정인 independent censoring 이 깨지는 경쟁 위험(competing risks) 상황을 다룬다. Naive 1-S(t) 의 편향, Cumulative Incidence Function (CIF), Fine-Gray subdistribution hazard 모형까지 추상 → 일상어 → 반사실 3 단계 직관으로 보강한다.

Experimentation
Epidemiology
저자

Kwangmin Kim

공개

2026년 05월 08일

1 5.5 — Comparison of Survival Curves

두 KM 곡선이 시각적으로 분리되어 보일 때, 그 차이가 통계적으로 유의한지 어떻게 판정하는가. Log-rank 검정 이 표준 도구다 (Woodward, 2014, Ch.5.5).

정의: Log-Rank 검정 (Mantel-Haenszel form)

각 사건 시점 \(t_i\) 에서 두 군 (1, 2) 의 위험 인구 \(n_{1i}, n_{2i}\) 와 사건 수 \(d_{1i}, d_{2i}\) 를 정의. 군 1 의 기대 사건 수 (귀무가설 — 두 군 위험률 동일) :

\[ E_{1i} = d_i \cdot \frac{n_{1i}}{n_i} \quad \text{where } d_i = d_{1i} + d_{2i}, \, n_i = n_{1i} + n_{2i} \]

분산: \[ V_i = \frac{n_{1i} n_{2i} d_i (n_i - d_i)}{n_i^2 (n_i - 1)} \]

검정 통계량: \[ \chi^2 = \frac{\left( \sum_i (d_{1i} - E_{1i}) \right)^2}{\sum_i V_i} \]

자유도 1 의 카이제곱 분포를 따른다 (귀무가설 하).

1.1 수식의 의미 — 매 시점의 “기대 vs 관찰”

직관 3 단계: Log-Rank 의 누적 편차
  • 추상: \(d_{1i} - E_{1i}\) 는 시점 \(t_i\) 에서 군 1 이 무작위 분배(비례)보다 사건을 더 또는 덜 겪었는가의 부호. 귀무 하에서 평균 0.
  • 일상어 비유: 농구 경기에서 매 쿼터마다 “기대 점수 vs 실제 점수” 의 차이를 누적. 한 쿼터의 운보다 누적 패턴이 진성 실력 차이를 드러냄.
  • 반사실: 두 군의 위험률이 같다면 매 시점에 사건이 비례 분배 → 누적 편차 0 근처. 다르면 한 군에 편향 누적 → 큰 통계량.

1.2 비례 위험 가정 하에서 가장 강한 검정

Log-rank 는 proportional hazards 가정 하에 가장 강한 검정력을 가진다. 즉 \(h_1(t)/h_2(t) = \text{const}\) 가정.

가정 위반: Crossing Hazards

가설: 새 약이 초기에 큰 효과(낮은 위험률) 를 주지만 1 년 후 효과 소멸. 두 군의 hazard 가 1 년 시점에 교차.

3 단계 직관:

  • 추상: \(h_1(t)/h_2(t)\) 가 시간에 따라 1 위/아래로 이동. 비례 위험 위반.
  • 일상어 비유: 마라톤에서 한 주자가 초반 빠르고 후반 느린 반면 다른 주자가 초반 느리고 후반 빠르면, 누적 거리는 비슷하나 어느 쪽이 빠른지 단순 비교 어려움.
  • 반사실: 비례 위험이 깨질 때 log-rank 는 시간 평균 효과만 보아 진성 패턴 (cross-over) 을 가린다. 검정력 ↓ 또는 false negative.

해법: 가중 log-rank (Wilcoxon-Gehan-Breslow, Tarone-Ware), 시간 의존 Cox, restricted mean survival time (RMST).

1.3 Stratified Log-Rank — 교란 통제

정의: Stratified Log-Rank

연령·성별 같은 교란 변수 \(S\) 의 strata 별로 Log-rank 통계량을 계산하고 합산.

\[ \chi^2_{\text{strat}} = \frac{\left( \sum_s \sum_i (d_{1i,s} - E_{1i,s}) \right)^2}{\sum_s \sum_i V_{i,s}} \]

각 stratum 안에서 두 군이 비교되므로, stratum 간의 baseline 위험률 차이가 통제된다. 이는 Cohort 의 Mantel-Haenszel 일반화.

1.4 시각적 해석 — Pointwise CI 와 차이의 유의성

KM 곡선의 음영 (pointwise CI) 이 두 군에서 겹치지 않는다고 해서 곧 통계적 유의를 의미하지 않는다.

직관: Pointwise CI vs Log-Rank
  • Pointwise CI: 각 시점에 진성 \(S(t)\) 가 95% 확률로 그 안.
  • Log-Rank: 전 시간 축에서 두 곡선의 진성 차이가 0 인가의 검정.

두 곡선이 한 시점에서 시각적으로 떨어져 있어도 log-rank p-값이 0.2 일 수 있음 — 다른 시점에서 비슷하면 누적 편차가 작아짐.

2 5.6 — Competing Risks

KM 의 핵심 가정은 censoring 과 사건이 독립이라는 것이다. 그러나 경쟁 위험(competing risks) 은 이 가정을 직접 깬다.

정의: 경쟁 위험 (Competing Risk)

관심 사건과 다른 사건이 같은 사람에서 발생할 수 있고, 다른 사건의 발생이 관심 사건 발생을 영구히 차단하는 상황 (Woodward, 2014, Ch.5.6).

예시:

  • 관심: 폐암 사망 / 경쟁: 심혈관 사망 (전자가 차단)
  • 관심: 첫 결혼 / 경쟁: 사망
  • 관심: 골절 / 경쟁: 사망 (특히 고령)

2.1 KM 이 깨지는 이유

가정 위반: Independent Censoring

KM 은 censoring 시점이 사건 시점과 독립이라 가정. 경쟁 위험은 이를 위반.

3 단계 직관:

  • 추상: \(T_{\text{관심}} \perp T_{\text{경쟁}}\) — 관심 사건과 경쟁 사건이 독립일 필요. 그러나 같은 사람에서 두 사건이 발생할 수 있고, 둘 다 사람의 건강 상태에 의존하므로 일반적으로 종속.
  • 일상어 비유: 등산에서 정상 도달(관심)과 부상으로 하산(경쟁) 이 모두 체력에 의존. 부상자를 단순 censoring 으로 처리하면 “정상 도달했다” 가정에 묻혀 도달률이 부풀려짐.
  • 반사실: 경쟁 위험을 무시하고 KM 만 적용하면, \(1 - \hat S(t)\) 가 진성 누적 발생 확률을 과대 추정. 가상의 시나리오 (경쟁 위험 0) 에서의 발생 확률을 추정하는 것이 됨.

2.2 두 가지 추정량 — KM vs CIF

2.2.1 1. Naive 1 - KM (Cause-Specific Marginal)

경쟁 사건을 censoring 처리한 KM 으로부터 \(1 - \hat S_k(t)\).

문제: 이는 “다른 모든 경쟁 사건이 0 이었다면 발생할 누적 확률” 의 추정 — 실제 데이터의 누적 사건율과 다르다.

2.2.2 2. Cumulative Incidence Function (CIF) — Aalen-Johansen

정의: Cumulative Incidence Function (CIF)

원인 \(k\) 의 누적 발생 확률: \[ \hat F_k(t) = \sum_{t_i \le t} \hat S(t_i^-) \cdot \frac{d_{ki}}{n_i} \]

여기서 \(\hat S(t_i^-) = \prod_{t_j < t_i} (1 - d_j / n_j)\) 는 모든 원인 통합 KM (시점 \(t_i\) 직전).

\(d_{ki}\) 는 시점 \(t_i\) 에서 원인 \(k\) 의 사건 수.

해석: \(\hat F_k(t)\) 는 “시점 \(t\) 까지 원인 \(k\) 의 사건이 발생한 비율” 의 진성 추정. 모든 경쟁 사건 \(\sum_k F_k(t) + S(t) = 1\).

2.3 직관 3 단계 — CIF 의 핵심

  • 추상: \(S(t_i^-)\) 가 “시점 \(t_i\) 까지 모든 사건 미발생자” 분율. 거기서 시점 \(t_i\) 에 원인 \(k\) 사건이 새로 발생할 비율을 곱하여 누적.
  • 일상어 비유: 100 명이 출발 → 시점 5 까지 70 명이 무사 → 시점 5 에 원인 A 로 5 명, 원인 B 로 3 명 사망. CIF_A 는 5 명이 70 명 출발자에서 발생한 비율로 누적.
  • 반사실: KM 이 원인 A 만 보고 원인 B 를 censoring 처리하면, 시점 5 에서 70 명 중 5 명 → 5/70 ≈ 7%. 실제로는 100 명에서 5 명 → 5%. 차이가 7% vs 5% 의 형태로 KM 이 과대 추정.

2.4 Cause-Specific Hazard vs Subdistribution Hazard

경쟁 위험에서 두 가지 hazard 함수.

2.4.1 Cause-Specific Hazard

\[ h_k^{cs}(t) = \lim_{\Delta t \to 0} \frac{P(t \le T < t + \Delta t, \text{cause} = k \mid T \ge t)}{\Delta t} \]

분모: 모든 사건 미발생자. 직관적으로 “지금 무사한 자가 다음 순간 원인 \(k\) 를 겪을 비율”.

2.4.2 Subdistribution Hazard (Fine-Gray)

\[ h_k^{sd}(t) = \lim_{\Delta t \to 0} \frac{P(t \le T < t + \Delta t, \text{cause} = k \mid T \ge t \, \text{or} \, (T < t \, \text{and cause} \neq k))}{\Delta t} \]

분모: 원인 \(k\) 의 사건이 아직 안 일어난 자 (다른 원인으로 사망한 자도 분모에 남김). 직관적으로 “원인 \(k\) 의 누적 발생 확률이 시간에 따라 어떻게 변하는가” 를 직접 모형화.

직관 3 단계: 두 hazard 의 차이
  • 추상: Cause-specific 는 즉각적 위험률, subdistribution 은 누적 발생 확률의 변화율. 전자는 사망 후 분모 제외, 후자는 사망 후도 분모에 남김.
  • 일상어 비유: 등산에서 정상 도달 위험률을 (1) 살아있는 등산객 중에서만 vs (2) 부상자도 분모에 포함하여 측정. 두 비율은 다르고, 둘 다 의미 있다.
  • 반사실: Cause-specific Cox 모형은 etiology(원인 메커니즘)에 강하고, subdistribution (Fine-Gray) 모형은 prediction(예측)에 강하다. 두 모형의 HR 해석이 달라 혼동 주의.

2.5 Fine-Gray Model

\[ h_k^{sd}(t \mid \mathbf{x}) = h_{0k}^{sd}(t) \exp(\beta^T \mathbf{x}) \]

Cox PH 의 cause-specific 버전. 직접적으로 CIF 의 효과를 모형화.

2.6 어느 모형을 언제 쓰는가

목표 모형 이유
인과 메커니즘 (etiologic) Cause-specific Cox 위험률의 즉각 변화
환자 예측 (prognostic) Fine-Gray (subdistribution) 누적 발생 확률 변화
두 시각 모두 양쪽 모형 보고 결과의 강건성

2.7 사례 — 골절과 사망의 경쟁 위험

예시: 고령 여성 골반 골절 코호트

가설: 70 세 여성 1,000 명 추적 — 5 년 안에 골반 골절 발생률 측정.

5 년 사이에: - 골절 발생: 80 명 - 골절 없이 사망: 200 명

KM 추정 (사망을 censoring): \(1 - \hat S(5) \approx 80 / 800 = 10\%\) (단순 추정).

CIF 추정: \(\hat F_{\text{골절}}(5) \approx 80 / 1000 = 8\%\).

차이 2%p — 사망이 골절을 차단하므로 진성 발생률이 KM 보다 낮다. 임상 의사가 환자에게 “5 년 안에 골절 위험” 을 말할 때 어느 수치가 적절한가? CIF 가 정직하다.

3 코드 예시 — Log-Rank, CIF, Fine-Gray

import numpy as np
import pandas as pd
from lifelines import KaplanMeierFitter
from lifelines.statistics import logrank_test
from lifelines import CoxPHFitter

# Lifelines 의 경쟁 위험은 다른 패키지 (scikit-survival, R 의 cmprsk) 가 더 강력
# 여기서는 핵심 흐름만

np.random.seed(42)
n = 1000

# 가상 데이터: 두 사건 (관심: 1, 경쟁: 2)
factor = np.random.binomial(1, 0.4, n)
true_T_1 = np.random.exponential(scale=1.0/0.05, size=n)
true_T_2 = np.random.exponential(scale=1.0/0.04, size=n)
true_T_1[factor == 1] /= 1.5

# 더 빨리 발생하는 사건이 관측됨
T = np.minimum(true_T_1, true_T_2)
cause = np.where(true_T_1 < true_T_2, 1, 2)

# Censoring at t=10
C = 10.0
event_indicator = (T <= C).astype(int)  # 사건 발생 여부
T_obs = np.minimum(T, C)
cause_obs = np.where(event_indicator == 1, cause, 0)  # 0 = censored

df = pd.DataFrame({"T": T_obs, "cause": cause_obs, "factor": factor})

# 1. Log-Rank — cause 1 vs censored
event_cause1 = (df.cause == 1).astype(int)
lr_cause1 = logrank_test(
    df.loc[df.factor == 1, "T"], df.loc[df.factor == 0, "T"],
    event_observed_A=event_cause1[df.factor == 1].values,
    event_observed_B=event_cause1[df.factor == 0].values,
)
print(f"Log-Rank (cause 1, naive): p = {lr_cause1.p_value:.4f}")

# 2. Naive KM 으로 1-S(t) — 과대 추정 가능
kmf_factor = KaplanMeierFitter()
kmf_factor.fit(
    df.loc[df.factor == 1, "T"],
    event_observed=event_cause1[df.factor == 1].values,
    label="Factor",
)
print(f"\nNaive 1 - KM (factor, t=5): {1 - kmf_factor.survival_function_at_times(5.0).values[0]:.3f}")

# 3. CIF — Aalen-Johansen 추정 (lifelines 12+ 의 AalenJohansenFitter 또는 cmprsk)
# from lifelines import AalenJohansenFitter
# aj = AalenJohansenFitter()
# aj.fit(durations=df["T"], event_observed=df["cause"], event_of_interest=1)
# print(aj.cumulative_density_)

# 4. Fine-Gray — sklearn-survival 의 FineGrayModel 또는 R 의 cmprsk
# from sksurv.linear_model import FineGray  # (gathered from scikit-survival)

주의: lifelines 의 기본 KM 은 경쟁 위험을 직접 다루지 않는다. AalenJohansenFitter (lifelines 0.27+) 또는 scikit-survival, R cmprsk 패키지가 정확한 CIF/Fine-Gray 분석을 제공.

4 결론 — Ch.5.5~5.6 의 메시지

도구 목적 주요 가정
Log-Rank 두 KM 곡선 차이 검정 Proportional hazards
Stratified Log-Rank 교란 통제 Stratum 내 PH
Naive 1 - KM (cause \(k\)) 가상 시나리오의 누적 확률 경쟁 위험 0 가정
CIF (Aalen-Johansen) 진성 누적 발생 확률 없음 (비모수)
Cause-Specific Cox 메커니즘 모형 PH per cause
Fine-Gray 예측 모형 Subdistribution PH

경쟁 위험이 의심되면 CIFFine-Gray 가 표준. KM 은 모든 경쟁 사건이 0 인 가상 시나리오를 추정하므로, 환자에게 직접 보여주기에는 부적절.

다음 글(B14) 에서는 가변 추적의 또 다른 분석 도구인 person-year 방법과, 긴 추적의 시간·연령·코호트 분리 분석인 APC 모형 을 다룬다.

5 관련 주제

선행

후속

다른 카테고리

Subscribe

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