1 정의
생존 분석(Survival Analysis)은 관심 사건(event)이 발생하기까지의 시간을 결과 변수로 다루는 통계적 방법론의 총칭이다.
- 결과 변수: 사건 발생까지의 시간 \(T \geq 0\) (생존 시간, survival time)
- 사건(event): 사망, 질병 발생, 재발, 이탈, 고장 등 연구 목적에 따라 정의
- 핵심 특징: 중도절단(censoring) 데이터를 체계적으로 처리할 수 있다
“생존”이라는 이름은 의학에서 유래했으나, 사건이 반드시 사망일 필요는 없다. “고장까지의 시간(time-to-failure)” 또는 “사건까지의 시간(time-to-event)”이라고도 부른다 (Kleinbaum & Klein, 2012, Ch.1).
2 개념 및 원리
2.1 생존 분석이 다루는 문제
일반적인 회귀 분석은 \(Y = f(X) + \epsilon\) 형태로 결과 변수를 모형화한다. 생존 분석도 결과 변수가 있다는 점에서 비슷하지만, 두 가지 근본적 차이가 있다:
- 결과 변수가 “시간”: 음수가 불가능하고(\(T \geq 0\)), 대부분 오른쪽으로 치우친(right-skewed) 분포를 따른다
- 중도절단(censoring): 모든 대상의 사건 발생 시점을 관측할 수 없다
이 두 가지 특성 때문에 일반적인 선형 회귀나 로지스틱 회귀로는 적절히 분석할 수 없으며, 생존 분석 고유의 방법론이 필요하다.
2.2 중도절단 (Censoring)
중도절단은 대상의 정확한 생존 시간을 알 수 없는 상황을 뜻한다.
추적 시작 추적 종료
| |
A ────────── X (사건 발생, T=5주) |
B ──────────────────────────────────── | (중도절단, T≥12주)
C ─────── ↑ (자발적 탈퇴, T≥3.5주) |
D ───────────────────────── | (중도절단, T≥8주)
E ────────── ↑ (추적 실패, T≥6주)|
F ── X (사건 발생, T=3.5주)|
X = 사건 발생, ↑ = 중도절단 시점
중도절단이 발생하는 세 가지 이유 (Kleinbaum & Klein, 2012, Ch.1):
- 연구 종료: 연구 기간이 끝날 때까지 사건이 발생하지 않은 경우
- 추적 실패(lost to follow-up): 연락 두절, 이사 등으로 추적이 불가능한 경우
- 자발적 탈퇴(withdrawal): 부작용, 사망(관심 사건이 아닌 경우) 등으로 연구에서 이탈한 경우
2.2.1 중도절단의 유형
| 유형 | 정의 | 예시 |
|---|---|---|
| 우측 절단(Right censoring) | 실제 생존 시간이 관측 시간 이상 | 연구 종료 시점까지 사건 미발생 |
| 좌측 절단(Left censoring) | 사건이 관측 시작 이전에 이미 발생 | HIV 검사 양성이지만 감염 시점 불명 |
| 구간 절단(Interval censoring) | 사건 발생이 두 관측 시점 사이에 있음 | 정기 검진 사이에 질병 발생 |
대부분의 생존 분석은 우측 절단(right censoring)을 다루며, 이 시리즈에서도 우측 절단을 기본으로 한다.
2.2.2 중도절단의 가정
생존 분석이 유효하려면 중도절단에 대한 가정이 필요하다:
- 독립 절단(independent censoring): 절단 여부가 생존 시간과 독립이다
- 비정보적 절단(noninformative censoring): 절단된 대상의 생존 시간 분포가 절단되지 않은 대상과 동일하다
- 무작위 절단(random censoring): 절단 시점이 무작위이다
이 가정이 위반되면 추정량에 편향이 발생한다. 예를 들어, 상태가 나쁜 환자가 선택적으로 탈퇴하면(informative censoring) 생존율이 과대 추정된다.
2.3 핵심 함수: 생존 함수와 위험 함수
생존 분석의 두 핵심 함수는 생존 함수(survival function)와 위험 함수(hazard function)이다. 이 두 함수는 서로 일대일 관계에 있어, 하나를 알면 다른 하나를 유도할 수 있다.
2.3.1 생존 함수 \(S(t)\)
생존 함수 \(S(t)\) 는 시점 \(t\) 까지 사건이 발생하지 않을 확률이다:
\[ S(t) = P(T > t) = 1 - F(t) \]
여기서 \(F(t) = P(T \leq t)\) 는 누적 분포 함수(CDF)이다.
생존 함수의 성질:
- \(S(0) = 1\): 시점 0에서는 모든 대상이 생존해 있다
- \(S(\infty) = 0\): 충분히 오랜 시간이 지나면 모든 대상에게 사건이 발생한다
- \(S(t)\) 는 단조 감소(non-increasing)한다
- \(S(t)\) 는 계단 함수(step function)로 추정되는 것이 일반적이다 (Kaplan-Meier)
2.3.2 위험 함수 \(h(t)\)
위험 함수 \(h(t)\) 는 시점 \(t\) 까지 생존한 대상이 \(t\) 직후 극히 짧은 시간 \(\Delta t\) 내에 사건을 경험할 순간적 위험률(instantaneous rate)이다:
\[ h(t) = \lim_{\Delta t \to 0} \frac{P(t \leq T < t + \Delta t \mid T \geq t)}{\Delta t} \]
위험 함수의 성질:
- \(h(t) \geq 0\) (음수 불가)
- 확률이 아니므로 1을 초과할 수 있다 (rate이다)
- 형태에 따라 질병/사건의 특성을 파악할 수 있다:
- 상수: 사건 발생 위험이 시간에 무관 (지수 분포)
- 단조 증가: 시간이 지남에 따라 위험 증가 (노화, 마모)
- 단조 감소: 초기에 위험이 높고 점차 감소 (수술 직후 사망)
- 욕조형(bathtub): 초기 높음 → 중간 안정 → 후기 증가 (제품 수명)
2.3.3 누적 위험 함수 \(H(t)\)
\[ H(t) = \int_0^t h(u) \, du = -\ln S(t) \]
누적 위험 함수는 시점 \(t\) 까지 축적된 총 위험량이다. Nelson-Aalen 추정량으로 비모수적으로 추정한다.
2.3.4 세 함수 간 관계
생존 함수, 위험 함수, 확률 밀도 함수는 서로 유도 가능하다:
\[ \begin{aligned} S(t) &= \exp\left(-\int_0^t h(u) \, du\right) = \exp(-H(t)) \\ h(t) &= \frac{f(t)}{S(t)} = -\frac{d}{dt}\ln S(t) \\ f(t) &= h(t) \cdot S(t) = -\frac{d}{dt}S(t) \end{aligned} \]
| 함수 | 기호 | 의미 | 추정 방법 |
|---|---|---|---|
| 생존 함수 | \(S(t)\) | 시점 \(t\) 이후 생존 확률 | Kaplan-Meier |
| 위험 함수 | \(h(t)\) | 순간 사건 발생률 | Cox 모형 |
| 누적 위험 함수 | \(H(t)\) | 누적 위험량 | Nelson-Aalen |
| 확률 밀도 함수 | \(f(t)\) | 시점 \(t\) 에서 사건 발생 밀도 | 모수적 모형 |
2.4 기본 데이터 구조
생존 분석의 데이터는 최소한 다음 두 변수를 포함한다:
| 변수 | 설명 | 예시 |
|---|---|---|
| \(T_i\) | 생존 시간 (사건 발생 또는 중도절단까지의 시간) | 5주, 12주, 3.5주 |
| \(\delta_i\) | 사건 지시 변수 (\(1\): 사건 발생, \(0\): 중도절단) | 1, 0, 0 |
확장된 데이터 구조에는 공변량(covariates) \(X_1, X_2, \ldots, X_p\) 가 추가된다:
| 대상 | \(T\) | \(\delta\) | \(X_1\) (나이) | \(X_2\) (처치) |
|---|---|---|---|---|
| 1 | 5 | 1 | 45 | 1 |
| 2 | 12 | 0 | 52 | 0 |
| 3 | 3.5 | 0 | 38 | 1 |
| 4 | 8 | 0 | 61 | 0 |
| 5 | 6 | 0 | 47 | 1 |
| 6 | 3.5 | 1 | 55 | 0 |
3 직관적 설명
직관: 생존 분석은 “언제 일어나는가?”에 답하는 통계 기법이다. 일반적인 분류 모델이 “이 환자가 재발할 것인가? (Yes/No)”를 묻는다면, 생존 분석은 “이 환자가 언제 재발할 것인가?”를 묻는다. 그리고 “아직 재발하지 않았지만 연구가 끝났다”는 정보도 버리지 않고 활용한다 — 이것이 중도절단의 처리이다.
3.1 왜 일반적인 방법으로는 안 되는가?
| 접근법 | 문제점 |
|---|---|
| 로지스틱 회귀 (\(Y = 0/1\)) | “언제”를 무시하고 “발생 여부”만 분석. 5주 후 사망과 50주 후 사망을 동일하게 취급 |
| 선형 회귀 (\(Y = T\)) | 중도절단 데이터를 처리할 수 없음. 절단된 관측치를 제외하면 편향 발생 |
| 평균 생존 시간 비교 | 중도절단이 있으면 산술 평균이 실제 생존 시간을 과소 추정 |
생존 분석은 시간 정보와 불완전한 관측(중도절단)을 동시에 다룰 수 있는 유일한 프레임워크이다.
4 왜 필요한가
4.1 중도절단을 무시하면 어떤 일이 벌어지는가
임상시험에서 100명의 환자를 5년간 추적한다고 하자.
- 30명은 사건(사망) 발생
- 20명은 연구 종료 시점까지 생존
- 50명은 추적 중 탈락 (이사, 연락 두절 등)
방법 1: 탈락자를 제외하고 분석 50명을 제외하면 30/50 = 60% 사망률로 추정한다. 하지만 탈락자 중에도 생존한 사람이 있었을 것이므로 사망률이 과대 추정된다.
방법 2: 탈락자를 “생존”으로 처리 30/100 = 30% 사망률로 추정한다. 하지만 탈락자 중 일부는 사망했을 수 있으므로 사망률이 과소 추정된다.
방법 3: 생존 분석 (Kaplan-Meier) 각 사건 발생 시점마다 “위험에 노출된 인원(risk set)”을 정확히 계산하여 생존 확률을 추정한다. 중도절단된 관측치는 해당 시점까지의 정보를 기여한 후 위험 집합에서 제거된다. 편향 없이 정확한 추정이 가능하다.
4.2 생존 분석의 세 가지 목표
- 생존 분포 추정 및 비교: 처치군과 대조군의 생존 곡선을 추정하고 비교한다 (Kaplan-Meier + Log-rank 검정)
- 공변량 효과 추정: 설명 변수(나이, 처치, 유전자 등)가 생존 시간에 미치는 영향을 정량화한다 (Cox 비례위험 모형)
- 예후 예측: 특정 환자의 생존 확률 또는 위험도를 예측한다 (위험 점수, 생존 곡선 예측)
5 응용 분야
| 분야 | 사건(event) | 시간(time) | 구체적 예시 |
|---|---|---|---|
| 임상의학 | 사망, 재발 | 진단 후 경과 시간 | 항암제 A vs B의 무진행 생존 기간 비교 |
| 역학 | 질병 발생 | 코호트 추적 기간 | 흡연자와 비흡연자의 폐암 발생까지 시간 |
| 공학/신뢰성 | 고장, 파손 | 사용 시간/사이클 | 반도체 수명 분석, 배터리 열화 |
| 비즈니스 | 고객 이탈, 해지 | 가입 후 경과 일수 | SaaS 구독자 이탈 분석 |
| HR/조직 | 퇴직, 이직 | 입사 후 경과 기간 | 직원 유지율(retention) 분석 |
| 보험 | 보험금 청구 | 가입 후 경과 기간 | 자동차 보험 사고 발생 시점 분석 |
| 사회과학 | 재범, 재혼 | 출소/이혼 후 경과 기간 | 가석방자 재범률 분석 |
| 제조 | 제품 반품 | 출고 후 경과 기간 | 품질 보증 기간 내 고장률 |
6 예시
6.1 예시: 백혈병 관해 유지 기간
Kleinbaum & Klein (2012, Ch.1)의 고전적 예시를 재구성한다.
6명의 백혈병 환자를 관해(remission) 후 12주간 추적한 결과:
| 환자 | 생존 시간 (주) | 상태 | 설명 |
|---|---|---|---|
| A | 5 | 사건 | 5주 차에 재발 |
| B | 12 | 중도절단 | 12주(연구 종료)까지 관해 유지 |
| C | 3.5 | 중도절단 | 3.5주 차에 자발적 탈퇴 |
| D | 8 | 중도절단 | 8주(연구 종료)까지 관해 유지 |
| E | 6 | 중도절단 | 6주 차에 추적 실패 |
| F | 3.5 | 사건 | 3.5주 차에 재발 |
관측된 정보:
- 사건 발생: A(5주), F(3.5주) — 정확한 재발 시점을 안다
- 중도절단: B(12주), C(3.5주), D(8주), E(6주) — 최소한 이만큼은 관해를 유지했다는 것만 안다
- 단순 평균: \((5 + 12 + 3.5 + 8 + 6 + 3.5) / 6 = 6.3\) 주 — 하지만 이 값은 중도절단을 무시한 것이므로 실제 평균 생존 시간의 하한에 불과하다
6.2 기술적 요약 통계
중도절단이 있을 때 사용할 수 있는 기술 통계:
- 중앙 생존 시간(median survival time): \(S(t) = 0.5\) 가 되는 시점
- 제한 평균 생존 시간(restricted mean survival time, RMST): 특정 시점 \(\tau\) 까지의 생존 곡선 아래 면적
\[ \text{RMST}(\tau) = \int_0^{\tau} S(t) \, dt \]
7 코드 예시
7.1 Step 1: 순수 Python 구현 (원리 이해)
def kaplan_meier(times, events):
"""
순수 Python으로 Kaplan-Meier 생존 함수를 구현한다.
times: 생존 시간 리스트
events: 사건 지시 변수 리스트 (1=사건, 0=중도절단)
"""
# (시간, 사건 여부) 쌍을 시간순으로 정렬
data = sorted(zip(times, events), key=lambda x: x[0])
n = len(data) # 전체 대상 수
at_risk = n # 현재 위험에 노출된 수
survival_prob = 1.0 # 누적 생존 확률
survival_curve = [(0, 1.0)] # (시간, 생존 확률) 리스트
i = 0
while i < n:
t = data[i][0]
# 같은 시점의 사건 수와 중도절단 수를 집계
d = 0 # 사건 수
c = 0 # 중도절단 수
while i < n and data[i][0] == t:
if data[i][1] == 1:
d += 1
else:
c += 1
i += 1
# 사건이 있으면 생존 확률 갱신: S(t) = S(t-) × (1 - d/n_risk)
if d > 0:
survival_prob *= (1 - d / at_risk)
survival_curve.append((t, survival_prob))
# 위험 집합에서 사건 + 중도절단 수만큼 제거
at_risk -= (d + c)
return survival_curve
# 백혈병 관해 데이터 (Kleinbaum & Klein, Ch.1)
times = [5, 12, 3.5, 8, 6, 3.5]
events = [1, 0, 0, 0, 0, 1]
curve = kaplan_meier(times, events)
print("Kaplan-Meier 생존 곡선:")
print(f"{'시점':>6} {'S(t)':>8}")
print("-" * 18)
for t, s in curve:
print(f"{t:>6.1f} {s:>8.4f}")출력 해석:
시점 S(t)
------------------
0.0 1.0000
3.5 0.8333 ← 6명 중 1명 사건 발생 → 5/6
5.0 0.6250 ← 4명(위험 집합) 중 1명 사건 발생 → 0.8333 × 3/4
7.2 Step 2: lifelines 라이브러리 (실무 활용)
import numpy as np
import matplotlib.pyplot as plt
from lifelines import KaplanMeierFitter
# 데이터 정의
times = np.array([5, 12, 3.5, 8, 6, 3.5])
events = np.array([1, 0, 0, 0, 0, 1]) # 1=사건, 0=중도절단
# Kaplan-Meier 추정
kmf = KaplanMeierFitter()
kmf.fit(durations=times, event_observed=events)
# 생존 곡선 출력
print(kmf.survival_function_)
print(f"\n중앙 생존 시간: {kmf.median_survival_time_}")
# 시각화
fig, ax = plt.subplots(figsize=(8, 5))
kmf.plot_survival_function(ax=ax, ci_show=True)
ax.set_xlabel("시간 (주)")
ax.set_ylabel("생존 확률 S(t)")
ax.set_title("Kaplan-Meier 생존 곡선 — 백혈병 관해 데이터")
plt.tight_layout()
plt.show()7.3 위험 함수의 직접 구현
def nelson_aalen(times, events):
"""
순수 Python으로 Nelson-Aalen 누적 위험 함수를 구현한다.
H(t) = Σ (d_j / n_j) for all j where t_j ≤ t
"""
data = sorted(zip(times, events), key=lambda x: x[0])
n = len(data)
at_risk = n
cum_hazard = 0.0
hazard_curve = [(0, 0.0)]
i = 0
while i < n:
t = data[i][0]
d = 0
c = 0
while i < n and data[i][0] == t:
if data[i][1] == 1:
d += 1
else:
c += 1
i += 1
if d > 0:
cum_hazard += d / at_risk
hazard_curve.append((t, cum_hazard))
at_risk -= (d + c)
return hazard_curve
hazard = nelson_aalen(times, events)
print("\nNelson-Aalen 누적 위험 함수:")
print(f"{'시점':>6} {'H(t)':>8}")
print("-" * 18)
for t, h in hazard:
print(f"{t:>6.1f} {h:>8.4f}")8 생존 분석의 주요 방법론 체계
이 시리즈에서 다룰 방법론을 개관한다:
생존 분석
├── 비모수적 방법 (Nonparametric)
│ ├── Kaplan-Meier 추정 ← 생존 곡선 추정
│ ├── Nelson-Aalen 추정 ← 누적 위험 함수 추정
│ └── Log-rank 검정 ← 두 집단 생존 곡선 비교
│
├── 반모수적 방법 (Semi-parametric)
│ ├── Cox 비례위험 모형 ← 공변량 효과 추정 (핵심)
│ ├── 비례위험 가정 검정 ← Schoenfeld 잔차
│ ├── 층화 Cox 모형 ← 비례위험 가정 완화
│ └── 시간 의존 공변량 Cox 모형 ← 공변량이 시간에 따라 변함
│
├── 모수적 방법 (Parametric)
│ ├── 지수 모형 ← h(t) = λ (상수)
│ ├── 와이블 모형 ← h(t) = λp(λt)^{p-1}
│ ├── 로그정규/로그로지스틱 모형 ← AFT 모형
│ └── 감마, Gompertz 모형
│
└── 고급 주제
├── 재발 사건 분석 ← 반복 사건
├── 경쟁 위험 분석 ← 여러 유형의 사건
├── 표본 크기 설계 ← 임상시험 설계
└── 기계학습 확장 ← RSF, DeepSurv
8.1 방법론 선택 가이드
| 목적 | 방법 | 가정 |
|---|---|---|
| 집단 간 생존 곡선 비교 | Kaplan-Meier + Log-rank | 비모수, 분포 가정 없음 |
| 공변량 효과 추정 | Cox PH 모형 | 비례위험 가정 |
| 구체적 생존 시간 예측 | 모수적 모형 (Weibull 등) | 분포 가정 |
| 비선형 효과, 고차원 | RSF, DeepSurv | 분포 가정 없음, 데이터 의존 |
9 관련 주제
시리즈 내 후속 포스트 (예정)
- Kaplan-Meier 추정과 Log-rank 검정 (Kleinbaum & Klein Ch.2)
- Cox 비례위험 모형 (Kleinbaum & Klein Ch.3)
- 비례위험 가정 검정 (Kleinbaum & Klein Ch.4)
- 층화 Cox 모형 (Kleinbaum & Klein Ch.5)
- 시간 의존 공변량 (Kleinbaum & Klein Ch.6)
- 모수적 생존 모형 (Kleinbaum & Klein Ch.7)
- 재발 사건 분석 (Kleinbaum & Klein Ch.8)
- 경쟁 위험 분석 (Kleinbaum & Klein Ch.9)
- 임상시험 표본 크기 설계 (Kleinbaum & Klein Ch.10)
선행 지식
다른 카테고리 연결
- Random Survival Forest — 생존 분석의 ML 확장
- 종단 데이터 DL — 시간 데이터의 딥러닝 접근
- 역학 연구 설계 — 코호트 연구와 생존 분석
참고 교재
- Kleinbaum, D.G. & Klein, M. (2012). Survival Analysis: A Self-Learning Text (3rd Ed.). Springer.
- Hosmer, D.W., Lemeshow, S. & May, S. (2008). Applied Survival Analysis (2nd Ed.). Wiley.
- Klein, J.P. & Moeschberger, M.L. (2003). Survival Analysis: Techniques for Censored and Truncated Data (2nd Ed.). Springer.
- Collett, D. (2015). Modelling Survival Data in Medical Research (3rd Ed.). CRC Press.