1 정의
\[ Y^a \perp\!\!\!\perp A \quad \text{for all } a \]
잠재 결과 \(Y^a\)와 실제 처리 \(A\)가 독립이다. 처리군과 대조군이 “교환 가능” — 처리군에 대조를 주었어도 대조군과 같은 결과 분포를 보였을 것이다.
- 역학: Exchangeability, Comparability
- IT: Balanced Groups, Unbiased Assignment (A/B 테스트의 무작위 배정이 보장)
| 역학 용어 | IT 용어 | 비고 |
|---|---|---|
| Randomization | Random Assignment | 무작위 배정 |
| Exchangeability | Group Balance | 교환가능성 = 집단 균형 |
| Standardization | Population-weighted Average | 층별 가중 평균 |
| IP Weighting | Propensity Score Weighting | 처리 확률 역수 가중 |
| Conditional Randomization | Stratified Randomization | 층별 무작위 배정 |
2 개념 및 원리
2.1 결측 데이터로서의 인과 추론
이전 편에서 인과 효과를 정의하기 위해 \(Y^{a=1}\), \(Y^{a=0}\)가 모두 필요하다는 것을 보았다. 현실에서는 개체별로 하나만 관측된다 — 나머지는 결측(missing)이다.
| 개체 | \(A\) | \(Y\) | \(Y(0)\) | \(Y(1)\) |
|---|---|---|---|---|
| Zeus | 1 | 1 | ? | 1 |
| Hera | 1 | 0 | ? | 0 |
| Kronos | 0 | 1 | 1 | ? |
| Rheia | 0 | 0 | 0 | ? |
무작위 배정(randomization)이 이 결측을 “무시해도 되는(ignorable)” 결측으로 만든다.
2.2 주변 무작위화에서의 교환가능성
교환가능성이 성립하면:
\[ \Pr[Y^a = 1 \mid A = 1] = \Pr[Y^a = 1 \mid A = 0] = \Pr[Y^a = 1] \]
교환가능성 + 일관성을 결합하면:
\[ E[Y^a] = E[Y^a \mid A = a] = E[Y \mid A = a] \]
따라서:
\[ \underbrace{E[Y \mid A=1] - E[Y \mid A=0]}_{\text{연관 차이 (관측 가능)}} = \underbrace{E[Y^{a=1}] - E[Y^{a=0}]}_{\text{인과 차이 (ATE)}} \]
이상적 무작위 실험에서 연관은 곧 인과이다 (Hernán & Robins, 2020, Ch.2).
2.3 주의: \(Y^a \perp\!\!\!\perp A\) vs. \(Y \perp\!\!\!\perp A\)
| 조건 | 의미 | 성립 조건 |
|---|---|---|
| \(Y^a \perp\!\!\!\perp A\) | 잠재 결과와 처리가 독립 | 무작위 배정 시 성립 |
| \(Y \perp\!\!\!\perp A\) | 관측 결과와 처리가 독립 | 처리 효과가 없을 때만 |
인과 효과가 존재하는 RCT에서 \(Y^a \perp\!\!\!\perp A\)는 성립하지만 \(Y \perp\!\!\!\perp A\)는 성립하지 않는다.
2.4 조건부 무작위화 (Conditional Randomization)
\[ Y^a \perp\!\!\!\perp A \mid L \quad \text{for all } a \]
공변량 \(L\)의 각 층(stratum) 내에서 잠재 결과와 처리가 독립이다.
- 역학: Conditional Exchangeability (조건부 교환가능성)
- IT: Balanced Within Strata (층화 무작위 배정으로 보장)
예시: 비위험 상태(\(L=0\)) 8명에게 50%, 위험 상태(\(L=1\)) 12명에게 75% 확률로 심장 이식 배정. 주변 교환가능성은 위반되지만, 각 \(L\) 층 내에서는 무작위이므로 조건부 교환가능성은 성립한다.
2.5 표준화 (Standardization)
조건부 교환가능성 하에서:
\[ \Pr[Y^a = 1] = \sum_l \Pr[Y = 1 \mid L = l, A = a] \cdot \Pr[L = l] \]
좌변은 반사실적 양이지만, 우변은 관측 데이터만으로 계산 가능하다.
예시 계산 (Hernán & Robins, 2020, Ch.2, Table 2.2):
| 층 | \(\Pr[L=l]\) | \(\Pr[Y=1 \mid L=l, A=1]\) | \(\Pr[Y=1 \mid L=l, A=0]\) |
|---|---|---|---|
| \(L=0\) | 0.4 | 1/4 | 1/4 |
| \(L=1\) | 0.6 | 2/3 | 2/3 |
\[ \Pr[Y^{a=1} = 1] = \frac{1}{4}(0.4) + \frac{2}{3}(0.6) = 0.5 \]
\[ \Pr[Y^{a=0} = 1] = \frac{1}{4}(0.4) + \frac{2}{3}(0.6) = 0.5 \]
인과 위험비 \(= 1.0\). 심장 이식의 평균 인과 효과 없음.
2.6 역확률 가중치 (IPW)
각 개체를 처리 확률의 역수 \(W^A = 1/f(A \mid L)\)로 가중하여, 처리 배정이 \(L\)에 의존하지 않는 유사 모집단(pseudo-population)을 구성한다.
| 개체 유형 | \(L\) | \(A\) | \(\Pr[A \mid L]\) | 가중치 \(W^A\) |
|---|---|---|---|---|
| \(L=0\), 처리 | 0 | 1 | 0.5 | 2.0 |
| \(L=0\), 비처리 | 0 | 0 | 0.5 | 2.0 |
| \(L=1\), 처리 | 1 | 1 | 0.75 | 1.33 |
| \(L=1\), 비처리 | 1 | 0 | 0.25 | 4.0 |
유사 모집단에서 \(L \perp\!\!\!\perp A\) → 주변 교환가능성 성립 → 연관 = 인과.
\[ E[Y^a] = \frac{E\left[\frac{I(A=a)}{f(A \mid L)} Y\right]}{E\left[\frac{I(A=a)}{f(A \mid L)}\right]} \]
| 측면 | 표준화 | IPW |
|---|---|---|
| 필요한 모형 | 결과 모형 \(E[Y \mid A, L]\) | 처리 모형 \(\Pr[A \mid L]\) |
| 가중 방식 | \(L\) 분포로 가중 평균 | 처리 확률 역수로 가중 |
| 결과 | 동일 (조건부 교환가능성 하) | 동일 |
| Doubly Robust | 두 방법을 결합하면 하나만 맞아도 일치 추정 |
2.7 세 가지 식별 조건 요약
| 조건 | 수식 | 무작위 실험에서 | 관찰 연구에서 |
|---|---|---|---|
| 교환가능성 | \(Y^a \perp\!\!\!\perp A \mid L\) | 설계로 보장 | 가정 |
| 양성 | \(\Pr[A=a \mid L=l] > 0\) | 설계로 보장 가능 | 검증 필요 |
| 일관성 | \(A=a \Rightarrow Y = Y^a\) | SUTVA 전제 | SUTVA 전제 |
3 직관적 설명
3.1 “동전 던지기”가 왜 강력한가
약의 효과를 알고 싶다. 건강한 사람은 약을 먹고 싶어하고, 아픈 사람은 안 먹으려 한다. 자발적 선택에 맡기면 처리군(약 복용)은 원래 건강한 사람들이고, 대조군은 아픈 사람들이다. 약을 먹은 사람이 더 건강한 것은 약 덕분이 아니라 원래 건강했기 때문이다.
동전 던지기(무작위 배정)는 이 문제를 해결한다: 건강한 사람도, 아픈 사람도 50:50으로 양쪽에 배정된다. 두 집단의 baseline이 통계적으로 동일하므로, 결과 차이는 처리 때문이라고 말할 수 있다.
3.2 1948년 스트렙토마이신 시험
최초의 현대적 RCT는 1948년 영국 Medical Research Council의 스트렙토마이신 결핵 치료 시험이다. 봉투에 넣은 랜덤 번호로 환자를 배정했다 — 이것이 교환가능성을 보장한 최초의 체계적 방법이었다. 이전에는 의사의 판단으로 “더 아픈 환자에게 신약”을 주는 것이 일반적이었고, 이로 인해 신약이 효과가 없는 것처럼 보이는 교란이 발생했다.
3.3 A/B 테스트에서의 교환가능성
| A/B 테스트 요소 | 역학 대응 | 교환가능성과의 관계 |
|---|---|---|
| 해싱 기반 무작위 배정 | 동전 던지기 | 교환가능성 보장의 메커니즘 |
| A/A 테스트 | 위약 대조 | 교환가능성 검증 도구 |
| SRM (Sample Ratio Mismatch) | 배정 비율 이상 | 교환가능성 위반의 징후 |
| 층화 무작위 배정 | 블록 무작위화 | 조건부 교환가능성 활용 |
4 왜 필요한가
4.1 무작위 배정 없이 발생하는 문제
전후 비교(Before-After)만으로 시책 효과를 판단하면:
- 계절성, 자연 회복, 외부 이벤트 등의 교란을 처치 효과로 오인
- 예: “광고 캠페인 후 매출 10% 증가” → 연말 특수 효과일 수 있음
자기 선택(Self-selection)에 의한 비교:
- 쿠폰을 사용한 사람 vs. 사용하지 않은 사람의 구매액 비교
- 쿠폰 사용자는 원래 구매 의향이 높은 집단 → 교란
4.2 교환가능성이 비즈니스 결정을 바꾸는 예
| 분석 방법 | 결과 | 의사결정 |
|---|---|---|
| 단순 비교 (교란) | 새 추천 알고리즘 사용자의 구매율이 2배 높음 | 알고리즘 전면 배포 |
| A/B 테스트 (교환가능성 보장) | 실제 인과 효과 = +3%p | 효과 대비 개발 비용 재검토 |
교란을 무시하면 10배 과대추정될 수 있다. 자기 선택된 집단과 무작위 배정된 집단의 차이는 종종 이 정도로 크다.
5 응용 분야
| 분야 | 활용 | 구체적 예시 |
|---|---|---|
| 임상시험 | Phase III RCT | 신약 생존율 비교: 표준화로 연령 보정 |
| 테크 기업 | A/B 테스트 | 새 UI의 전환율 효과 측정 |
| 마케팅 | 층화 실험 | 국가별 다른 배정 비율 → 표준화로 전체 효과 추정 |
| 정책 | 조건부 무작위 배정 | 저소득층에 더 높은 확률로 보조금 배정 → IPW 보정 |
| 게임 | 밸런싱 실험 | 레벨별 다른 보상 테스트 → 층화 분석 |
6 예시
6.1 조건부 무작위 실험의 표준화
20명 모집단, L ∈ {0(비위험), 1(위험)}
L=0: 8명, 처리 확률 50% → 처리 4명, 대조 4명
L=1: 12명, 처리 확률 75% → 처리 9명, 대조 3명
관측 결과:
L=0, A=1: 사망 1/4 = 25% L=0, A=0: 사망 1/4 = 25%
L=1, A=1: 사망 6/9 = 67% L=1, A=0: 사망 2/3 = 67%
표준화:
Pr[Y^{a=1}=1] = 0.25 × 0.4 + 0.67 × 0.6 = 0.50
Pr[Y^{a=0}=1] = 0.25 × 0.4 + 0.67 × 0.6 = 0.50
ATE = 0 (인과 효과 없음)
단순 비교: 처리군 사망률 = 7/13 = 54%, 대조군 = 3/7 = 43%. 단순 비교는 처리가 해로운 것으로 보이지만, 표준화하면 인과 효과 = 0이다. 교란 변수 \(L\)(위험 상태)이 처리 배정에 영향을 미쳤기 때문이다.
7 코드 예시
7.1 표준화와 IPW 비교
import numpy as np
import pandas as pd
np.random.seed(42)
n = 5000
# --- 조건부 무작위 실험 시뮬레이션 ---
L = np.random.binomial(1, 0.6, n) # 60%가 위험 상태
# 조건부 무작위 배정: L=0이면 50%, L=1이면 75%
prob_treat = 0.5 + 0.25 * L
A = np.random.binomial(1, prob_treat)
# 결과: ATE = -0.05 (처리의 보호 효과)
true_ate = -0.05
prob_y = 0.2 + 0.3 * L + true_ate * A
Y = np.random.binomial(1, np.clip(prob_y, 0, 1))
df = pd.DataFrame({"L": L, "A": A, "Y": Y})
# --- 1. Naive estimate (교란된) ---
naive = df[df.A == 1].Y.mean() - df[df.A == 0].Y.mean()
print(f"Naive (biased): {naive:.4f}")
# --- 2. Standardization ---
std_ate = 0
for l in [0, 1]:
p_l = (df.L == l).mean()
e_y1 = df[(df.L == l) & (df.A == 1)].Y.mean()
e_y0 = df[(df.L == l) & (df.A == 0)].Y.mean()
std_ate += (e_y1 - e_y0) * p_l
print(f"Standardization: {std_ate:.4f}")
# --- 3. IPW ---
ps = 0.5 + 0.25 * df.L.values # 알려진 성향 점수
w = np.where(df.A == 1, 1 / ps, 1 / (1 - ps))
y1_ipw = np.average(df.Y[df.A == 1], weights=w[df.A == 1])
y0_ipw = np.average(df.Y[df.A == 0], weights=w[df.A == 0])
ipw_ate = y1_ipw - y0_ipw
print(f"IPW: {ipw_ate:.4f}")
print(f"\nTrue ATE: {true_ate:.4f}")7.2 A/B 테스트 시뮬레이션: 교환가능성의 힘
from scipy import stats
np.random.seed(123)
n_per_group = 10000
# RCT: 무작위 배정 → 교환가능성 보장
control_rate = 0.10
treatment_rate = 0.12 # 진짜 효과: +2%p
control_outcomes = np.random.binomial(1, control_rate, n_per_group)
treatment_outcomes = np.random.binomial(1, treatment_rate, n_per_group)
# 효과 추정
p_c = control_outcomes.mean()
p_t = treatment_outcomes.mean()
rd = p_t - p_c # Risk Difference = Uplift
rr = p_t / p_c # Risk Ratio = Lift
# 검정
z_stat, p_value = stats.proportions_ztest(
[treatment_outcomes.sum(), control_outcomes.sum()],
[n_per_group, n_per_group],
alternative="two-sided"
)
print("=== A/B 테스트 결과 (역학 ↔ IT 지표) ===")
print(f"Control rate: {p_c:.4f}")
print(f"Treatment rate: {p_t:.4f}")
print(f"Risk Difference (Uplift): {rd:+.4f}")
print(f"Risk Ratio (Lift): {rr:.3f}")
print(f"NNT (Number to Convert): {1/abs(rd):.0f}")
print(f"z-statistic: {z_stat:.3f}, p-value: {p_value:.4f}")8 관련 주제
이전/다음
같은 카테고리
- A/B 테스트의 핵심 메커니즘 — 무작위 배정의 실무 적용
- RCT와 A/B 테스트의 설계 원칙
다른 카테고리
9 참고 문헌
- Hernán, M. A. & Robins, J. M. (2020). Causal Inference: What If, Ch.2. Chapman & Hall/CRC.
- Horvitz, D. G. & Thompson, D. J. (1952). A generalization of sampling without replacement from a finite universe. JASA, 47(260), 663-685.
- Medical Research Council (1948). Streptomycin treatment of pulmonary tuberculosis. BMJ, 2(4582), 769-782.