1 정의
Kohavi (2020) Ch.21.3~21.4 의 SRM 발생 원인 + 진단 절차.
1.0.0.1 5 가지 Cause
| Cause | 메커니즘 | 빈도 |
|---|---|---|
| Buggy Randomization | Hash, ramp-up, isolation 의 implementation issue | 일반적 |
| Data Pipeline | Bot filter, cleaning 의 variant 별 차이 | 일반적 |
| Residual Effects | Restart 의 affected user composition | 가끔 |
| Bad Trigger Condition | Redirect 의 loss, asymmetric trigger | 일반적 |
| Treatment-Affected Attribute | Trigger attribute 가 Treatment 영향 | Rare 하지만 critical |
1.0.0.2 6 가지 Debugging Step
| Step | 검증 | 도구 |
|---|---|---|
| 1. Upstream | Randomization point 의 upstream 차이 | Pre-randomization metric |
| 2. Variant assignment | Hash function 의 정확성 | Hash distribution test |
| 3. Pipeline stages | Stage 별 SRM | Pipeline 의 각 step |
| 4. Initial period | Cache, ramp-up 의 영향 | Time-based exclusion |
| 5. Segments | Day, browser, user type | Segment 별 SRM |
| 6. Intersection | 다른 실험 의 variant 비율 | Cross-experiment check |
원문 인용 (Ch.21.3): “Multiple companies have reported seeing SRMs and have highlighted the value of this test as a guardrail.”
핵심 통찰: SRM 의 root cause 는 다양 (5 가지). 단일 fix 가 부족. Systematic debugging 절차 가 root cause 의 식별. Mature platform 의 internal tools 가 6 step 자동화.
2 개념 및 원리
2.1 Cause 1 — Buggy Randomization
저자 명시 (Ch.21.3).
2.1.1 일반적 randomization
Standard 의 Bernoulli randomization:
variant = hash(user_id) % 2
→ Treatment 또는 Control
가정:
Hash 가 uniform
Same probability per variant
2.1.2 복잡성의 source
저자 강조: “things get more complex in practice because of ramp-up procedures.”
2.1.2.1 Ramp-up 의 복잡성
일반적 schedule:
Day 1: 1% Treatment, 99% Control
Day 3: 5% Treatment, 95% Control
Day 7: 50% / 50%
Issue:
Day 1~6 의 데이터 가 50/50 design 의 일부 아님
분석 시 Day 7 부터 만 사용?
Day 1 의 사용자 가 Day 7 에 다시 visit 시 어느 group?
2.1.2.2 Concurrent Experiment
시나리오:
Experiment A: 50/50 (running)
Experiment B: 50/50 (new)
사용자 의 variant assignment:
A 의 randomization seed 1
B 의 randomization seed 2
Independence:
A 와 B 의 variant 가 independent
User 가 A_T + B_T 또는 A_T + B_C 등
Bug:
Seed 의 share 또는 correlation
→ A_T 와 B_T 가 correlated
→ 일부 cell 의 user 가 더 많음
→ SRM in some experiments
2.1.2.3 Isolation Group
Isolation:
실험 A 의 사용자 가 실험 B 에 들어가지 않음
Conflict 회피
Bug:
Isolation logic 의 잘못
→ 일부 사용자 가 두 실험 모두 노출
→ A 의 sample 이 B 의 변화 영향
2.1.3 Microsoft Office 의 사례
저자 명시.
Setup:
Microsoft Office 의 Treatment:
- Internal Microsoft employees: 100% Treatment
- External users: 10% Treatment, 10% Control
Issue:
Treatment group 에 internal heavy user 추가 포함
Control 에는 internal user 없음
→ Treatment 의 user composition 다름
→ Heavy user 가 자연스럽게 metric 높음
→ "Treatment 가 좋아 보임" (false)
SRM detect:
Treatment count > Control count (internal user 만큼)
Sample mismatch
2.1.3.1 Lesson
Sub-population (internal employee) 이 different rule 에 노출:
External 분석 시 internal 제외 필요
Sample 의 segmentation 의 명시 필요
Modern platform:
Internal employee 의 metric 별도 추적
External 분석 의 isolation
자동 SRM detection
이 사례가 randomization 의 systematic issue 의 typical pattern.
2.2 Cause 2 — Data Pipeline Issues
저자 명시.
2.2.1 Bot Filtering
Pipeline 의 standard step:
Bot detection (Ch.16):
Heuristic 으로 bot 분류
Sample 에서 제외
Issue:
Treatment 의 변경이 user 행동 변경
일부 normal user 가 bot heuristic 매칭 (false positive)
Treatment 의 bot reclassification ↑
→ Treatment user 가 적게 분석
→ SRM
2.2.2 Bing 의 Quote
저자 강조: “At Bing over 50% of traffic in the United States is filtered out as bots, and 90% of traffic in China and Russia is bot generated!”
2.2.2.1 Implication
Bot 의 비율:
US: 50%+
China, Russia: 90%+
Bot filter 의 critical 성:
Sample 의 50%+ 의 자동 exclude
Treatment 의 영향 시 huge SRM 가능
→ Bot detection logic 의 robust 의무
→ Variant 별 bot rate 의 monitoring
2.2.3 MSN 의 Extreme 사례
저자 강조: “In one extreme case at MSN, the Treatment was so good at increasing usage, that the best users passed one heuristic threshold and were classified as bots a bug.”
2.2.3.1 시나리오
Treatment: 매우 좋은 feature
Engagement dramatic 증가
Bot heuristic:
"1 일 N+ visit 시 bot"
Threshold: N=20
Treatment 의 효과:
Best user 가 visit 폭증 (예: 10 → 30)
Threshold 초과
→ Bot 분류 (false positive)
→ 분석 에서 제외
결과:
Treatment 의 best user 제외
Treatment 의 average metric ↓
→ "Treatment 가 inferior" (false)
SRM:
Treatment 의 bot reclassification ↑
Sample 의 mismatch detect
→ Investigation 의 trigger
2.2.3.2 Lesson
Bot heuristic 의 dangerous:
Threshold 가 user 의 cap 으로 작용 가능
Treatment 의 effect 가 cap 의 일부 만 측정
해결:
Bot heuristic 의 review (Treatment 별)
Threshold 의 가변 또는 ML-based
Heavy user 의 protected category
저자 인용 (Kohavi 2016): MSN 사례.
2.3 Cause 3 — Residual Effects
저자 명시.
2.3.1 시나리오
실험 운영:
Day 1~7: 실험 진행 중
Day 4: Bug 발견 (Treatment 의 일부 user 의 broken experience)
Day 5: Bug fix
Day 5~: 분석 시작 (bug fix 후)
Issue:
Day 1~4 의 broken experience 가 일부 user 의 abandonment
Day 5 의 sample 이 affected user 의 subset
Treatment 의 affected user 가 이미 abandoned
→ Treatment 의 sample 가 Control 보다 적음
→ SRM
2.3.2 일반화
Re-randomize 안 함의 trade-off:
Pros:
- User 의 일관 경험 (variant 안 변경)
- Implementation 단순
Cons:
- Pre-fix 의 영향 carry-over
- Sample 의 selection bias
- SRM 가능
2.3.3 해결
Option 1: Re-randomize:
새 random seed
Pre-fix 영향 제거
단 사용자 의 variant 변경 (UX 영향)
Option 2: Cool-down period:
Pre-fix 영향 의 attenuation 대기
Day 8~14 만 분석
Sample size 손실
Option 3: Bias correction:
Pre-period 의 metric 으로 boost
Affected user 의 weight 보정
Implementation 복잡
대부분 case: Option 1 (re-randomize) 또는 Option 2 (cool-down).
저자 인용 (Kohavi et al. 2012): residual effect 의 표준 사례.
2.4 Cause 4 — Bad Trigger Condition
저자 명시.
2.4.1 Redirect 사례
저자 명시 (Ch.20 의 Browser Redirect).
시나리오:
Site A → Site A' (Treatment redirect)
Trigger condition: "user reached A'"
Issue:
Redirect 의 일부 loss:
- Network failure
- Browser bug
- User abandonment (slow redirect)
Treatment user 의 일부 가 A' 도달 못 함
Trigger 안 됨
→ Triggered Treatment 가 Control 보다 적음
→ SRM in triggered analysis
2.4.2 Asymmetric Trigger
일반적 mistake:
Trigger condition 가 Treatment 만 의 event 기반
Control 의 counterfactual trigger 부재
예:
Trigger: "사용자 가 새 feature 사용"
Control 의 새 feature: 없음
→ Trigger condition 의 evaluation 의 asymmetric
Result:
Treatment 의 trigger event log
Control 의 trigger event 부재
→ SRM in triggered analysis
2.4.3 해결
Symmetric trigger condition:
Treatment·Control 양쪽에서 evaluable
Same trigger event log
Counterfactual logging (F-KOH20-2)
Implementation:
Trigger 가 user 의 action 또는 segment 의
Variant 의 영향 받지 않는 condition
이 symmetric 가 trigger 의 표준.
2.5 Cause 5 — Treatment-Affected Attribute
저자 명시.
2.5.1 Dormant User 사례
저자 명시.
시나리오:
Campaign: dormant user 에 promotion
Trigger condition: "user.dormant == True"
Dormant attribute:
User profile DB 에 저장
Last seen > 30 days 시 dormant
자동 update
Issue:
Treatment 의 효과:
Dormant user 가 active
Last seen 시점 update
"Dormant" attribute → False
분석 시 trigger condition evaluation:
실험 끝 시점 의 dormant
→ Treatment 의 일부 (active 화된) user 가 dormant 아님
→ 분석 에서 제외
Control:
Dormant user 가 active 안 함
"Dormant" attribute 유지
→ 분석 에 포함
→ Treatment 의 user 가 분석 에 적게 포함
→ Triggered SRM
2.5.1.1 해결
저자 강조: “The analysis should be triggered to the state of the dormant attribute before the experiment started (or before each user was assigned).”
Pre-experiment timing 의 trigger:
Trigger condition 의 evaluation:
Pre-experiment 의 attribute 사용
Treatment 의 영향 받지 않음
Implementation:
Attribute 의 snapshot (실험 시작 시점)
Trigger condition 의 evaluation 시 snapshot 사용
Why this works:
Pre-experiment attribute 가 immutable (실험 영향 안 받음)
Trigger condition 의 stable
→ Symmetric trigger
→ No SRM
2.5.2 ML Attribute 의 자동 Update
저자 강조: “Trigger conditions based on machine learning algorithms are especially suspect because models may be updated while the experiment is running and impacted by Treatment effect.”
시나리오:
Trigger condition: "ML model 의 prediction == X"
ML model 의 자동 update:
실험 중 model 의 retrain
New training data 가 Treatment 의 영향 받음
Model 의 prediction 변화
Issue:
Treatment 의 user 의 prediction 변화
Trigger condition 의 evaluation 변화
→ Triggered set 의 변동
→ SRM
2.5.2.1 해결
ML model 의 freeze:
실험 기간 동안 model 변경 금지
Pre-experiment 의 model 만 사용
Implementation:
Model version 의 pinning
Experiment-specific 의 stable model
Trade-off:
ML model 의 진화 손실 (단기)
실험 의 trustworthy 우선
이 ML attribute 의 함정이 modern AI-driven product 의 가장 미묘한 SRM cause.
2.6 6 가지 Debugging 단계
저자 명시 (Ch.21.4).
2.6.1 Step 1 — Upstream Check
저자 강조: “Validate that there is no difference upstream of the randomization point or trigger point.”
2.6.1.1 Bing Image 사례
Setup:
Bing Image team 의 실험 (image search 의 변경)
Trigger: image search query
Issue:
Treatment 의 image search 결과 의 일부 가 inline regular Bing
→ Bing 의 web search 에 image result 노출
→ Web search experience 변경
→ Web search 의 SRM 영향
Investigation:
Upstream check:
Bing web search (upstream of image)
Treatment 의 web search behavior 변경
→ Web search 도 영향
→ Trigger 의 redefinition 필요
해결:
Trigger 의 확대:
Image OR web search 의 Treatment 영향
더 broad triggered set
Sample mismatch 회피
이 사례 가 upstream check 의 가치.
2.6.2 Step 2 — Variant Assignment Validation
저자 명시.
Hash function 의 검증:
Hash(user_id) % 2 → 0 또는 1
Distribution 의 uniform 검증
Concurrent experiments:
Multiple experiments 의 isolation
Hash collision 의 detection
2.6.2.1 사례 — Concurrent Experiment Theft
저자 명시.
Setup:
Experiment A: font color 변경 (black → dark blue)
Experiment B (concurrent): background color 변경
Filter: "user with font set to black"
Issue:
B 의 filter 가 user 의 font 의존
A 의 Treatment 가 일부 사용자 의 font 변경 (dark blue)
→ B 의 filter 의 evaluation 변화
→ 일부 user 가 A 의 font-black variant 에서 B 의 분석에 포함
→ A 의 font-black variant 의 일부 user 가 stolen by B
→ A 의 SRM
2.6.2.2 해결
Isolation group:
A 와 B 의 isolation
Same user 가 둘 다 의 noise 안 됨
또는 attribute snapshot:
B 의 filter 의 pre-experiment font
A 의 영향 받기 전 의 attribute
2.6.3 Step 3 — Pipeline Stages
저자 명시: “Follow the stages of the data processing pipeline to see whether any cause an SRM.”
2.6.3.1 Stage 별 SRM
Pipeline:
Raw data → bot filter → cleaning → enrichment → analysis
각 stage 의 SRM check:
Stage 1 (raw): pass
Stage 2 (after bot filter): fail (← root cause)
Stage 3 (after cleaning): fail (carry-over)
Stage 4 (analysis): fail
→ Bot filter 가 root cause
→ Investigation 의 focus
2.6.3.2 Bing 의 자동 tooling
Modern platform:
Pipeline stage 별 SRM 의 자동 check
Each stage 의 sample count
Stage 의 transition 시 mismatch 발생 시 alert
Tools:
- Stage-by-stage dashboard
- Mismatch attribution
- Stage 의 owner 식별
2.6.4 Step 4 — Initial Period Exclude
저자 명시: “Is it possible that both variants did not start together?”
2.6.4.1 시나리오
Shared control:
Multiple experiments 의 공유 control
Control 가 항상 active
Treatment 가 새로 시작
Issue:
Treatment 의 ramp-up:
Day 1: 1% (slowly)
Day 7: 50%
Cache:
Control 의 cache 가 warm (이전 실험 의 잔재)
Treatment 의 cache 가 cold
Apps:
Mobile app 의 Treatment 코드 의 push 시간
일부 user 가 update 안 됨
Phones offline:
일부 user 가 offline 상태
Treatment 도달 지연
→ Initial period 의 sample mismatch
2.6.4.2 해결
Initial period exclusion:
Day 1~3 의 데이터 제외
Stable adoption 후 만 분석
이 표준 절차 가 cache·ramp 의 issue 회피.
2.6.5 Step 5 — Segment Analysis
저자 명시.
2.6.5.1 Segment dimensions
Day-by-day:
특정 day 의 anomaly?
Ramp 의 변경?
Other experiment 의 시작?
Browser:
Browser 의 specific bug?
Old version compatibility?
User type:
New vs returning?
Heavy vs light?
Country, region, device, language 등
2.6.5.2 Bing Scenario 2 의 reapply
Bing 의 사례 (F-KOH21-1):
Browser segment:
Old Chrome: SRM
Other browsers: pass
→ Old Chrome user exclude → SRM 해결
이 segment-by-segment 의 표준 debug.
2.6.6 Step 6 — Cross-Experiment Intersection
저자 명시: “Look at the intersection with other experiments. Treatment and Control should have similar percentages of variants from other experiments.”
2.6.6.1 시나리오
Setup:
Experiment A: T_A vs C_A (50/50)
Experiment B (concurrent): T_B vs C_B (50/50)
Independent:
A 의 user 가 B 의 어느 variant?
Random
Expected: 50/50
Check:
A_T 의 user 의 B variant 분포
A_C 의 user 의 B variant 분포
Should be both 50/50
Bug:
A_T 가 B_T 의 80%, B_C 의 20% (random 이 아님)
A_C 가 B_T 의 30%, B_C 의 70%
→ Hash collision 또는 isolation issue
→ A 와 B 의 cross-pollination
→ SRM in both experiments
해결:
Isolation group 의 redesign
Hash seed 의 separation
이 cross-experiment check 가 mature platform 의 표준 debug.
2.6.6.2 Layered investigation
Outer layer (causes):
Step 1 — Upstream: 실험 의 boundary check
Step 2 — Randomization: implementation 의 정확성
Inner layer (data):
Step 3 — Pipeline: each stage 의 정확성
Step 4 — Initial: timing 의 정확성
Granular (segments):
Step 5 — Segments: which user group?
Step 6 — Intersection: cross-experiment
순서:
Outer → Inner → Granular
점진적 narrowing
2.6.6.3 Action priority
Step 1 fail:
실험 의 boundary 잘못
Trigger redefine
Step 2 fail:
Implementation bug
Hash 또는 isolation fix
Step 3 fail:
Pipeline stage fix
Bot filter, cleaning 의 logic
Step 4 fail:
Initial period exclude
Cache, ramp 의 timing
Step 5 fail:
Affected segment exclude
Browser bug fix
Step 6 fail:
Cross-experiment isolation
Hash separation
2.6.6.4 Tooling 의 evolution
Manual investigation:
- SQL queries
- Pipeline log inspection
- Time consuming
Automated tooling:
- Per-stage SRM check
- Segment-level analysis
- Cross-experiment monitor
- Engineer-friendly dashboard
Modern platform:
Manual + automated
Automated 의 first pass
Manual 의 deep investigation
이 progression 이 platform maturity 의 한 차원.
3 왜 필요한가
5 cause + 6 debug 부재 시.
- SRM 의 root cause 모름: Fix 의 trial-and-error
- Bug 의 silent damage: 누적된 incorrect decisions
- Investigation 의 inefficient: 분석가 의 time loss
활성 시.
- Systematic debug: Fast root cause identification
- Bug fix: Permanent solution
- Tooling investment: Future SRM 의 빠른 resolution
이 framework 이 mature platform 의 표준.
4 응용 사례 — Microsoft ExP 의 SRM Tool
ExP 의 자동 SRM 의 tooling (가상 reconstruction):
When SRM detected:
Automated diagnostics:
1. Upstream check (pre-randomization metric difference)
2. Hash distribution test
3. Pipeline stage SRM:
- Raw data
- After bot filter
- After cleaning
- After enrichment
4. Initial period analysis (Day 1~3 exclude 시 SRM 변화)
5. Segment SRM (browser, country, day, user_type)
6. Cross-experiment intersection check
Output:
- Root cause hypothesis (가장 likely cause)
- Suggested fix
- Investigation report
Engineer 의 review:
Automated report 의 hypothesis 검토
Specific stage 의 deep dive
Fix implement
Re-experiment
Time savings:
Manual SRM debug: 며칠
ExP automated: 시간 단위
이 tooling 이 mature platform 의 ROI 의 한 부분.
5 코드 예시 — 6 Step Debugging Tool
자동 SRM debug 의 implementation.
import numpy as np
import pandas as pd
from scipy import stats
rng = np.random.default_rng(42)
def srm_check(t_count, c_count, expected_ratio=0.5, alpha=0.001):
"""SRM check using chi-square test."""
n_total = t_count + c_count
if n_total == 0:
return {"passed": None, "p_value": None}
expected_t = n_total * expected_ratio
expected_c = n_total * (1 - expected_ratio)
chi2 = (t_count - expected_t)**2 / expected_t + (c_count - expected_c)**2 / expected_c
p_value = 1 - stats.chi2.cdf(chi2, df=1)
return {
"t_count": t_count,
"c_count": c_count,
"ratio": t_count / max(c_count, 1),
"p_value": p_value,
"passed": p_value > alpha
}
# 가상 실험 with simulated SRM (browser bug)
n_users = 500_000
treatment = rng.choice([0, 1], n_users, p=[0.5, 0.5])
browser = rng.choice(["Chrome", "Firefox", "Safari", "OldChrome"], n_users, p=[0.5, 0.2, 0.25, 0.05])
# Bug: OldChrome user 의 Treatment 의 일부 가 bot 분류 (10% loss)
is_bot = np.zeros(n_users, dtype=bool)
for i in range(n_users):
if browser[i] == "OldChrome" and treatment[i] == 1:
if rng.uniform(0, 1) < 0.30: # 30% reclassified as bot
is_bot[i] = True
valid_users = ~is_bot
# === Automated SRM Debug ===
print("=== SRM Debug Tool ===\n")
# Step 1: Overall SRM
print("Step 1: Overall SRM Check")
result = srm_check(((treatment == 1) & valid_users).sum(),
((treatment == 0) & valid_users).sum())
print(f" T: {result['t_count']:,}, C: {result['c_count']:,}")
print(f" Ratio: {result['ratio']:.4f}")
print(f" P-value: {result['p_value']:.2e}")
if not result['passed']:
print(f" *** SRM DETECTED — proceeding to debug ***\n")
# Step 2: Pre-randomization (upstream check) - simulated
print("Step 2: Pre-randomization Upstream Check")
print(" No upstream metric difference assumed")
print(" PASS (proceed)\n")
# Step 3: Pipeline stages
print("Step 3: Pipeline Stage SRM")
stages = [
("Raw data (pre-filter)",
((treatment == 1)).sum(),
((treatment == 0)).sum()),
("After bot filter",
((treatment == 1) & valid_users).sum(),
((treatment == 0) & valid_users).sum()),
]
for stage_name, n_t, n_c in stages:
r = srm_check(n_t, n_c)
status = "PASS" if r['passed'] else "FAIL"
print(f" {stage_name}: T={n_t:,}, C={n_c:,}, p={r['p_value']:.4f} [{status}]")
# Identify offending stage
print()
if srm_check(((treatment == 1)).sum(), ((treatment == 0)).sum())['passed']:
print(" ROOT: Bot filter introduced SRM\n")
# Step 4: Initial period (simulated, no day data here)
print("Step 4: Initial Period (skip — no time data)\n")
# Step 5: Segment analysis
print("Step 5: Segment SRM (Browser)")
for b in ["Chrome", "Firefox", "Safari", "OldChrome"]:
seg_mask = (browser == b) & valid_users
n_t_seg = (seg_mask & (treatment == 1)).sum()
n_c_seg = (seg_mask & (treatment == 0)).sum()
r = srm_check(n_t_seg, n_c_seg)
status = "PASS" if r['passed'] else "FAIL"
print(f" {b}: T={n_t_seg:,}, C={n_c_seg:,}, p={r['p_value']:.4f} [{status}]")
# Step 6: Cross-experiment (simulated)
print("\nStep 6: Cross-experiment Intersection (skip — single experiment)\n")
# Recommendation
print("=" * 50)
print("=== Diagnosis ===")
print("Root cause: Bot filter reclassifies OldChrome users")
print("Fix options:")
print(" 1. Update bot detection to handle OldChrome correctly")
print(" 2. Exclude OldChrome users from analysis")
print(" 3. Re-run after bot detection fix")
print()
# After exclude
print("=== After Excluding OldChrome ===")
new_valid = valid_users & (browser != "OldChrome")
result_new = srm_check(((treatment == 1) & new_valid).sum(),
((treatment == 0) & new_valid).sum())
print(f"T: {result_new['t_count']:,}, C: {result_new['c_count']:,}")
print(f"Ratio: {result_new['ratio']:.4f}")
print(f"P-value: {result_new['p_value']:.4f}")
print(f"Result: {'PASS' if result_new['passed'] else 'FAIL'}")5.0.0.1 Manual vs Automated
Manual SRM debug:
- SQL queries (수십~수백 개)
- 분석가 의 hypothesis testing
- 며칠 걸림
Automated tool:
- 6 step 의 자동 실행
- 분 단위 결과
- Root cause 의 hypothesis 즉시
5.0.0.2 Modern Platform 의 Standard
Microsoft ExP, LinkedIn Concourse, Google Internal:
- SRM detected → automatic diagnostics
- Engineer 에게 root cause hypothesis 제공
- Specific segment, stage 의 evidence
ROI:
Manual: weeks of investigation
Automated: hours
→ 10x productivity
5.0.0.3 Iterative Debug
Tool 의 limit:
- 일부 cause 의 detect 만
- Complex case 의 manual deep dive
Hybrid approach:
Automated 의 first pass
Manual 의 specific deep dive
Best of both
이 hybrid 가 mature platform 의 표준.
6 관련 주제
선행
다음 글
관련 챕터
- F16-1 — Bot Filtering
- F20-* — Triggering — Trigger condition issues
- F15-* — Ramping — Ramp 시 SRM
다른 카테고리 연결