1 타당성·편향·인과 추론·효과 지표
이 파일은 20번 연구 설계 대분류의 타당성/편향/인과 추론 섹션을 분리한 것이다. 이전 파일: 21 — 각 연구 설계 상세
1.1 1. 내적 타당성 vs 외적 타당성
1.1.1 정의
| 타당성 | 질문 | 위협 요인 |
|---|---|---|
| 내적 타당성 (Internal Validity) | “이 연구 안에서 처치가 결과를 일으킨 것이 맞는가?” | 편향, 교란, 역인과 |
| 외적 타당성 (External Validity) | “이 결과가 다른 맥락/집단에도 적용되는가?” | 표본 편향, 상황 특수성 |
1.1.2 내적 타당성의 위협
내적 타당성을 떨어뜨리는 요인들:
1. 선택 편향: 처치/대조군이 체계적으로 다름
2. 성숙 효과: 시간 경과에 따른 자연 변화
3. 역사 효과: 실험 중 외부 사건 발생
4. 검사 효과: 반복 측정이 행동을 변화
5. 도구 변화: 측정 기준이 실험 중 변경
6. 회귀 효과: 극단값이 평균으로 회귀
7. 이탈 편향: 처치/대조군의 차별적 탈락
1.1.3 외적 타당성의 IT 적용
상황: 미국 파워유저 대상 A/B 테스트에서 전환율 +5%p 효과
외적 타당성 질문:
→ 한국 유저에게도 같은 효과? (모집단 차이)
→ 신규 유저에게도? (경험 수준 차이)
→ 6개월 후에도? (노벨티 효과 소멸)
→ 모바일에서도? (환경 차이)
SATE vs PATE:
SATE = 실험 참여자(표본)의 평균 처치 효과
PATE = 전체 사용자(모집단)의 평균 처치 효과
SATE ≠ PATE 일 수 있음 → 외적 타당성 문제
1.1.4 IT 환경의 대표적 위협
| 위협 | 내적 타당성 | 외적 타당성 |
|---|---|---|
| 노벨티 효과 (Novelty Effect) | O | O |
| 새 UI에 대한 일시적 호기심이 지표를 부풀림 | 시간 경과 후 효과 소멸 | 장기 효과와 다름 |
| 자원자 편향 (Volunteer Bias) | O | O |
| 실험 참여를 자발적으로 선택 | 능동적 사용자 과대 대표 | 비참여자에게 일반화 불가 |
| 플랫폼 효과 | - | O |
| 모바일 vs 데스크톱 행동 차이 | - | 다른 플랫폼에 일반화 주의 |
1.2 2. 편향(Bias) 3대 범주
역학에서 정립된 편향의 체계적 분류. 모든 연구 설계에서 이 세 가지를 점검해야 한다.
1.2.1 분류 체계
편향 (Bias)
│
├── 1. 선택 편향 (Selection Bias)
│ │ "누구를 연구에 포함/제외했는가"
│ ├── 표본 선택 편향: 연구 참여자 ≠ 목표 모집단
│ ├── 자기 선택 편향: 처치를 스스로 선택 (관찰 연구)
│ ├── 생존 편향 (Survivorship): 탈락자 무시 → 효과 과대
│ ├── Berkson's Bias: 입원(선택) 기준이 두 질환 모두에 영향
│ ├── Collider Bias: 결과의 후손을 조건부 → 가짜 연관
│ └── 이탈 편향 (Attrition): 추적 탈락이 비무작위적
│
├── 2. 정보 편향 (Information Bias / Measurement Bias)
│ │ "어떻게 측정했는가"
│ ├── 회상 편향 (Recall): 케이스가 노출을 더 잘 기억
│ ├── 관찰자 편향: 연구자의 기대가 측정에 영향
│ ├── 오분류 (Misclassification)
│ │ ├── 비차별적: 노출/결과를 균등하게 잘못 분류 → 효과 희석
│ │ └── 차별적: 한쪽에서만 잘못 분류 → 효과 과대/과소
│ └── 사회적 바람직성: 응답자가 바람직한 답 선택
│
└── 3. 교란 (Confounding)
│ "제3의 변수가 처치-결과 관계를 왜곡"
├── 양의 교란: 효과를 과대 추정
├── 음의 교란: 효과를 과소 추정 (또는 방향 반전)
├── Simpson's Paradox: 하위 집단과 전체의 방향이 반대
└── 시간 변동 교란: L_t가 T_{t-1}의 결과이자 T_t의 교란
→ 표준 회귀로 해결 불가 (G-methods 필요)
1.2.2 IT 편향 예시
| 편향 유형 | IT 상황 | 메커니즘 | 대응 |
|---|---|---|---|
| 선택 편향 | 실험 대상에서 신규 유저 제외 | 파워 유저만 분석 → 과대 추정 | 포함 기준 명시, 사전 등록 |
| 생존 편향 | “장기 유저는 만족도가 높다” | 불만족 유저는 이미 이탈 | 이탈자 포함 분석, ITT |
| 노벨티 효과 | 새 UI 출시 직후 클릭률 ↑ | 호기심에 의한 일시적 증가 | Burn-in 기간 설정 |
| SRM (Sample Ratio Mismatch) | 처치/대조 비율 ≠ 설계 비율 | 배정 로직 오류, 봇, 크롤러 | 카이제곱 SRM 검정 |
| 측정 편향 | 클릭 이벤트 로깅 누락 | 느린 페이지에서 이벤트 미발생 | 로깅 QA, 양방향 검증 |
| 교란 | “다크모드 사용자의 전환율이 높다” | 파워유저가 다크모드를 더 많이 씀 | 세그먼트 통제, PSM |
1.3 3. 반사실(Counterfactual) 프레임워크
1.3.1 Rubin Causal Model 핵심
상세는 35편 — 인과 추론 프레임워크 참조.
인과는 “처치를 받지 않았다면 어떤 결과가 나왔을까?”라는 반사실적 질문에 답하는 것이다.
\[\tau_i = Y_i(1) - Y_i(0)\]
- \(Y_i(1)\): 개체 \(i\)가 처치를 받았을 때의 잠재 결과
- \(Y_i(0)\): 개체 \(i\)가 처치를 받지 않았을 때의 잠재 결과
- 근본 문제: 한 개체에 대해 두 잠재 결과를 동시에 관찰할 수 없다
\[Y_i^{obs} = T_i \cdot Y_i(1) + (1 - T_i) \cdot Y_i(0)\]
1.3.2 반사실 추정 방법 비교
| 방법 | 반사실 구성 방식 | 핵심 가정 | 인과 강도 | IT 적용 |
|---|---|---|---|---|
| RCT / A/B | 무작위 배정 대조군 | SUTVA | ★★★★★ | A/B 테스트 |
| DiD | 대조군의 변화 패턴 | 평행 추세 | ★★★★☆ | 지역별 출시 |
| SCM | 가중합으로 합성 대조군 | 가중 재현성 | ★★★★☆ | 단일 국가 정책 |
| ITS | 개입 전 추세 연장 | 추세 연속성 | ★★★☆☆ | 알고리즘 변경 |
| RDD | 임계값 직전 관측치 | 연속성, 비조작 | ★★★★☆ | 등급 기반 혜택 |
| PSM | 매칭된 비처치군 | 무시가능성 | ★★★☆☆ | 관찰 데이터 효과 추정 |
| IPTW | 가중 가상 모집단 | 양의 확률, 올바른 PS | ★★★☆☆ | 관찰 데이터 효과 추정 |
| IV / 2SLS | 도구변수 유도 변동 | 배제 제한 | ★★★★☆ | Encouragement Design |
| Doubly Robust | 결과+처치 모델 결합 | 둘 중 하나 정확 | ★★★★☆ | 고신뢰 추정 |
| G-Computation | 조건부 분포 시뮬레이션 | 순차적 무시가능성 | ★★★★☆ | 종단 데이터 |
| MSM (IPTW) | 시간 변동 가중치 | 올바른 가중 모델 | ★★★★☆ | 종단 정책 효과 |
| MAB | 사후 베이지안 추론 | 베이지안 사전분포 | ★★☆☆☆ | 실시간 최적 배분 |
1.4 4. 인과 효과 추정량 체계
1.4.1 ATE 패밀리
| 추정량 | 수식 | 의미 | IT 적용 |
|---|---|---|---|
| ATE | \(E[Y(1) - Y(0)]\) | 전체 집단 평균 효과 | 모든 유저에 기능 적용 시 평균 효과 |
| ATT | \(E[Y(1) - Y(0) \mid T=1]\) | 실제 처치자의 효과 | 기능을 실제 쓴 유저의 효과 |
| ATC | \(E[Y(1) - Y(0) \mid T=0]\) | 비처치자에 적용 시 효과 | 미사용자에게 확장 시 기대 효과 |
| SATE | \(\frac{1}{n}\sum_i [Y_i(1) - Y_i(0)]\) | 표본 평균 효과 | 실험 참여자의 효과 |
| PATE | \(E_{pop}[Y(1) - Y(0)]\) | 모집단 평균 효과 | 전체 서비스 유저 효과 |
| CATE | \(E[Y(1) - Y(0) \mid X=x]\) | 하위 집단별 효과 | 파워유저 vs 신규유저 효과 차이 |
| LATE | \(E[Y(1) - Y(0) \mid \text{compliers}]\) | 순응자 효과 | Encouragement에 반응한 유저의 효과 |
1.4.2 SATE vs PATE: 내적 타당성 vs 외적 타당성
SATE (Sample ATE):
실험에 참여한 1만 명의 평균 효과
→ 내적 타당성이 높으면 신뢰 가능
→ "이 실험 안에서 효과가 있었다"
PATE (Population ATE):
서비스 전체 100만 명에 대한 평균 효과
→ 외적 타당성이 필요
→ "전체 유저에게 런칭해도 효과가 있을까?"
SATE ≠ PATE가 되는 상황:
- 실험 대상 = 파워유저만 → 신규유저에는 다른 효과
- 실험 기간 = 2주 → 장기 효과와 다름 (노벨티)
- 실험 환경 = 모바일만 → 데스크톱에는 다른 효과
1.5 5. Propensity Score Matching (PSM)
상세는 35편 참조.
1.5.1 핵심 아이디어
RCT에서는 무작위 배정이 모든 공변량을 균형 잡히게 만든다. 관찰 데이터에서는 이 균형이 자연적으로 존재하지 않으므로, 처치 확률(propensity score)을 기준으로 매칭하여 사후적으로 균형을 만든다.
\[e(X) = P(T = 1 \mid X)\]
Rosenbaum & Rubin (1983): 다차원 \(X\) 대신 1차원 스칼라 \(e(X)\)로 조건부를 대체할 수 있다.
1.5.2 Python 코드
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import NearestNeighbors
# --- 1. Propensity Score 추정 ---
np.random.seed(42)
n = 2000
# 교란 변수
activity = np.random.normal(50, 10, n)
tenure = np.random.exponential(12, n)
# 처치: 활동 수준과 tenure에 의존 (교란!)
prob_treat = 1 / (1 + np.exp(-(activity - 50) / 5 - (tenure - 12) / 10))
treatment = np.random.binomial(1, prob_treat)
# 결과: 처치 효과 = 3
outcome = 20 + 0.3 * activity + 0.1 * tenure + 3 * treatment + np.random.normal(0, 5, n)
df = pd.DataFrame({
"activity": activity, "tenure": tenure,
"treatment": treatment, "outcome": outcome
})
# Propensity Score
X = df[["activity", "tenure"]]
ps_model = LogisticRegression()
ps_model.fit(X, df["treatment"])
df["ps"] = ps_model.predict_proba(X)[:, 1]
# --- 2. Nearest Neighbor Matching ---
treated = df[df.treatment == 1]
control = df[df.treatment == 0]
nn = NearestNeighbors(n_neighbors=1)
nn.fit(control[["ps"]])
distances, indices = nn.kneighbors(treated[["ps"]])
matched_control = control.iloc[indices.flatten()]
# ATT 추정
att = treated["outcome"].values - matched_control["outcome"].values
print(f"ATT = {att.mean():.2f} (SE = {att.std() / np.sqrt(len(att)):.2f})")
print(f"진짜 효과: 3.00")
# --- 3. Balance Check ---
def smd(x1, x0):
return (x1.mean() - x0.mean()) / np.sqrt((x1.var() + x0.var()) / 2)
for col in ["activity", "tenure"]:
before = smd(treated[col], control[col])
after = smd(treated[col], matched_control[col].values)
print(f"{col}: SMD before={before:.3f}, after={after:.3f}")1.6 6. 효과 측정 지표
상세는 33편 참조.
1.6.1 전체 지표 체계
| 지표 | 수식 | 직관 | 설계 |
|---|---|---|---|
| RR (Relative Risk) | \(\frac{P(Y \mid E)}{P(Y \mid \bar{E})}\) | 노출군이 몇 배 위험한가 | 코호트, RCT |
| OR (Odds Ratio) | \(\frac{ad}{bc}\) | 오즈의 비율 (RR 근사, 희귀 시) | 케이스-컨트롤, 로지스틱 |
| HR (Hazard Ratio) | \(\frac{h_E(t)}{h_{\bar{E}}(t)}\) | 순간 위험의 비율 | 생존분석 |
| ARR (Absolute Risk Reduction) | \(P_{control} - P_{treat}\) | 절대적으로 몇 %p 감소 | RCT |
| NNT (Number Needed to Treat) | \(1 / ARR\) | 몇 명 처치해야 1명 예방 | 비용-효과 분석 |
| RRR (Relative Risk Reduction) | \(1 - RR\) | 상대적으로 몇 % 감소 | RCT, 코호트 |
1.6.2 NNT의 비즈니스 의사결정 활용
예시: AI Agent 개인화
대조군 이탈률: 40%
처치군 이탈률: 30%
ARR = 10%p
NNT = 1 / 0.10 = 10
→ 10명에게 개인화를 적용해야 1명의 이탈을 방지
비용-효과 분석:
개인화 비용: 사용자당 월 $2 → 10명 = $20
고객 LTV: $200
NNT × 비용 = $20 < $200 = LTV
→ 경제적으로 타당
만약 NNT = 50이면:
50명 × $2 = $100 < $200 → 여전히 타당
만약 NNT = 200이면:
200명 × $2 = $400 > $200 → 비경제적!
1.7 7. A/B 설계에 적용된 임상시험 원칙
상세는 32편 — RCT와 A/B 테스트 참조.
1.7.1 7.1 무작위 배정 (Randomization)
해시 기반 층화 배정 — 실험 간 독립성을 보장하면서 세그먼트별 균형을 유지한다.
import hashlib
def assign_treatment_stratified(user_id, strata_key, salt="exp_v1", ratio=0.5):
"""층화 해시 배정: strata 내에서 독립적으로 해시 배정."""
hash_input = f"{user_id}_{strata_key}_{salt}"
hash_val = int(hashlib.sha256(hash_input.encode()).hexdigest(), 16)
bucket = hash_val % 10000
return "treatment" if bucket < ratio * 10000 else "control"핵심: salt를 실험마다 다르게 설정하면, 같은 유저라도 실험 간 독립적으로 배정된다.
1.7.2 7.2 블라인딩 (Blinding)
| 수준 | 의학 | IT |
|---|---|---|
| 단일 맹검 | 환자가 처치 모름 | 사용자가 변형 모름 (대부분 자동) |
| 이중 맹검 | + 의사도 모름 | + 분석가가 중간 결과 모름 |
| 삼중 맹검 | + 결과 평가자 모름 | + PM/의사결정자가 실험 종료 전 결과 미열람 |
IT에서 블라인딩이 깨지는 주요 원인: 분석가가 실험 중 대시보드 확인 → p-hacking / 조기 종료 유발.
1.7.3 7.3 검정력 분석 (Power Analysis)
\[n = \frac{(z_{\alpha/2} + z_\beta)^2 \left[ p_1(1-p_1) + p_2(1-p_2) \right]}{(p_1 - p_2)^2}\]
import numpy as np
from statsmodels.stats.power import NormalIndPower
from statsmodels.stats.proportion import proportion_effectsize
p_control = 0.10 # 기저율
p_treatment = 0.12 # 기대 전환율
alpha = 0.05
power = 0.80
effect_size = proportion_effectsize(p_treatment, p_control)
analysis = NormalIndPower()
n_per_group = int(np.ceil(
analysis.solve_power(effect_size=effect_size, alpha=alpha,
power=power, alternative="two-sided")
))
print(f"그룹당 필요 표본: {n_per_group:,}")
print(f"총 필요 표본: {n_per_group * 2:,}")
daily_users = 5000
experiment_days = int(np.ceil(n_per_group * 2 / daily_users))
print(f"예상 실험 기간: {experiment_days}일")1.7.4 7.4 ITT 분석
배정 기준 분석: 실제 기능 사용 여부와 무관하게, 배정된 그룹 기준으로 분석한다.
- 효과가 희석(diluted)되지만 선택 편향이 없다
- “배포(deployment)의 효과”를 측정하는 것
- Per-Protocol 분석(실제 사용자만)은 보조 분석으로만 보고
1.7.5 7.5 Sequential Testing
매일 p-value를 확인하면 실제 False Positive Rate가 명목 \(\alpha\)를 크게 초과한다 (Peeking Problem).
검정 횟수 실제 False Positive Rate (α=0.05)
1 5.0%
5 14.0%
10 19.3%
50 37.1%
100 48.3%
O’Brien-Fleming 경계값: 중간 분석 시점마다 다른 기각 기준을 적용하여 전체 \(\alpha\)를 통제한다.
\[z_k^* = z_{\alpha/2} \cdot \sqrt{\frac{K}{k}}\]
import numpy as np
from scipy.stats import norm
def obrien_fleming_boundary(K, alpha=0.05):
"""O'Brien-Fleming 경계값: 초반 엄격, 후반 완화."""
z_alpha = norm.ppf(1 - alpha / 2)
boundaries = []
for k in range(1, K + 1):
z_boundary = z_alpha * np.sqrt(K / k)
p_boundary = 2 * (1 - norm.cdf(z_boundary))
boundaries.append({
"analysis": f"{k}/{K}",
"info_fraction": k / K,
"z_boundary": round(z_boundary, 3),
"p_boundary": round(p_boundary, 5)
})
return boundaries
results = obrien_fleming_boundary(K=4)
for r in results:
print(f"분석 {r['analysis']}: z > {r['z_boundary']}, p < {r['p_boundary']}")분석 1/4: z > 3.920, p < 0.00009
분석 2/4: z > 2.772, p < 0.00557
분석 3/4: z > 2.263, p < 0.02362
분석 4/4: z > 1.960, p < 0.05000
초반은 극도로 보수적이고, 최종 분석은 일반 검정과 동일한 수준이다.
1.8 8. 반사실 추정 방법 선택 가이드
처치가 무작위 배정되었는가?
├── YES → RCT 분석 (t-test, ANOVA, 회귀) [32편]
└── NO → 관찰 데이터
│
├── 미관측 교란이 있는가?
│ ├── YES → 도구변수(IV)가 있는가?
│ │ ├── YES → 2SLS / LATE [35편]
│ │ └── NO → Sensitivity Analysis, Bounds
│ │
│ └── NO (무시가능성 가정 가능)
│ │
│ ├── 처치가 시간에 따라 변하는가?
│ │ ├── YES → G-methods (MSM, G-computation) [35편]
│ │ └── NO (단일 시점)
│ │ │
│ │ ├── 불연속 임계값? → RDD [34편]
│ │ ├── 정책 도입 시점? → DiD / ITS [34편]
│ │ └── 그 외 → PSM / IPTW / Doubly Robust [35편]
│ │
│ └── 메커니즘 분해? → Mediation Analysis [35편]
│
└── 효과 이질성(CATE)? → Causal Forest, DML [35편]
1.9 9. 요약
| 주제 | 핵심 메시지 |
|---|---|
| 타당성 | 내적 타당성(편향 없는 추정)과 외적 타당성(일반화)은 트레이드오프 관계 |
| 편향 | 선택·정보·교란 — 3대 범주를 모든 설계에서 점검 |
| 반사실 | 인과는 “안 했다면?”이라는 질문. 방법마다 반사실 구성 방식이 다름 |
| ATE 체계 | ATE/ATT/CATE/LATE — 추정하는 효과가 정확히 “누구의 효과”인지 명시 |
| PSM | 관찰 데이터에서 사후적 균형 생성. Balance check(SMD < 0.1) 필수 |
| 효과 지표 | OR은 RR을 과장. NNT로 비즈니스 의사결정 연결 |
| 임상시험 원칙 | 무작위배정, 블라인딩, 검정력, ITT, Sequential Testing — 100년 임상 방법론의 IT 이식 |
시리즈 관련 파일:
- 20 — 연구 설계 Overview ← 전체 지도
- 21 — 각 연구 설계 상세 ← 이전 파일
- 32 — RCT와 A/B 테스트 ← 확장
- 33 — 관찰 연구 설계 ← 확장
- 34 — 준실험적 설계 ← 확장
- 35 — 인과 추론 프레임워크 ← 확장