어떤 상태에서 이탈이 자주 관측된다고 해서 그 상태를 바꾸면 이탈이 줄어든다고 결론 내릴 수는 없습니다. 결과를 예측하는 질문과 개입의 효과를 묻는 질문에는 서로 다른 근거가 필요합니다. 마지막 강의는 경로의 끝을 다루면서 이 차이를 분명히 합니다.
2D 상태 지도에서 두 갈래로 나뉜 점들을 생각해 봅시다. 현재 점이 어느 가지로 갈지 예측하는 것이 fate prediction입니다. 관측 종료 뒤 사건이 언제 발생할지 분석하는 것이 생존분석입니다. 프롬프트나 처치를 바꾸었을 때 결과가 얼마나 달라지는지 묻는 것이 인과추론입니다. 같은 사람이나 세포를 다뤄도 정답 열과 시간의 시작점이 다릅니다.
준비와 수업 계획
조건부확률, 로지스틱 회귀, 1강의 데이터 계약, 8강의 시간 순서를 복습합니다. 100분을 검열과 Kaplan–Meier 20분, Cox 모델 20분, 결과 예측과 Python 25분, 인과추론과 토론 35분으로 나눕니다. 목표는 예측 확률, 사건 발생률, 처치효과를 구분하고 각각의 검증 근거를 설명하는 것입니다. 환경 설정, 전체 구현, 실습 ZIP을 사용합니다.
먼저 세 개의 분석 대상을 구분합니다
공통 데이터의 time은 16프레임 경로를 관측하는 동안 0에서 1까지 증가합니다. fate는 이 경로의 최종 분기입니다. 반면 생존분석의 duration은 16프레임 관측이 모두 끝난 뒤 시작하는 별도의 추적 기간입니다. 사건 시각과 검열 시각도 그 추적 시계를 기준으로 생성합니다. 이미 이탈한 세션의 미래 프레임을 계속 관측했다고 가정하는 데이터가 아닙니다.
outcome은 무작위 처치 뒤의 연속값 결과입니다. fate와 다른 정답이고, 처치가 앞서 관측한 분기를 바꾼 것으로 해석하지 않습니다. 이 강의에서 학습하는 세 모델을 하나의 “이탈 예측 정확도”로 합치지 않는 이유입니다. 데이터는 원리를 설명하는 합성 실험이며 실제 임상이나 서비스 성능을 검증한 벤치마크가 아닙니다.
검열된 관측은 사건도 영원한 생존도 아닙니다
사건 시각을 $T$, 추적을 끝낸 시각을 $C$라고 하면 실제로 기록하는 값은
$$ \widetilde T=\min(T,C),\qquad \delta=\mathbf1[T\leq C] $$입니다. $\delta=0$이면 $T>C$라는 사실만 압니다. 5일까지 사건이 없었다고 사건 시각을 5로 입력하거나, 앞으로도 사건이 없다고 라벨링하면 둘 다 틀립니다. 이런 관측을 통째로 버려도 오래 추적되는 개체의 정보가 선택적으로 사라질 수 있습니다. lifelines의 생존분석 소개는 이 오른쪽 검열을 출발점으로 삼습니다.
생존함수는 사건이 아직 일어나지 않았을 확률입니다.
$$ S(t)=P(T>t). $$연속 시간의 위험함수는 짧은 구간의 조건부 사건 확률을 구간 길이로 나눈 극한입니다.
$$ h(t)=\lim_{\Delta t\downarrow0} \frac{P(t\leq TKaplan–Meier를 네 개체로 계산합니다
A는 2일에 사건, B는 3일에 검열, C는 4일에 사건, D는 5일에 검열되었다고 하겠습니다. 사건 시각 $t_j$ 직전의 위험집합 크기를 $n_j$, 사건 수를 $d_j$라고 하면
$$ \widehat S(t)=\prod_{t_j\leq t}\left(1-\frac{d_j}{n_j}\right) $$입니다. 2일 직전에는 네 개체가 남아 있으므로 $\widehat S(2)=1-1/4=0.75$입니다. 3일의 B 검열에서는 곡선을 내리지 않고 다음 위험집합에서 B를 제외합니다. 4일 직전에는 C와 D 둘이 남아 있으므로 $\widehat S(4)=0.75(1-1/2)=0.375$입니다. 5일의 검열도 새로운 사건은 아닙니다. 관측 범위를 넘어 곡선을 무한히 연장할 근거는 없습니다.
이처럼 위험집합을 갱신하는 것이 알고리즘의 핵심입니다. 전체 집단을 합친 단순 Kaplan–Meier 해석에는 그 집단에서 비정보적 검열이라는 가정이 필요합니다. 어떤 위험도 변수를 조건으로 했을 때만 검열이 독립적이라면, 그 변수를 무시한 합동 곡선까지 자동으로 타당해지지는 않습니다. 층화나 적절한 조정이 필요합니다. 이번 생성기는 검열 시각을 사건과 공변량에 독립적으로 생성합니다. API와 신뢰구간은 KaplanMeierFitter 문서를 참고합니다.
Cox 모델은 위험의 비율을 학습합니다
특징 $x$에 따른 차이를 표현하려면 다음 모델을 쓸 수 있습니다.
$$ h(t\mid x)=h_0(t)\exp(\beta^\top x). $$$h_0(t)$는 시간에 따라 달라지는 기준 위험함수입니다. 두 개체의 고정된 특징 차이에 대한 위험비 $\exp[\beta^\top(x_a-x_b)]$는 시간에 따라 일정합니다. 이것이 비례위험 가정입니다. 위험비가 2라는 말은 생존확률이 절반이라는 뜻이 아닙니다.
동일 시각의 사건이 없을 때, 개체 $i$가 사건을 겪기 직전의 위험집합 $R(t_i)$를 사용한 부분우도는
$$ L(\beta)=\prod_{i:\delta_i=1} \frac{\exp(\beta^\top x_i)}{\sum_{j\in R(t_i)}\exp(\beta^\top x_j)} $$입니다. 그 순간 사건이 발생했다는 조건에서 누가 사건을 겪었는지를 비교하므로 공통 $h_0$가 약분됩니다. 앞 예제에서 A, B, C, D의 상대 위험 점수가 각각 1, 2, 1, 2라면 A의 사건은 $1/6$, C의 사건은 $1/3$을 기여합니다. 부분우도는 $1/18$입니다. 검열된 B와 D도 사건 이전의 분모에 기여했습니다.
실제 코드는 CoxPHFitter(penalizer=.05)를 학습 세션에 적합합니다. 동시 사건 처리 등 세부 구현은 CoxPHFitter 문서에 있습니다. 비례위험, 공변량에 조건부인 비정보적 검열, 특징 함수 형태, 개체 간 독립성 등을 점검해야 합니다. 잔차 진단이나 시간과의 상호작용을 검토하지 않고 계수만 읽지 않습니다. Cox 계수 자체도 관측 데이터에서 인과효과가 되지는 않습니다.
앞부분만 보고 결말을 예측합니다
분기 결과를 $F$라고 쓰면 예측 목표는 $P(F=1\mid\text{현재까지의 관측})$입니다. 이번 코드는 time <= .4인 앞부분만 씁니다. 표준화와 PCA도 학습 세션의 앞부분에만 적합한 뒤, 세션마다 잠재 좌표를 평균해 로지스틱 회귀에 넣습니다. 전체 경로로 PCA를 선택해 놓고 마지막 분류기만 앞부분으로 학습하는 방식이 아닙니다.
중요한 실패 조건이 있습니다. 생성기의 분기 항은 $\max(t-0.4,0)$에 비례하므로 이 입력 구간에는 아직 분기 신호가 없습니다. baseline은 결과와 관련되지만 이 분류기의 입력에는 넣지 않았습니다. 따라서 그림에 결말이 잘 구분된다는 이유로 이른 시점에서도 맞출 수 있다고 기대하면 안 됩니다.
평가에는 정확도 외에도 Brier 점수 $n^{-1}\sum_i(p_i-y_i)^2$, 로그 손실, 순위 판별력인 ROC AUC, 보정 그림을 함께 씁니다. Brier는 작을수록 좋지만 보정만 측정하는 점수는 아닙니다. 보정은 0.7이라고 예측한 사례 중 실제 비율도 그 부근인지 묻습니다. 평가 30개를 네 구간으로 나눈 그림은 매우 불안정하므로 매끈한 보정 곡선처럼 해석하지 않습니다. scikit-learn의 지표 안내에서 정의를 확인할 수 있습니다.
Python 결과를 성공담으로 바꾸지 않습니다
압축을 푼 실습 폴더에서 실행합니다.
from pathlib import Path
from lesson12 import run
print(run(Path("outputs")))
또는 python lesson12.py --output outputs를 실행합니다. 생존곡선은 120개 전체의 기술적 요약이고, Cox와 분기 예측은 90개 학습 세션에 적합해 30개 평가 세션에서 측정합니다. 처치효과는 별도 무작위 실험의 120개 결과로 추정합니다.

고정 시드의 분기 예측 AUC는 0.415, Brier는 0.28793입니다. 학습 집합의 양성 비율만 항상 출력하는 기준선 Brier 0.25086보다 나쁩니다. 테스트 결과를 보고 확률을 뒤집거나 모델을 다시 골라 좋은 값만 보고하면 평가가 오염됩니다. 이번 결과는 이 입력과 절차가 유용한 예측을 보여 주지 못했다는 증거입니다.
Cox의 평가 concordance index는 0.515입니다. 비교 가능한 개체 쌍에서 위험 순위와 사건 순서가 얼마나 맞는지 보는 지표이며, 생존확률의 보정 점수는 아닙니다. 30세션의 이 결과를 모델의 성공이라고 주장할 수 없습니다. 표본 확대, 사전 지정한 검증, 사건 수와 불확실성 보고가 필요합니다.
상태와 결과의 상관에서 처치효과로
갈등 상태에 있는 사용자가 자주 이탈한다고 합시다. 원래의 불만이 갈등 상태와 이탈을 모두 만들었다면 그 불만은 교란 요인입니다. 갈등이라는 이름의 잠재 좌표를 줄이는 것만으로 원인이 제거되지는 않습니다. 먼저 실제로 실행할 개입을 정의해야 합니다.
처치를 $A\in\{0,1\}$, 각 처치를 받았을 때의 잠재 결과를 $Y(1),Y(0)$이라고 쓰면 평균 처치효과는
$$ \operatorname{ATE}=\mathbb E[Y(1)-Y(0)] $$입니다. 한 개체에서 두 결과를 동시에 관측할 수 없으므로 비교 설계가 필요합니다. 무작위 A/B 배정은 처치 전 원인들과 배정의 독립성을 확보하는 출발점입니다. 실제 대화 실험에서는 사용자에게 반복 처치가 섞이거나 다른 세션의 처치가 영향을 미치는지 고려해 무작위화 단위를 정합니다.
이번 후속 연속 결과는 $Y=0.7B+0.8A+\epsilon$이고 $A$는 무작위입니다. 정답 ATE는 0.8입니다. 단순한 처치군과 대조군의 평균 차이는 0.895, 독립 표본 분산으로 계산한 근사 95% 신뢰구간은 **[0.627, 1.163]**입니다. 표준오차는 $\sqrt{s_1^2/n_1+s_0^2/n_0}$이고 구간은 추정값에 $1.96$ 표준오차를 더하고 뺍니다. 이는 합성 실험의 결과이며 실제 프롬프트 효과가 0.8이라는 뜻이 아닙니다. 분기 예측의 실패와 별도로 평가합니다.
관측 자료에서는 가정을 더해야 합니다
성향점수(propensity score)는 처치 전 변수 $L$에 따른 배정 확률 $e(L)=P(A=1\mid L)$입니다. 매칭이나 역확률 가중에 사용할 수 있지만, 점수를 추정했다고 교란이 자동으로 사라지지는 않습니다. 예를 들어 처치군에 $1/e(L)$, 대조군에 $1/[1-e(L)]$ 가중치를 주려면 관측 변수에 조건부인 교환 가능성 $Y(a)\perp A\mid L$, 각 조건에서 양쪽 처치가 가능한 양성성, 잘 정의된 처치와 관측 결과를 연결하는 일관성이 필요합니다. 처치 이후 변수까지 무조건 보정하지 않으며, 극단적인 가중치와 미측정 교란도 확인합니다. Hernán과 Robins의 인과추론 교재가 이 가정을 체계적으로 다룹니다.
차분의 차분(Difference-in-Differences)은 처치 집단과 비교 집단의 전후 변화를 다시 비교합니다.
$$ \widehat\tau_{\rm DiD}= (\overline Y_{T,\mathrm{after}}-\overline Y_{T,\mathrm{before}}) -(\overline Y_{C,\mathrm{after}}-\overline Y_{C,\mathrm{before}}). $$처치 집단이 10에서 14, 비교 집단이 8에서 10이 되었다면 값은 2입니다. 이를 효과로 해석하려면 처치가 없었을 때 두 집단의 추세가 평행했을 것이라는 가정이 필요합니다. 사전 반응이 없고 집단 구성도 적절히 안정적이어야 합니다. 사전 추세가 비슷해 보여도 미래의 반사실 추세가 증명되지는 않습니다. 도입 시점이 여러 개인 경우 단순한 한 식을 무심코 확대하면 안 됩니다. Callaway와 Sant’Anna의 연구는 이런 확장을 다룹니다. 성향점수와 DiD는 개념 확장이며 이번 Python 코드가 실행한 추정기는 무작위 평균 차이입니다.
두 응용과 마지막 과제
바이오에서는 분화 결과, 특정 사건까지의 시간, 처치의 효과가 각각 다른 질문입니다. 파괴적인 발현 측정만으로 같은 세포의 사후 생존을 관측했다고 가정할 수 없으며, 실제 측정 설계와 추적 단위를 맞춰야 합니다. 캐릭터 채팅에서도 결말 유형과 이탈은 다른 결과이고, 마지막 메시지가 관측되었다는 것만으로 영구 이탈을 확정할 수 없습니다. 사건 정의와 관찰 종료 규칙을 먼저 문서화합니다.
최종 프로젝트에서는 질문 하나를 택해 관측 단위와 이용 가능한 시점을 적고, 단순한 기준선과 비교합니다. 이어 표현, 경로, 동역학 중 실제로 검증한 부분을 그림으로 연결합니다. 마지막에는 예측에서 주장할 수 있는 것과 개입 실험이 있어야 주장할 수 있는 것을 나눠 적습니다. 낮은 성능을 숨기지 않고 원인을 데이터 계약까지 거슬러 설명하는 것도 완성도 높은 결과입니다.
연습문제와 해설
- 검열을 사건으로 바꾸면? 네 개체 예제에서 3일의 B를 사건으로 처리해 보세요. 답: $\widehat S(3)=0.75(1-1/3)=0.5$로 부당하게 내려갑니다. 실제로는 3일까지 사건이 없었다는 정보만 있습니다.
- 초기 결말 예측을 개선하려면? 전체 경로로 PCA를 다시 학습해도 될까요? 답: 이른 예측의 입력 제한을 깨뜨립니다. 예측 시점을 명시적으로 늦추거나 그 시점에 측정 가능한 새 특징을 추가하는 별도 실험을 설계하고, 검증과 평가도 다시 나눕니다.
- 상관을 개입으로 바꿔 보세요. “갈등 군집에서 이탈이 많다”를 프롬프트 실험 질문으로 고치세요. 답 예: 동일한 적격 조건에서 두 구체적인 프롬프트를 무작위 배정하고, 미리 정한 기간의 이탈 정의와 사용자 단위 효과를 비교합니다. 군집의 이름을 바꾸는 것은 개입이 아닙니다.
처음의 $x\rightarrow z\rightarrow\text{trajectory}\rightarrow\text{dynamics}\rightarrow\text{fate}$는 이제 각 단계의 목적식과 평가가 붙은 분석 과정이 되었습니다. 다음에 새로운 알고리즘을 만나면 이 과정의 어느 질문을 풀고, 어떤 관측을 추가로 요구하는지부터 확인해 봅시다.