군집 사용 시점과 누출 — Compliance·Leakage·Permutation 의 실무 (Buisson Ch.10.1)

AirCnC 콜센터 SOP 사례, Cluster 결정의 3 가지 logistics, 제한된 표본의 시뮬레이션

Buisson (2021) Ch.10 의 random assignment 절을 자세히 정리한다. Cluster-level 배정을 선택하는 3 가지 logistic 사유 (cognitive load, leakage, compliance), AirCnC 콜센터 사례의 stratified cluster 배정, 제한된 cluster 수에서의 permutation-based simulation, 결정 임계값 (decision threshold) 의 조정을 단계별로 시연한다.

Experimentation
Causal Inference
저자

Kwangmin Kim

공개

2026년 05월 08일

1 정의

정의: Cluster-level 배정 결정의 3 가지 사유
1. Cognitive Load (인지 부담)
   Individual 마다 다른 treatment → 직원 인지 부담 + mistake

2. Leakage (누출)
   같은 cluster 내 individual 간 영향 → 그룹 간 spillover

3. Compliance Enforceability (compliance 강제 가능성)
   Cluster 단위 정책이 individual 단위보다 enforceable

각 사유가 단독으로 cluster-level 정당화. 여러 사유가 동시 시 더 강한 결정.

직관 — 3 사유의 우선순위

분석가의 자문:

  1. “Individual 마다 다른 treatment 가 가능한가?” — No 면 cluster 강제
  2. “Individual 간 영향이 있는가?” — Yes 면 cluster 권장
  3. “Compliance 측정이 어려운가?” — Yes 면 cluster 권장

3 가지 모두 No 면 individual-level OK.

콜센터 사례:

  • Cognitive load: Yes (rep 마다 SOP 전환 부담)
  • Leakage: Yes (reps 간 채팅, 같은 콜센터 내 confusion)
  • Compliance: Yes (어렵게 측정 가능, 그러나 cluster 가 enforceable)

→ 모든 사유 cluster-level 가리킴. Decision 명확.

2 사유 1: Cognitive Load

2.1 문제 시나리오

Individual 단위 SOP 전환의 함정

만약 각 통화에 무작위 SOP:

Call 1 (10:00 AM): 새 SOP — "사과 한 번 + 문제 해결"
Call 2 (10:15 AM): 기존 SOP — "여러 번 사과"
Call 3 (10:30 AM): 새 SOP
Call 4 (10:45 AM): 기존 SOP
...

문제:

  • Rep 의 인지 부담 (작업 전환 비용)
  • 무의식적 mistakes (잘못된 SOP 적용)
  • 시뮬레이션 필요한 정보를 정확히 따르지 못함
  • Compliance 저하 → 효과 측정 흐림

비유: 운전 중 매번 우측 통행 vs 좌측 통행 무작위 → 사고 위험.

직관 — Cognitive Load 의 실험 비용

분석가가 인지해야 할 비용:

  • Individual 무작위 시 compliance 80% → 효과 measurement 의 20% 손실
  • Cluster 무작위 시 compliance 95% → 5% 손실

같은 sample size 에서:

  • Individual: 효과 추정의 80% 정확도
  • Cluster: 95% 정확도

→ Cognitive load 는 통계적 정확도의 비용.

비즈니스 함의: Cluster-level 이 compliance 향상 → 더 작은 sample size 로 같은 power.

2.2 콜센터 reps 의 인지 부담 — 자세히

Buisson 의 관찰

“Reps 가 통화마다 SOP 전환 시 인지 부담 + noncompliance 위험.”

자세한 시나리오:

  • Call 시작 전: 분석가가 “이번엔 새 SOP” 또는 “기존 SOP” 표시
  • Rep 가 적절한 SOP 회상 + 적용
  • 통화 압박 (실시간) → 인지 자원 한계
  • 한 SOP 의 정확한 따름이 어려움

해결: cluster (콜센터)-level

  • 한 콜센터의 모든 reps 가 같은 SOP
  • 통화마다 전환 없음
  • 자연스러운 routine 형성
  • 인지 부담 ↓ → compliance ↑

3 사유 2: Leakage (누출)

3.1 문제 시나리오

Individual 그룹 간 영향

같은 콜센터 내 individual 무작위:

Center A:
   Rep 1 (Treatment) — 새 SOP
   Rep 2 (Treatment) — 새 SOP
   Rep 3 (Control) — 기존 SOP
   Rep 4 (Control) — 기존 SOP
   ...

3 개월 후:

  • Treatment reps 의 CSAT 점수 ↑
  • Control reps 가 점심시간에 채팅:
    • “어떻게 하니까 점수가 좋아?”
    • “새 SOP 시도해 볼까?”

결과:

  • Control reps 의 일부가 새 SOP 따라함
  • 두 그룹 차이 약화
  • 효과 측정 underestimate
직관 — Leakage 의 통계적 결과

Leakage 가 효과 추정에 미치는 영향:

진짜 효과: +1.0 CSAT
Leakage 0%: 추정 = +1.0 (정확)
Leakage 30%: 추정 = +0.7 (control 일부가 treatment 효과)
Leakage 70%: 추정 = +0.3 (대부분 같은 SOP)
Leakage 100%: 추정 ≈ 0 (구분 안 됨)

비즈니스 함의:

  • 효과 있는 SOP 도 leakage 로 0 처럼 보임
  • “이 SOP 효과 없음” 잘못된 결론
  • Production 거부 → 좋은 정책 폐기

해결: cluster-level (콜센터 분리) → leakage 거의 0.

3.2 Leakage 의 5 흔한 메커니즘

비즈니스 사례
메커니즘 방지
Word-of-mouth 친구의 새 기능 추천 Geo-isolation
Spillover 새 정책에 customer 반응이 변경 Cluster 단위 정책
Imitation Control 이 treatment 따라하기 Physical separation
Compensation 성과 추적 시 control 이 더 노력 Treatment 비밀 유지
Network effect 같은 platform 내 상호작용 분리된 platform

각 메커니즘이 cluster-level 의 사유.

4 사유 3: Compliance Enforceability

4.1 문제 시나리오

Individual 단위 compliance 측정 어려움

각 rep 의 SOP 준수 측정:

  • 수단 1: 통화 녹음 + manual review (20% sampling)
    • 시간·비용 큼
    • Subjective evaluator
  • 수단 2: 자동 음성 분석 (NLP)
    • 정확도 80% (perfect 안 됨)
    • 새 SOP 의 미묘한 변화 catch 어려움

→ 100% compliance enforce 어려움.

Cluster (콜센터) 단위:

  • 콜센터 매니저가 모든 reps 에 SOP 전달
  • 콜센터 단위 training
  • 매니저가 일관된 enforcement
  • Compliance 자연스럽게 ↑
직관 — Cluster 의 social enforcement

같은 cluster 의 reps 가:

  • 서로 보고 배움
  • “동료가 새 SOP 잘 따른다 → 나도”
  • 자연스러운 norm 형성

다른 cluster 와 비교:

  • Cross-cluster 비교 적음
  • Norm 이 cluster 단위 안정

→ Cluster 가 compliance 의 social enforcement 도구.

5 Cluster 배정의 logistical 절차

5.1 단계

5 단계
1. Cluster 식별
   - Geographic, organizational, network-based
   - Cluster 간 분리 (leakage 0)

2. Cluster 특성 수집
   - 각 cluster 의 baseline metric
   - 인구통계, 규모, 등

3. Stratified cluster 배정
   - Distance 기반 매칭 (Ch.9 의 stratification)
   - Cluster 의 특성 기반

4. Cluster 단위 treatment 적용
   - 각 cluster 에 SOP, 광고, 정책 등 일괄 적용

5. Individual 데이터 수집
   - 각 cluster 내 individual 의 outcome
   - HLM 분석에 사용

5.2 AirCnC 의 stratified 배정

10 콜센터의 매칭

각 콜센터의 baseline 특성:

Center reps 수 평균 CSAT 평균 age payment %
1 18 7.3 35 40
2 22 7.1 38 42
3 15 7.5 33 38
4 19 7.0 36 41
5 21 7.2 37 39
6 17 7.4 34 41
7 20 7.1 35 40
8 16 7.6 32 37
9 18 7.0 38 43
10 23 7.3 36 40

거리 기반 stratification:

  • 5 pair 형성 (각 pair 의 두 colt 가 가장 비슷)
  • 각 pair 의 한 cluster 가 control, 다른 cluster 가 treatment
Pair 1: Center 7 ↔ Center 2 (treatment, control)
Pair 2: Center 8 ↔ Center 9
Pair 3: Center 3 ↔ Center 6
Pair 4: Center 1 ↔ Center 5
Pair 5: Center 10 ↔ Center 4
직관 — 5 pair 의 의미

10 콜센터 = 5 pair = 5 effective comparison.

각 pair 안의 두 cluster 가 비슷:

  • Pair 7-2: 둘 다 평균 reps, 비슷한 CSAT, 비슷한 age
  • 다른 변수의 영향이 두 cluster 에서 cancel
  • 두 cluster 의 차이 = treatment 효과의 진짜 측정

이 pair 구조가 stratification 의 본질.

5 pair 만으로 충분한가? 다음 절 (제한된 표본의 시뮬레이션) 에서.

5.3 5 Pair 의 32 permutation

제한된 무작위성

5 pair 에서 가능한 무작위 배정:

  • 각 pair 마다 2 가지 (control-treatment 또는 treatment-control)
  • 5 pair → \(2^5 = 32\) 가능 배정

비교: stratification 없는 단순 무작위:

  • 10 cluster 중 5 control 선택 = \(\binom{10}{5} = 252\) 가능

Stratification 후: 252 → 32 (87% 감소).

이게 stratification 의 cost: 다양한 무작위 표본 줄어듦.

직관 — 32 permutation 의 함의

Power simulation 시:

  • 1000 simulation 실행해도 32 종류 배정만 (반복)
  • 각 배정 ~31 번씩 평균
  • 정보 추가 안 됨 (무작위성 제한)

분석가의 default:

  • 32 permutation 모두 enumeration (보장된 covers)
  • 또는 ~ 100 simulation (32 의 약 3 배)

이게 limited cluster 의 특수성.

6 Permutation-Based Simulation

6.1 Binary 인코딩

32 permutation 의 enumerate

각 permutation 을 5-bit binary 로:

00000 → Pair 의 첫 cluster 모두 control
00001 → Pair 1, 2, 3, 4 의 첫 cluster control + Pair 5 의 둘째 control
...
11111 → Pair 의 둘째 cluster 모두 control

Python:

n_pairs = 5
n_perms = 2 ** n_pairs  # 32

for perm in range(n_perms):
    binary_str = format(perm, f"0{n_pairs}b")
    # binary_str 의 각 bit 가 pair 의 배정 swap 여부
    treatment_centers = []
    for pair_idx, bit in enumerate(binary_str):
        if bit == "0":
            treatment_centers.append(stratified_pairs[pair_idx][0])
        else:
            treatment_centers.append(stratified_pairs[pair_idx][1])

이 enumeration 으로 모든 가능 배정 cover.

직관 — Vocabulary 비유

Buisson 의 비유:

“학생이 LSAT 를 위해 단어 외우려 함. 사전 사서 매일 무작위 단어 10 개. 1000 단어 외울 계획. 그러나 사전에 96 단어만 있음.”

학생이 1000 번 무작위 추출해도 단어 96 종류만.

Power simulation 도 같음:

  • Permutation 32 종류만 → 32 simulation 이면 모두 cover
  • 그 이상은 반복만

→ Limited cluster 의 simulation 은 enumeration 이 더 효율적.

6.2 Power Simulation 의 변형

Cluster 사례의 simulation
def cluster_power_sim(hist_data, stratified_pairs, eff_size, n_perms=32):
    """Cluster experiment 의 permutation simulation."""
    decisions = []
    n_pairs = len(stratified_pairs)

    for perm in range(n_perms):
        binary_str = format(perm, f"0{n_pairs}b")

        # 배정
        treatment_centers = []
        control_centers = []
        for pair_idx, bit in enumerate(binary_str):
            if bit == "0":
                control_centers.append(stratified_pairs[pair_idx][0])
                treatment_centers.append(stratified_pairs[pair_idx][1])
            else:
                control_centers.append(stratified_pairs[pair_idx][1])
                treatment_centers.append(stratified_pairs[pair_idx][0])

        # 시뮬레이션
        sim_data = hist_data.copy()
        sim_data["group"] = np.where(
            sim_data["center_ID"].isin(treatment_centers),
            "treatment",
            "control",
        )

        # 효과 추가
        sim_data["call_CSAT"] = np.where(
            sim_data["group"] == "treatment",
            sim_data["call_CSAT"] + eff_size,
            sim_data["call_CSAT"],
        )

        # HLM 분석 + 의사결정
        decisions.append(hlm_decision(sim_data))

    return np.mean(decisions)

이 함수가 cluster experiment 의 power 정확히 추정.

6.3 첫 결과 — Underconfident vs Overconfident

CI 의 잘못된 coverage

E-BUI9 의 발견:

  • Stratified individual: 90% CI 가 90% 보다 더 자주 0 포함 (underconfident)

[E-BUI10] 의 발견 (정반대):

  • Stratified cluster: 90% CI 가 0 거의 미포함 (overconfident)

이유:

  • 5 pair × 32 perm = 96 unique simulations
  • 추정 분포가 4 개 cluster (specific pair 배정의 결과)
  • CI 가 “tight cluster” 들로 분리
  • CI 가 0 포함 안 함 → false positive risk ↑

→ Standard CI 의사결정 규칙 (CI > 0) 이 잘못된 결정.

직관 — Discontinuity 의 시각

96 simulation 의 CI 분포:

CI    | count
─────|─────
[-1, -0.5] | 25
[-0.3, -0.1] | 25
[+0.1, +0.3] | 25
[+0.5, +1.0] | 21

CI 가 4 cluster 로 분리:

  • 0 근처 CI 거의 없음
  • “Tight clusters” 패턴

이게 stratification + cluster 의 결과. CI 의 표준 해석 (0 포함 = no effect) 이 안 맞음.

해결: 임계값 조정 (다음).

6.4 Decision Threshold 조정

0 → 0.25 임계값

표준 의사결정: “CI 가 0 위 → implement” → False positive 50%.

수정 의사결정: “Effect 추정 > 0.25 → implement”.

False positive (effect = 0):
   추정 > 0.25 인 simulation 비율
   ≈ 25% (5 pair 의 일부가 양수 cluster)

True positive (effect = 0.6):
   추정 > 0.25 인 simulation 비율
   ≈ 75% (cluster 가 0.25 위로 이동)

→ 임계값 조정으로 false positive 50% → 25%, power 보존.

직관 — 임계값의 비즈니스 의미

VP 가 threshold 0.25 의미:

“+0.25 CSAT 미만의 효과는 비즈니스 의사결정에 의미 없음. 그 이상이면 SOP 변경 가치.”

이 임계값이 VP 의 입장 + 통계적 안정성 모두 만족.

분석가의 보고:

“CI 가 0 포함 여부는 unreliable. 대신 effect 추정값이 임계값 (+0.25) 초과 여부로 결정. 이 규칙으로 false positive 25%, target effect (+0.6) 의 power 75%.”

비즈니스 파트너의 결정:

  • 75% power 충분? → 진행
  • 부족 (90% 원함)? → 더 많은 cluster 필요 (50 콜센터?)

6.5 Power Curve 자세히

AirCnC 결과
Effect   Threshold 0    Threshold 0.25
   0       0.50            0.25
   0.25    0.55            0.50
   0.5     0.65            0.65
   0.6     0.75            0.75
   0.75    0.85            0.85
   1.0     0.95            0.95
   1.5     1.00            1.00

특징:

  • 0~0.25 사이 power 변화 (작은 effect 검출)
  • 0.5+ 부터 안정
  • Threshold 변경이 left side 만 영향 (small effect), right side 보존
직관 — Threshold 의 trade-off

낮은 threshold (0):

  • False positive ↑ (50%)
  • Small effect 검출 ↑

높은 threshold (0.25):

  • False positive ↓ (25%)
  • Small effect 검출 ↓

→ 비즈니스 가 small effect 무시 가능하면 threshold 0.25 권장.

AirCnC 의 결정:

  • VP 의 target = 0.6
  • 0.25 미만은 무의미
  • 따라서 threshold 0.25 OK + power 75%

7 코드 예시 — Cluster 시뮬레이션

7.1 통합 Power Simulation

import numpy as np
import pandas as pd
import statsmodels.formula.api as smf
from itertools import product


def cluster_stratified_pairs(centers_df, n_groups=2):
    """간단한 stratified pairing — 짝 매칭."""
    # numeric 변수만 (예시)
    features = centers_df.select_dtypes(include=[np.number]).values
    # rescale
    features = (features - features.min(axis=0)) / (features.max(axis=0) - features.min(axis=0))

    # Greedy pairing
    n = len(features)
    used = np.zeros(n, dtype=bool)
    pairs = []
    while used.sum() + 2 <= n:
        avail = np.where(~used)[0]
        # 첫 미사용 vs 가장 가까운 미사용
        i = avail[0]
        used[i] = True
        avail = np.where(~used)[0]
        if len(avail) == 0:
            break
        distances = np.sqrt(((features[avail] - features[i]) ** 2).sum(axis=1))
        j = avail[np.argmin(distances)]
        used[j] = True
        pairs.append((centers_df.iloc[i]["center_ID"], centers_df.iloc[j]["center_ID"]))

    return pairs


def cluster_power_simulation(hist_data, stratified_pairs, effect_size,
                                threshold=0.25, n_perms=None):
    """Cluster experiment 의 enumerate-based power."""
    n_pairs = len(stratified_pairs)
    if n_perms is None:
        n_perms = 2 ** n_pairs  # 모든 permutation enumerate

    decisions = []
    estimates = []

    for perm in range(n_perms):
        binary_str = format(perm, f"0{n_pairs}b")

        # 배정
        treatment_centers = set()
        for pair_idx, bit in enumerate(binary_str):
            if bit == "0":
                treatment_centers.add(stratified_pairs[pair_idx][1])
            else:
                treatment_centers.add(stratified_pairs[pair_idx][0])

        # 시뮬레이션
        sim_data = hist_data.copy()
        sim_data["group"] = np.where(
            sim_data["center_ID"].isin(treatment_centers),
            "treatment",
            "control",
        )

        # 효과 추가
        sim_data["call_CSAT"] = np.where(
            sim_data["group"] == "treatment",
            sim_data["call_CSAT"] + effect_size,
            sim_data["call_CSAT"],
        )

        # HLM
        try:
            mixed = smf.mixedlm(
                "call_CSAT ~ group",
                data=sim_data,
                groups=sim_data["center_ID"],
            ).fit(disp=False)
            est = mixed.params.get("group[T.treatment]", 0)
        except Exception:
            est = 0

        estimates.append(est)
        decisions.append(1 if est > threshold else 0)

    return {
        "power": np.mean(decisions),
        "estimates": estimates,
    }
직관 — 이 함수의 가치

이 함수가 분석가에게 주는 것:

  • Cluster experiment 의 정확한 power 계산
  • Permutation enumerate (반복 없음)
  • Threshold 조정 가능

비즈니스 분석에서:

  • 5~20 cluster 일 때 32~1M permutation enumerate
  • 21+ cluster 면 sampling

→ Production-quality cluster experiment power 도구.

7.2 Threshold 결정 자동화

def find_optimal_threshold(hist_data, pairs, target_effect, target_power=0.8,
                              effect_grid=None):
    """Threshold 별 power curve 계산 + 최적 threshold."""
    if effect_grid is None:
        effect_grid = [0, 0.25, 0.5, target_effect, 1.0, 1.5]

    threshold_grid = [0, 0.1, 0.2, 0.25, 0.3, 0.5]
    results = []

    for thr in threshold_grid:
        # False positive (effect = 0)
        fp = cluster_power_simulation(hist_data, pairs, 0, threshold=thr)["power"]
        # True positive (target effect)
        tp = cluster_power_simulation(hist_data, pairs, target_effect, threshold=thr)["power"]

        results.append({
            "threshold": thr,
            "false_positive": fp,
            "true_positive": tp,
            "passes_target": tp >= target_power and fp <= 0.10,
        })

    return pd.DataFrame(results)
직관 — 자동화의 가치

이 함수가 자동으로:

  1. 다양한 threshold 시도
  2. 각 threshold 의 false positive + true positive
  3. 목표 power 만족하는 threshold 추천

분석가의 default 워크플로:

  • 이 함수 실행 → threshold 결정
  • 비즈니스 파트너에게 보고 → 합의
  • 본 실험 진행

→ Cluster experiment 의 표준 도구.

8 종합 — 분석가의 결정 트리

Cluster vs Individual 결정
1. "Individual 마다 다른 treatment 가능?" (cognitive load)
   No → Cluster 강제
   Yes → Step 2

2. "Individual 간 영향 (leakage) 있음?"
   Yes → Cluster 권장
   No → Step 3

3. "Compliance 측정 어려움?"
   Yes → Cluster 권장 (social enforcement)
   No → Individual OK

만약 Cluster 결정:
   4. Cluster 수가 작은가 (< 30)?
      Yes → Stratified pairing + permutation enumerate
      No → Stratified randomization + standard power simulation

   5. Threshold 조정 필요 (CI overconfident)?
      Yes → 비즈니스 임계값 사용
      No → 0 표준

이 결정 트리가 cluster experiment 의 표준.

9 관련 주제

9.1 Ch.10 의 형제 글

9.2 이전 챕터

9.3 카테고리 진입점

Subscribe

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