Bootstrap 검정력 + ITT/CACE — 층화 후 분석의 두 추정량 (Buisson Ch.9.2)

층화의 free power, Encouragement Design, ITT vs CACE 의 비즈니스 의미

Buisson (2021) Ch.9 의 power simulation + 결과 분석을 자세히 정리한다. 층화의 자연스러운 false positive 감소 효과, power 곡선의 자세한 해석, 신뢰 수준 trade-off, Encouragement Design 의 의미, ITT (Intention-to-Treat) 추정량, CACE (Complier Average Causal Effect) 추정량의 도출과 IV 접근을 단계별로 시연한다.

Experimentation
Causal Inference
저자

Kwangmin Kim

공개

2026년 05월 08일

1 정의

정의: ITT 와 CACE

층화 무작위 실험에서 모든 owner 가 treatment 를 100% 따르지 않는 경우 (encouragement design), 두 가지 추정량 (Buisson, 2021, Ch.9):

  1. ITT (Intention-to-Treat): “Treatment 를 권유 하면 어떤 효과?”
    • 무작위 배정 그룹의 outcome 비교
    • 실제 treatment 수용 여부 무관
    • 인과 추정량 (랜덤화 보장)
  2. CACE (Complier Average Causal Effect): “Treatment 를 강제 하면 어떤 효과?”
    • Compliers (treatment 그룹 + 수용자) 의 효과 추정
    • IV (Instrumental Variable) 접근 사용
    • 부분 모집단 (compliers) 에 대한 효과
직관 — 두 추정량의 의미

분석가가 자주 혼동: “효과 = treatment 의 효과 = 그냥 그룹 비교.”

두 다른 질문:

  • ITT: “현실적으로 treatment 를 권하면 매출 ↑?”
    • 실제 정책의 효과 (일부는 거부 가능)
    • 비즈니스 의사결정에 직접 사용
  • CACE: “Treatment 를 100% 강제하면?”
    • 가정적 시나리오
    • 정책 변경 (mandatory) 고려 시 참고

분석가가 실험 결과 보고 시 둘 다 보고하는 것이 표준.

→ ITT 는 “실제 효과”, CACE 는 “이상 효과”.

2 Power Simulation — Stratified 적용

2.1 Single Simulation 함수

Stratified 추가

E-BUI8-3 의 Power simulation 에 stratified assignment 만 추가.

def single_sim_fun_stratified(dat_df, metric_fun, Nexp, eff_size,
                                B=100, conf_level=0.9):
    # 1. 무작위 month 선택
    period = np.random.choice(range(1, 36))
    dat = dat_df[dat_df["period"] == period].copy()
    if len(dat) > Nexp:
        dat = dat.sample(Nexp)

    # 2. 층화 무작위 배정 (E-BUI9-1 의 함수)
    assgnt = stratified_assignment(dat, "ID", n_groups=3)
    sim_data = dat.merge(assgnt, on="ID", how="inner")

    # 3. Treatment 그룹에 효과 추가
    sim_data["BPday"] = np.where(
        sim_data["group"] == "treat2",
        sim_data["BPday"] + eff_size,
        sim_data["BPday"],
    )

    # 4. 의사결정
    return decision_fun(sim_data, metric_fun, B, conf_level)

핵심: 단순 무작위가 stratified 로 바뀜. 나머지는 동일.

2.2 AirCnC 결과 — Sample Size 1,500

시뮬레이션 결과 (Buisson)
# 5,000 owner 까지 점검
power_sim_fun(dat_df, n_exp=5000, eff_size=2, n_sim=100)  # ≈ 1.0

# 작은 N 시도
power_sim_fun(dat_df, n_exp=500, eff_size=2, n_sim=100)  # ≈ 0.55
power_sim_fun(dat_df, n_exp=1000, eff_size=2, n_sim=100)  # ≈ 0.85
power_sim_fun(dat_df, n_exp=1500, eff_size=2, n_sim=100)  # ≈ 0.92
power_sim_fun(dat_df, n_exp=2000, eff_size=2, n_sim=100)  # ≈ 0.97

결정: N = 1,500 면 power 90% 도달.

5,000 owner 중 1,500 만 사용 (= 30%) → 나머지 3,500 은 대조 그룹 outside.

직관 — 30% 만 사용의 의미

비즈니스 함의:

  • 5,000 owner 중 1,500 명만 실험 참여
  • 나머지 3,500 은 status quo
  • 실험 종료 후 결과 보고 + 결정

장점:

  • 실험 위험을 최소화 (3,500 owner 영향 안 받음)
  • 결과가 negative 일 때 빠른 회복

단점:

  • 작은 그룹 (500/그룹) → 의사결정 risk
  • 더 큰 표본 (예: 5,000) 이라면 더 정확

→ Sample size 결정은 위험 vs 정확도 trade-off.

2.3 Power 곡선 분석

Effect 별 Power (N = 1,500)
효과 크기      Power
   $0          0.05  (= α, false positive)
   $0.5        0.10  (낮음)
   $1.0        0.30
   $1.5        0.65
   $2.0        0.90  (target)
   $3.0        0.99

특징:

  • $0 ~ $1 사이 power 급락
  • $2 부터 안정 plateau
직관 — 곡선의 의미

Power curve 의 형태가 분석가에게 알려주는 것:

  • Steep slope ($1 → $2): 작은 효과 변화에도 power 크게 변함
  • Plateau ($2+): 더 큰 효과는 power 거의 100%
  • 저점 ($0): false positive 만 (5%)

비즈니스 함의:

  • 진짜 효과가 $1.5 이면 65% 만 검출 → 35% false negative
  • $2.0 이 비즈니스 임계값 → 90% 검출 → 만족
  • $0.5 미만은 검출 못 해도 OK (비즈니스 무의미)

3 Stratification 의 Free Power 효과

3.1 False Positive 감소

자연스러운 부작용

Buisson 의 발견:

“Stratification 후 false positive rate 가 5% 보다 작음. 500 simulation 에서 0% 관찰.”

이유:

  • 층화로 그룹 간 균형 → noise 감소
  • Effect = 0 일 때도 그룹 간 차이 매우 작음
  • Bootstrap CI 가 자연스럽게 좁음
  • 0 미포함 가능성 ↓ → false positive ↓
직관 — Free Power 의 양면성

장점:

  • False positive 5% → 0% (가짜 결정 감소)
  • 약속한 안전성 보장

단점:

  • 작은 진짜 효과 ($0.5) 도 검출 못 함 (power 매우 낮음)
  • 모든 효과 크기에서 power 곡선이 아래로 이동

→ “Free 가 항상 좋은 건 아님”. 작은 효과를 놓칠 수 있음.

이게 분석가가 알아야 할 stratification 의 미묘함.

3.2 Confidence Level 의 Trade-off

다양한 신뢰 수준

같은 N = 1,500 에서 power curve 비교:

신뢰 수준  False Positive  Power($0.5)  Power($1)  Power($2)
   90%        0.05            0.10        0.30       0.90
   80%        0.10            0.20        0.50       0.95
   60%        0.20            0.35        0.70       0.98
   40%        0.30            0.50        0.85       0.99

낮은 신뢰 → 좁은 CI → 더 자주 0 미포함:

  • False positive ↑
  • Power ↑ (모든 effect 에서)
직관 — 분석가의 결정

Confidence level 의 결정:

비즈니스 맥락 권장
큰 비용 + 어려운 구현 90% (보수적)
작은 비용 + 쉬운 구현 60~80%
Mandatory 정책 변경 95~99%
마케팅 A/B 테스트 80% (관행)

AirCnC 사례:

  • Treatment 구현 비용 큼 ($10/일/owner → 연 $36,500/owner × 5,000 owner = $1.8억/년)
  • 잘못된 구현 시 큰 손실
  • → 90% confidence 적절

작은 효과는 검출 못 해도 OK. 큰 효과 ($2+) 만 정확히 검출.

4 실험 결과 분석

4.1 ITT — Intention to Treat

ITT 의 정의

“Treatment 그룹 vs Control 그룹 비교 — 실제 treatment 수용 여부 무관.”

수식:

\[ \text{ITT} = \mathbb{E}[Y \mid \text{group} = \text{treatment}] - \mathbb{E}[Y \mid \text{group} = \text{control}] \]

회귀로:

\[ Y_i = \beta_0 + \beta_1 \cdot \text{group}_i + \text{covariates} + \epsilon_i \]

\(\beta_1\) = ITT.

직관 — ITT 가 답하는 질문

질문: “이 treatment 를 출시하면 매출이 어떻게 되나?”

답: ITT.

이유:

  • 실제 출시 시 일부 customer 가 거부 가능 (opt-out)
  • ITT 는 그 거부도 포함한 평균 효과
  • 따라서 “정책 시행의 진짜 효과”

비교 (잘못된 분석):

  • “수용자 vs 거부자 비교”
  • 수용 자체가 selection (자기 선택)
  • 인과 추정 아님 (confounded)

→ ITT 만이 정책 의사결정에 정확.

4.2 AirCnC ITT 결과

회귀 결과
import statsmodels.formula.api as smf

# Treatment 2 (free cleaning) 비용 $10/day 차감
exp_data["BPday_net"] = np.where(
    (exp_data["group"] == "treat2") & (exp_data["compliant"] == 1),
    exp_data["BPday"] - 10,
    exp_data["BPday"],
)

# 회귀
model = smf.ols(
    "BPday_net ~ sq_ft + tier + avg_review + group",
    data=exp_data,
).fit()
print(model.summary())

Buisson 의 결과 (가상):

                Coefficient  Std.Err.  p-value
Intercept       19.23        3.57      0.0001
sq_ft           0.0068       0.0037    0.066
tier2           1.06         0.84      0.21
tier1           5.17         1.04      0.0001
avg_review      1.69         0.25      0.0001
grouptreat1     0.97         0.89      0.27   ← 1박 minimum
grouptreat2    -0.17         0.89      0.85   ← 무료 청소

해석:

  • Treat1 (1 박 min): +$0.97/일 (p = 0.27, marginal)
  • Treat2 (무료 청소): -$0.17/일 (효과 거의 없음)
비즈니스 의사결정

비즈니스 임계값: $2/일 효과 이상이어야 implement.

결과:

  • Treat1: $0.97 → 임계값 미달 → Reject
  • Treat2: -$0.17 → 손해 → Reject

→ 두 treatment 모두 정책 변경 불가.

분석가의 보고:

“두 treatment 모두 비즈니스 임계값 ($2/day) 미달. 현재 정책 (24 시간 청소) 유지 권장.”

4.3 ITT 의 Bootstrap CI

신뢰구간
from scipy import stats
import numpy as np

def bootstrap_treat1_effect(df, B=1000):
    """Treat1 의 Bootstrap CI."""
    coeffs = []
    for _ in range(B):
        sample = df.sample(n=len(df), replace=True)
        m = smf.ols(
            "BPday ~ sq_ft + tier + avg_review + group",
            data=sample,
        ).fit()
        coeffs.append(m.params["group[T.treat1]"])
    coeffs.sort()
    lo = coeffs[int(B * 0.05)]
    hi = coeffs[int(B * 0.95)]
    return lo, hi


lo, hi = bootstrap_treat1_effect(exp_data)
print(f"Treat1 90% CI: [${lo:.3f}, ${hi:.3f}]")

가상 결과: [$0.002, $2.66].

해석:

  • CI 의 하한이 $0.002 — 0 매우 가까움
  • 통계적으로 marginal 유의
  • 비즈니스 임계값 ($2) 가 CI 안에 있음 → 효과 있을 수도, 없을 수도

→ 결정 불확실. 추가 실험 또는 정책 결정 보류.

5 Encouragement Design 의 함의

5.1 “Treatment” 의 두 의미

무작위 vs 수용

AirCnC 사례에서 무작위 배정이 강제 못 함:

  • 무료 청소 그룹: owner 가 무료 청소 거부 가능
  • 1 박 min 그룹: owner 가 1 박 정책 설정 안 함 가능

따라서 4 가지 owner 유형 (예: 1 박 min):

그룹 배정 1 박 min 정책 분류
Control No A: 정상 control
Control Yes (자기 선택) B: 항상 1 박 min (defier or always-taker)
Treatment Yes C: complier
Treatment No D: never-taker

각 분류의 outcome 이 다름.

직관 — 4 가지 분류의 의미

비유: “약 처방” 실험.

  • A: 처방 안 받음 + 약 안 먹음 (정상 control)
  • B: 처방 안 받았는데 다른 곳에서 약 먹음 (control 그룹의 always-taker)
  • C: 처방 받음 + 약 먹음 (complier)
  • D: 처방 받았는데 안 먹음 (never-taker)

각 그룹의 결과를 비교하려면 어떻게?

  • A vs C: control 정상 vs treatment 수용자 — selection bias
  • 모든 treatment vs 모든 control: ITT (실제 정책 효과)
  • C 만 vs D 만: confounded (수용 자체가 selection)

→ 단순 비교는 잘못. ITT 만 인과 정확.

5.2 CACE — Complier Average Causal Effect

CACE 의 도출

CACE 는 “complier 만의 평균 효과” 추정.

수식 (단순 binary case):

\[ \text{CACE} = \frac{\text{ITT}}{\text{Compliance Rate}} = \frac{\beta_{\text{ITT}}}{P(\text{compliance} = 1 | \text{group} = \text{treatment})} \]

해석:

  • ITT: 모든 treatment 그룹의 평균 효과 (수용자 + 거부자)
  • Compliance rate: 수용자 비율
  • CACE: 수용자만의 효과 (배율)

예: ITT = $1, compliance = 50% → CACE = $1 / 0.5 = $2.

→ CACE 는 ITT 보다 항상 큼 (수용 안 한 사람의 0 효과를 제외).

직관 — CACE 의 비즈니스 의미

CACE 가 답하는 질문:

“만약 모든 owner 가 treatment 를 강제로 받으면?”

(예: 정책으로 1 박 min 강제)

이 답은:

  • 비교 baseline: 무작위 수용자만의 효과
  • 가정: never-taker 가 강제 시에도 비슷한 효과 → 가정 검증 어려움
  • 실용적 추정 제공

비즈니스 함의:

  • ITT 가 marginal → CACE 가 클 수 있음 (수용자만의 효과는 강함)
  • 정책 변경 (mandatory) 고려 시 CACE 검토

5.3 CACE 의 IV 접근

Instrumental Variable

CACE 추정은 IV (Instrumental Variable) 의 단순 응용.

무작위 그룹 배정 (Z) → Treatment 수용 (T) → Outcome (Y)

여기서:

  • Z = instrument (무작위 배정)
  • T = treatment (실제 수용)
  • Y = outcome

IV 추정:

\[ \text{CACE} = \frac{\text{Cov}(Z, Y)}{\text{Cov}(Z, T)} \]

회귀로:

# Stage 1: T = α + γ * Z + ε
# Stage 2: Y = β_0 + β_1 * T_hat + δ

linearmodels 패키지 사용.

CACE 의 가정

IV 가 작동하려면:

  1. Relevance: Z 가 T 에 영향 (compliance > 0)
  2. Exclusion: Z 가 Y 에 직접 영향 X (T 통해서만)
  3. Monotonicity: Z = 1 → T 가 같거나 ↑ (defier 없음)

만약 가정 위반:

  • Defier 존재 시: CACE 가 잘못
  • Z → Y 직접 효과 (예: 그룹 인지가 outcome 영향) 시: bias

→ 가정 점검 필수. 도메인 직관으로.

5.4 AirCnC CACE 계산

시뮬레이션
from linearmodels.iv import IV2SLS

# Treat1 (1 박 min) 의 CACE
exp_data["treat1_assigned"] = (exp_data["group"] == "treat1").astype(int)
exp_data["treat1_received"] = ((exp_data["group"] == "treat1") &
                                (exp_data["compliant"] == 1)).astype(int)

iv_model = IV2SLS(
    dependent=exp_data["BPday"],
    exog=exp_data[["sq_ft", "avg_review"]],
    endog=exp_data["treat1_received"],
    instruments=exp_data["treat1_assigned"],
).fit()

print(iv_model.summary)

가상 결과:

  • Compliance rate (treat1 그룹의 수용자): 30%
  • ITT (treat1 의 회귀 계수): $0.97
  • CACE = $0.97 / 0.30 ≈ $3.23

해석:

  • 수용한 owner 만의 효과 = $3.23 (1 박 min 의 진짜 효과)
  • 비즈니스 임계값 $2 초과 → mandatory 시 implement 가치
직관 — ITT vs CACE 의 의사결정 함의

같은 실험의 두 결과:

  • ITT = $0.97: “실제 정책 (권유 + 옵션) 효과 = $0.97/day”
  • CACE = $3.23: “수용자만의 효과 = $3.23/day”

비즈니스 의사결정:

  • 권유 정책: ITT $0.97 < $2 → Reject
  • 강제 정책 (모두에게 1 박 min): CACE $3.23 > $2 → 고려
    • 단, never-taker 가 강제 시 같은 효과인지는 가정
    • CSAT 영향 (강제로 인한 불만) 별도 점검
    • 정치적 부담

→ ITT 와 CACE 가 다른 의사결정.

분석 보고:

“권유 정책은 효과 미미. 강제 정책은 잠재적 효과 있으나 수용 가정 + CSAT 영향 검토 필수.”

6 Outside-Group Treatment 의 처리

Treat1 의 특수 상황

AirCnC 의 1 박 min:

  • 무작위 배정 외에도 owner 가 자체적으로 1 박 min 설정 가능 (소프트웨어상)
  • Control 그룹 owner 가 1 박 min 사용 가능 (자기 결정)

따라서 4 가지 case:

그룹 1 박 min 사용 의미
Control No 정상 control
Control Yes “spillover” — control 인데 treatment 효과
Treatment Yes complier
Treatment No never-taker

문제: Control 그룹의 일부가 treatment 같은 행동.

직관 — Spillover 의 처리

만약 control 의 일부가 treatment 행동을 하면:

  • ITT 가 약화 (control 의 baseline 이 올라감)
  • 진짜 효과보다 작게 보임

해결:

  1. As-Treated 분석: 실제 행동 기준 비교 (selection bias)
  2. Per-Protocol: spillover 한 control 제외 (selection bias)
  3. Local Average Treatment Effect: IV 로 처리 가능

비즈니스 분석에서 default = ITT (가장 보수적). Spillover 가 큰 영향이면 추가 분석.

7 실무 — Power Simulation 자동화

7.1 Stratified Power Function

import numpy as np
import pandas as pd
import statsmodels.formula.api as smf


def stratified_power_sim(hist_data, n_exp, eff_size, n_sim=100,
                           confidence=0.9, treatment_var="group",
                           outcome_var="BPday", seed=42):
    """Stratified 실험의 power simulation."""
    np.random.seed(seed)
    decisions = []

    for _ in range(n_sim):
        # 1. 표본
        period = np.random.choice(hist_data["period"].unique())
        period_data = hist_data[hist_data["period"] == period].copy()
        if len(period_data) > n_exp:
            period_data = period_data.sample(n_exp)

        # 2. Stratified 배정 (단순화 — 실제로는 [E-BUI9-1] 의 함수)
        period_data["group"] = np.random.choice(
            ["control", "treat1", "treat2"],
            len(period_data),
        )

        # 3. Treatment 효과
        period_data[outcome_var] = np.where(
            period_data["group"] == "treat2",
            period_data[outcome_var] + eff_size,
            period_data[outcome_var],
        )

        # 4. 회귀 + Bootstrap CI
        coeffs = []
        B = 100
        for _ in range(B):
            boot = period_data.sample(n=len(period_data), replace=True)
            m = smf.ols(f"{outcome_var} ~ group", data=boot).fit(disp=0)
            coeffs.append(m.params.get("group[T.treat2]", 0))
        coeffs.sort()
        lo = coeffs[int(B * (1 - confidence) / 2)]

        decisions.append(1 if lo > 0 else 0)

    return np.mean(decisions)
직관 — 함수의 단계
  1. 시간대 sampling (실제 실험 mirror)
  2. Stratified 배정
  3. 효과 추가
  4. 회귀 + Bootstrap

이 4 단계가 실제 실험의 시뮬레이션. 본 분석 코드와 같은 회귀 사용 → 일관성.

7.2 Power Curve 자동화

import matplotlib.pyplot as plt

def plot_power_curve(hist_data, sample_sizes, effect_sizes, n_sim=50):
    """Power curve 시각화."""
    fig, ax = plt.subplots(figsize=(10, 6))

    for n_exp in sample_sizes:
        powers = []
        for eff in effect_sizes:
            p = stratified_power_sim(hist_data, n_exp, eff, n_sim)
            powers.append(p)
        ax.plot(effect_sizes, powers, "o-", label=f"N={n_exp}")

    ax.axhline(y=0.9, linestyle="--", color="red", alpha=0.5, label="Target 0.9")
    ax.set_xlabel("Effect Size ($/day)")
    ax.set_ylabel("Power")
    ax.set_title("Power Curve at Various Sample Sizes")
    ax.legend()
    ax.grid(alpha=0.3)
    plt.tight_layout()
    plt.savefig("power_curve_stratified.png", dpi=80)
    plt.show()
직관 — 시각화의 가치

Power curve 가 비즈니스 파트너에게 전달:

  • 효과 크기 vs power 의 관계
  • 다양한 N 의 비교
  • Sweet spot 식별 (target 90% 달성하는 최소 N)

비즈니스 의사결정 도구.

8 종합 — 분석 워크플로

분석가의 default
1. ToC 명확화 (Ch.8.1)
2. Random assignment 설계 (Ch.8.2 + 9.1)
   - Owner-level
   - 층화 매칭
3. Power simulation (Ch.9.2)
   - Stratified 적용
   - 효과 크기 시나리오
   - Sample size 결정
4. A/A Test
5. 본 실험 (1,500 owner × 3 그룹 = 1,500 명/그룹)
6. ITT 분석
   - 회귀 + Bootstrap CI
   - 비즈니스 임계값 비교
7. CACE 분석 (encouragement design)
   - IV 회귀
   - Mandatory 정책 시나리오
8. 보고서
   - ITT (실제 효과)
   - CACE (가정적 mandatory)
   - 비즈니스 권장

각 단계가 다음 단계의 전제. 모든 단계 통과 시 의사결정 권장.

9 관련 주제

9.1 Ch.9 의 형제 글 (Ch.9 완결)

9.2 이전 챕터

9.3 후속 챕터

9.5 카테고리 진입점

Subscribe

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