Design Effect
Definition
**설계 효과(Design Effect, DEFF)**는 복잡한 표집 설계가 단순 무작위 표집에 비해 분산에 미치는 영향을 측정합니다.
클러스터 랜덤화에서:
여기서:
- : 클러스터당 평균 샘플 수
- : 클러스터 내 상관계수 (Intraclass Correlation Coefficient)
유효 샘플 사이즈:
Intuitive Understanding
클러스터 랜덤화에서 같은 클러스터 내 관측치들은 서로 비슷합니다 (예: 같은 도시의 사람들).
만약 한 클러스터의 모든 사람이 정확히 같다면, 그 클러스터에서 100명을 관측해도 정보는 1명분입니다. ICC가 이 “유사성”을 측정하고, DEFF는 이로 인한 정보 손실을 정량화합니다.
Key Properties
ICC (Intraclass Correlation Coefficient)
- : 클러스터 내 상관 없음 → DEFF = 1
- : 클러스터 내 완전 상관 → DEFF = m
DEFF의 영향
| ICC | m=10 | m=50 | m=100 |
|---|---|---|---|
| 0.01 | 1.09 | 1.49 | 1.99 |
| 0.05 | 1.45 | 3.45 | 5.95 |
| 0.10 | 1.90 | 5.90 | 10.90 |
ICC가 0.05이고 클러스터당 100명이면, 유효 샘플이 약 1/6로 줄어듭니다.
왜 클러스터 랜덤화를 하는가?
가격 실험에서 **간섭(interference)**이 발생하면 개인 수준 랜덤화가 불가능:
- 친구가 할인 받으면 나도 요구
- 소셜 미디어로 가격 차이 공유
- 재판매(arbitrage)
클러스터 랜덤화는 간섭을 줄이지만, 검정력을 희생합니다.
Example
샘플 사이즈 계산
import numpy as np
def sample_size_clustered(baseline_rate, mde_relative, icc, cluster_size,
alpha=0.05, power=0.80):
"""
클러스터 랜덤화를 위한 샘플 사이즈 계산
"""
from scipy import stats
# 개인 수준 필요 샘플
p1 = baseline_rate
p2 = baseline_rate * (1 + mde_relative)
z_alpha = stats.norm.ppf(1 - alpha/2)
z_beta = stats.norm.ppf(power)
n_individual = 2 * ((z_alpha + z_beta)**2 * p1 * (1-p1)) / (p2 - p1)**2
# 설계 효과
deff = 1 + (cluster_size - 1) * icc
# 클러스터 수준 필요 샘플
n_clustered = n_individual * deff
# 필요 클러스터 수
n_clusters = np.ceil(n_clustered / cluster_size)
return {
'n_individual': int(n_individual),
'deff': deff,
'n_clustered': int(n_clustered),
'n_clusters_per_arm': int(n_clusters / 2),
'total_sample': int(n_clusters * cluster_size)
}
# 예: 도시 수준 클러스터, ICC=0.05, 도시당 1000명
result = sample_size_clustered(
baseline_rate=0.05,
mde_relative=0.10,
icc=0.05,
cluster_size=1000
)
print(f"개인 랜덤화 필요 샘플: {result['n_individual']:,}")
print(f"설계 효과: {result['deff']:.2f}")
print(f"클러스터 랜덤화 필요 샘플: {result['n_clustered']:,}")
print(f"필요 클러스터 수 (그룹당): {result['n_clusters_per_arm']}")
클러스터 랜덤화 구현
import hashlib
def cluster_randomize(cluster_id, experiment_name, treatment_prob=0.5):
"""클러스터 수준 무작위 할당"""
hash_input = f"{cluster_id}_{experiment_name}"
hash_value = int(hashlib.md5(hash_input.encode()).hexdigest(), 16)
return 'treatment' if (hash_value % 100) / 100 < treatment_prob else 'control'
# 도시 수준 클러스터
cities = ['Seoul', 'Busan', 'Incheon', 'Daegu', 'Daejeon']
for city in cities:
group = cluster_randomize(city, 'price_exp_2024')
print(f"{city}: {group}")
ICC 추정
import statsmodels.formula.api as smf
def estimate_icc(data, outcome_col, cluster_col):
"""
혼합 효과 모델로 ICC 추정
"""
# 널 모델 (무작위 절편만)
model = smf.mixedlm(
f"{outcome_col} ~ 1",
data,
groups=data[cluster_col]
)
result = model.fit()
# 분산 성분 추출
var_between = result.cov_re.iloc[0, 0] # 클러스터 간 분산
var_within = result.scale # 클러스터 내 분산
icc = var_between / (var_between + var_within)
return icc
# ICC 추정
icc = estimate_icc(data, 'purchase_amount', 'city')
print(f"추정 ICC: {icc:.4f}")
Related Concepts
- A-B Testing - DEFF가 적용되는 맥락
- Statistical Power - DEFF가 영향을 미치는 대상
- CUPED - 분산 감소의 다른 접근법
References
- Kish, L. (1965). Survey Sampling.
- Donner, A., & Klar, N. (2000). Design and Analysis of Cluster Randomization Trials.
- Comprehensive Personalized Pricing Guide, Part V, §15.3