1 정의
Kohavi (2020) Ch.20.2~20.4 의 첫 3 사례. 각각 다른 mechanism 의 trigger.
| Pattern | 정의 | 예시 |
|---|---|---|
| Partial Exposure | 사전 정의된 segment 만 노출 | US users only, Edge browser |
| Conditional Exposure | 특정 행동 시 노출 | Checkout 시작, weather query |
| Coverage Increase | 처치 영역 단순 확장 | Free shipping $35 → $25 |
1.0.0.1 Pattern 의 공통 원칙
Triggered subset = {사용자 | Treatment 와 Control 의 결과 달라질 가능성}
Non-triggered = {사용자 | Treatment effect = 0 보장}
분석:
Triggered subset 만 분석 → effect dilution 회피
Non-triggered 무시 → noise 제거
원문 인용 (Ch.20.2): “If you make a change that only impacts some users, the Treatment effect of those who are not impacted is zero. This simple observation of analyzing only users who could have been impacted by your change has profound implications for experiment analysis.”
핵심 통찰: 3 패턴의 본질이 같다 — counterfactual 의 difference. Pattern 1 은 segment 정의로 명백, pattern 2 는 사용자 행동으로 conditional, pattern 3 은 set 연산 (T \ C). 메커니즘이 달라도 trigger 의 본질은 같음.
2 개념 및 원리
2.1 Pattern 1 — Partial Exposure (의도적 부분 노출)
저자 명시 (Ch.20.2 Example 1).
2.1.1 시나리오 — Geo-Specific Change
실험: 새 feature, US users 만 영향
이유:
- Localization (US 시장 의 specific need)
- Regulatory (US 규제 만 적용)
- Phase rollout (US 부터 점진 expansion)
Trigger condition:
사용자 의 location == US
Triggered subset:
US users 만 분석
Non-US users 분석 제외
2.1.1.1 Effect 의 dilution 회피
시나리오:
US users: 10% of population
Treatment effect on US: +5%
Non-US: 0% effect
Naive analysis:
Effect = 0.10 × 5% + 0.90 × 0% = 0.5%
→ Effect 가 1/10 dilute
Triggered analysis:
Effect = 5% (US users 만 분석)
→ Full effect 측정
2.1.2 Mixed Users 의 처리
저자 강조: “you must include ‘mixed’ users, those from both the United States and other countries, in the analysis if they could have seen the change.”
2.1.2.1 시나리오 — 여행 사용자
사용자 Alice:
- 평소 거주: 미국 (Treatment 노출 가능)
- 여행: 영국 (Treatment 미노출)
분석 시:
Alice 가 US 에서 visit: Treatment 노출 → triggered
Alice 가 영국에서 visit: Treatment 미노출 → 영향 없음?
2.1.2.2 핵심 — Residual Effect
저자 강조: “Be sure to include all their activities after seeing the change even activities performed outside the United States, because they were exposed and there could be residual effects on the non-US visit.”
Residual effect 의 메커니즘:
Day 1 (US): Alice 가 새 feature 봄
Day 2 (영국): Alice 가 visit
- 영국 server 의 feature 미노출
- But Alice 의 mental model 이 이미 changed
- "I know this feature exists"
- 행동 변화 가능 (search 패턴, 구매 패턴)
따라서:
Triggered = mixed users 의 모든 visit (US 또는 비 US)
Trigger 한 번 하면 lifetime trigger
2.1.2.3 Triggered 의 lifetime 추적
Implementation:
사용자 가 US visit 시 → "triggered" flag 설정
이후 모든 visit (어느 location 이든) → triggered analysis 포함
Why:
- Residual effect 정확 측정
- Cross-location user behavior 분석
- Treatment 의 진정 lifetime impact
2.1.3 다른 Partial 사례
저자 명시.
2.1.3.1 Browser-specific
실험: Edge browser 에만 새 feature
Trigger: User-agent == Edge
함정:
User-agent spoofing 가능 (사용자가 Edge 위장)
Privacy mode 의 user-agent 다름
해결:
Server-side detection
Client-side detection 의 cross-validation
2.1.3.2 Geographic by Zip
실험: 특정 zip code 의 free same-day shipping
Trigger: shipping address 의 zip code == 특정 list
복잡성:
Multi-address 사용자 (work vs home)
Address 의 거짓 입력
Mobile user (location 변동)
해결:
Most recent shipping address
또는 사용자 declared primary address
2.1.3.3 Heavy Users
저자 강조 (Ch.20.2): “users who visited your website at least three times in the last month (note that it’s critical that the definition be well-defined based on data prior to the experiment start and not one that could be impacted by the Treatment).”
Trigger: heavy user definition
Wrong (Treatment 영향 받음):
"3+ visits during experiment"
- Treatment 가 visit 빈도 영향
- Selection bias
Correct (pre-experiment data):
"3+ visits in 30 days BEFORE experiment start"
- Pre-period data 만
- Trigger 정의가 immutable
- Selection bias 없음
2.1.3.4 Trigger Definition 의 timing 의 critical 성
Pre-period data 의 가치:
- Trigger condition 이 Treatment 의 영향 안 받음
- Counterfactual stable
- Trustworthy 분석
Post-experiment data 시:
- Trigger 정의 자체가 noise
- Selection bias 가능
- 분석 결과 의심
이 timing 이 trigger 정의의 hard rule.
가정: US users 만 trigger, 여행 사용자 (US + 비 US) 무시.
2.1.3.5 결과
시나리오:
사용자 Alice: 평소 US 거주, 가끔 영국 여행
Treatment 가 Alice 의 US visit 시 새 feature
Alice 가 영국 visit 시 행동 변화 (residual)
Naive (US visit 만 분석):
Alice 의 US visit: Treatment 효과 측정
Alice 의 영국 visit: 분석 제외
Issue:
영국 visit 도 residual effect 가짐
분석에서 빠지면 effect 의 일부 누락
Treatment 의 진정 lifetime impact 부정확
Mixed users 포함:
Alice 의 모든 visit 분석 (US 또는 영국)
Lifetime impact 정확
2.1.3.6 산업 표준
대부분 platform: trigger 한 번 하면 lifetime 추적. Trigger flag 가 sticky — 사용자 의 모든 future visit 에서 triggered.
이것이 trigger 의 mental model 의 본질.
2.2 Pattern 2 — Conditional Exposure (조건 노출)
저자 명시 (Ch.20.2 Example 2).
2.2.1 시나리오 — Checkout Flow
실험: Checkout 흐름의 button color 변경
Trigger: 사용자 가 checkout 시작
Non-trigger:
- Browse 만 한 사용자 (구매 의도 없음)
- Cart 추가 후 abandoning
- Login 만 한 사용자
Triggered:
- Cart → "Proceed to checkout" click
- Checkout 의 첫 page 도달
2.2.1.1 분석 효율
일반 e-commerce:
10% 사용자 가 checkout 시작
90% 가 browse only
Naive:
Effect 가 1/10 dilute
Sample size: 10x
Triggered:
10% 만 분석
Effect: full magnitude
2.2.2 4 가지 conditional 사례
저자 명시.
2.2.2.1 사례 1 — Checkout 변경
Trigger: checkout 시작 (cart → checkout flow 진입)
Non-trigger:
- 모든 browsing user
- Cart abandon user
- Login but no add-to-cart
Implementation:
사용자 의 first checkout action 시 trigger
이후 모든 activity 분석 포함
2.2.2.2 사례 2 — Collaboration 변경 (Word, Docs)
Trigger: collaboration session 참여
- Multi-user document editing
- Real-time co-authoring
Non-trigger:
- Single-user document
- Read-only access
- Comment only (no editing)
Implementation:
Co-editing event detect 시 trigger
2.2.2.3 사례 3 — Unsubscribe Screen 변경
Trigger: unsubscribe screen 도달
- Settings → unsubscribe link
- Email 의 unsubscribe link
- Account closure flow
Non-trigger:
- 모든 normal user
- 90%+ 사용자
Implementation:
Unsubscribe screen URL access 시 trigger
2.2.2.4 사례 4 — Search Result Page 의 Weather Widget
Trigger: weather query (예: "weather Seattle")
- Search query 가 weather pattern 매칭
- Search engine 의 weather answer 노출
Non-trigger:
- 95% 의 query (weather 무관)
Implementation:
Weather answer 노출 시 trigger
사용자 의 후속 query 도 추적 (residual)
2.2.2.5 Conditional 의 implementation 패턴
Algorithm:
for each user event:
if event_matches_trigger_condition:
mark_user_as_triggered()
분석 시:
triggered_users = users_with_trigger_flag
metrics = compute(triggered_users)
이 sticky flag pattern 이 conditional triggering 의 표준.
2.2.3 Conditional 의 challenge — Counterfactual
저자 명시 (later in Ch.20).
2.2.3.1 Trigger condition 의 명확성
명확한 conditional:
"사용자가 checkout flow 도달"
- Treatment·Control 모두 같은 trigger event
- Counterfactual 동일
애매한 conditional:
"사용자 가 새 feature 사용"
- Treatment 만 새 feature
- Control 의 counterfactual: "이 사용자가 새 feature 가 있었으면?"
- 측정 어려움
2.2.3.2 Symmetric Trigger 의 유지
Best practice:
Trigger condition 이 Treatment·Control 양쪽에서 evaluable
Same set 의 사용자가 trigger
Comparison 의 정확성
Implementation:
Treatment 가 새 feature 추가 시:
Original feature 가 Control 에서 trigger 만
Trigger logic 자체가 같은 user identification
Anti-pattern:
Trigger 가 Treatment-specific 일 때:
Control 의 trigger 가 모호 또는 missing
Counterfactual 정의 어려움
이 symmetric 가 conditional 의 trustworthy 의 본질.
2.3 Pattern 3 — Coverage Increase
저자 명시 (Ch.20.4 Example 3).
2.3.1 시나리오 — Free Shipping Threshold
Original (Control):
사용자 가 cart > $35 시 free shipping
Treatment:
사용자 가 cart > $25 시 free shipping
(threshold lowered)
2.3.2 사용자 의 3 가지 분류
Class 1: cart > $35
Control: free shipping
Treatment: free shipping (same)
→ Same experience → Treatment effect = 0
Class 2: cart < $25
Control: paid shipping
Treatment: paid shipping (same)
→ Same experience → Treatment effect = 0
Class 3: cart in [$25, $35]
Control: paid shipping
Treatment: free shipping (different!)
→ Different experience → Treatment effect ≠ 0
2.3.2.1 Triggered subset
Triggered = Class 3 만
Non-triggered = Class 1 + Class 2
분석:
Class 3 사용자 만 분석 → full effect 측정
Other classes 무시 → noise 제거
2.3.3 Venn Diagram 시각화
저자 명시 Figure 20.1.
Original Control coverage (free shipping):
Set C = {users | cart > $35}
Treatment coverage:
Set T = {users | cart > $25}
Coverage increase:
T ⊃ C (T contains C)
Triggered:
T \ C = {users | cart in [$25, $35]}
(Treatment 의 새 영역 만)
2.3.3.1 Set 의 mathematical 처리
Inclusion 관계:
T \ C = T ∩ C^c
= {x | x ∈ T ∧ x ∉ C}
Triggered subset:
사용자 의 cart 가 [$25, $35] in any visit
Variant 별 다른 결과 받은 사용자
2.3.3.2 사용자 가 multiple visit 시
사용자 Bob:
Visit 1: cart $40 → C 와 T 모두 free shipping (no trigger)
Visit 2: cart $30 → C 는 paid, T 는 free (trigger)
Visit 3: cart $20 → C 와 T 모두 paid (no trigger)
Bob 의 trigger:
Visit 2 가 first trigger event
Trigger flag set
이후 모든 visit (Visit 3 포함) 분석에 포함
Why include Visit 3:
Bob 의 Visit 2 의 free shipping 경험이 행동 변화
Visit 3 의 행동도 residual effect 영향
이 inclusion 이 lifetime tracking 의 본질.
2.3.4 함정 — Free Shipping 의 광고
저자 강조: “we assume that no ‘advertisement’ of the free shipping promotion is on the site; if at some point free shipping displays for the user and it is different between Control and Treatment, that immediately becomes a trigger point.”
2.3.4.2 Implementation 의 detail
Banner 의 effect 가 cart amount 와 독립:
Triggered = home page visitor (모든 사람)
→ Triggering 의 가치 ↓ (거의 모든 user trigger)
Banner 의 effect 가 specific:
Triggered = banner 봄 + cart amount 의 specific range
→ 더 narrow trigger
2.3.4.3 실무 결정
Trigger condition 의 결정:
Conservative: 모든 home page visitor (over-trigger)
Aggressive: cart [$25, $35] 만 (banner 효과 무시)
선택:
Banner 의 effect 가 minor → cart 만
Banner 가 dominant → 모든 visitor
대부분 case:
Conservative trigger (over-include) 권고
Sensitivity 약간 손실 but trustworthy
3 패턴이 모두 set 연산.
2.3.4.4 Pattern 1 — Partial
Set:
All users = U
Triggered = subset of U (predefined)
Triggered = {users in segment S}
2.3.4.5 Pattern 2 — Conditional
Set:
All users = U
Triggered = users with action A
Triggered = {users | action A occurred}
2.3.4.6 Pattern 3 — Coverage Increase
Set:
Control coverage = C
Treatment coverage = T (T ⊃ C)
Triggered = T \ C
Triggered = {users | x ∈ T but x ∉ C}
2.3.4.7 통합 mental model
모든 trigger condition:
Triggered = {x | f_T(x) ≠ f_C(x)}
where f_V is the experience under variant V
Pattern 1: f differs by segment
Pattern 2: f differs after action A
Pattern 3: f differs in coverage area
이 unified view 가 triggering 의 통합 framework. 다른 implementation 이지만 same logic.
2.3.4.8 Implementation 의 hierarchy
가장 단순 (Pattern 1):
Pre-defined segment
No counterfactual evaluation needed
→ 가장 일반적
중간 (Pattern 2):
Sticky flag based on action
No explicit counterfactual
→ 일반적
복잡 (Pattern 3):
Set difference
Counterfactual evaluation 필요 (banner 의 효과 등)
→ Mature platform
이 hierarchy 가 maturity 의 적용 순서.
2.4 Pattern 1·2·3 의 implementation 비교
2.4.1 Pre-experiment Setup 비교
Pattern 1 — Partial:
사전 segment definition (DB query)
실험 시작 시 정의 fixed
사용자 의 segment membership static
Pattern 2 — Conditional:
Trigger event definition (action 정의)
Real-time event detection
사용자 의 trigger flag dynamic
Pattern 3 — Coverage Increase:
Treatment·Control coverage definition
Set difference computation
사용자 의 cart amount 의 dynamic 평가
2.4.2 Logging 요구
Pattern 1:
- User segment data (pre-experiment)
- Visit log (during experiment)
Pattern 2:
- Action event log
- Trigger flag tracking
Pattern 3:
- User cart amount (per visit)
- Coverage logic 의 결과
- Trigger event log
2.4.3 Implementation Cost
Pattern 1: low (segment 만)
Pattern 2: medium (event tracking)
Pattern 3: high (coverage logic + counterfactual)
이 cost 가 mature platform 의 phased adoption 의 reason.
3 왜 필요한가
3 patterns 의 triggering 부재 시.
- Niche feature 의 dilution: Effect 가 1/10 ~ 1/100 dilute
- False negative: Real effect 가 noise 에 묻힘
- 실험 시간 ↑: Same sensitivity 위해 더 큰 sample, 더 긴 시간
활성 시.
- Effect 의 진정 magnitude
- Sensitivity 5~100x (depends on trigger rate)
- Decision speed 가속
4 응용 사례 — Microsoft Office 의 Conditional Triggering
Microsoft Office 의 collaboration 실험:
실험: Word 의 co-authoring UI 변경
Trigger: 사용자 가 multi-user document editing 시작
Implementation:
Real-time co-authoring detect:
- Multiple users 가 same document 동시 수정
- User 가 다른 사용자 의 cursor·changes 봄
Trigger event log
분석:
Triggered users: ~5% (collaboration 자주 안 함)
Effect on triggered: +10% engagement (collaboration metric)
Naive analysis:
Effect: 0.05 × 10% = 0.5%
→ Detect 어려움 (variance 큼)
Triggered analysis:
Effect: 10%
→ Detect 쉬움 (sensitivity 20x)
Decision:
Launch collaboration UI 변경
ROI 정확 측정
이 사례가 conditional triggering 의 실무 가치.
5 코드 예시 — Triggered vs Naive Analysis
3 패턴 의 sample analysis 비교.
import numpy as np
import pandas as pd
from scipy import stats
rng = np.random.default_rng(42)
# 가상 데이터 — 5000 users
n_users = 5000
# Pattern 1: Partial Exposure (US users only)
def pattern_1_geo_partial():
print("=== Pattern 1: Geo-Partial (US only) ===")
user_country = rng.choice(["US", "UK", "DE", "FR"], n_users, p=[0.3, 0.2, 0.2, 0.3])
treatment = rng.choice([0, 1], n_users, p=[0.5, 0.5])
# Treatment effect: +5% engagement on US users
baseline_engagement = rng.normal(50, 15, n_users)
treatment_effect = np.where(
(user_country == "US") & (treatment == 1),
baseline_engagement * 0.05,
0
)
final_engagement = baseline_engagement + treatment_effect
# Naive analysis
naive_t = final_engagement[treatment == 1]
naive_c = final_engagement[treatment == 0]
_, p_naive = stats.ttest_ind(naive_t, naive_c)
naive_lift = (naive_t.mean() - naive_c.mean()) / naive_c.mean() * 100
print(f"Naive (all users): lift={naive_lift:.2f}%, p={p_naive:.4f}")
# Triggered analysis (US only)
us_mask = user_country == "US"
triggered_t = final_engagement[us_mask & (treatment == 1)]
triggered_c = final_engagement[us_mask & (treatment == 0)]
_, p_triggered = stats.ttest_ind(triggered_t, triggered_c)
triggered_lift = (triggered_t.mean() - triggered_c.mean()) / triggered_c.mean() * 100
print(f"Triggered (US): lift={triggered_lift:.2f}%, p={p_triggered:.4f}")
# Pattern 2: Conditional Exposure (Checkout users)
def pattern_2_checkout_conditional():
print("\n=== Pattern 2: Conditional (Checkout users) ===")
initiated_checkout = rng.choice([0, 1], n_users, p=[0.9, 0.1]) # 10% checkout rate
treatment = rng.choice([0, 1], n_users, p=[0.5, 0.5])
# Conversion: 50% in checkout, +10% effect with treatment
converted = np.zeros(n_users, dtype=int)
for i in range(n_users):
if initiated_checkout[i] == 1:
base_conv = 0.5
if treatment[i] == 1:
base_conv = 0.55 # +10% relative
converted[i] = rng.binomial(1, base_conv)
# Naive analysis (all users)
naive_t = converted[treatment == 1]
naive_c = converted[treatment == 0]
_, p_naive = stats.ttest_ind(naive_t, naive_c)
naive_rate_t = naive_t.mean()
naive_rate_c = naive_c.mean()
print(f"Naive: T conv={naive_rate_t:.4f}, C conv={naive_rate_c:.4f}, p={p_naive:.4f}")
# Triggered analysis (checkout users only)
triggered = initiated_checkout == 1
triggered_t = converted[triggered & (treatment == 1)]
triggered_c = converted[triggered & (treatment == 0)]
_, p_triggered = stats.ttest_ind(triggered_t, triggered_c)
triggered_rate_t = triggered_t.mean()
triggered_rate_c = triggered_c.mean()
print(f"Triggered: T conv={triggered_rate_t:.4f}, C conv={triggered_rate_c:.4f}, p={p_triggered:.4f}")
# Pattern 3: Coverage Increase (Free shipping threshold)
def pattern_3_coverage_increase():
print("\n=== Pattern 3: Coverage Increase (Free shipping) ===")
cart_amount = rng.uniform(0, 100, n_users)
treatment = rng.choice([0, 1], n_users, p=[0.5, 0.5])
# Free shipping rule
# Control: free if cart > $35
# Treatment: free if cart > $25
free_shipping_control = cart_amount > 35
free_shipping_treatment = cart_amount > 25
# Triggered: cart in [$25, $35]
triggered_mask = (cart_amount >= 25) & (cart_amount <= 35)
# Conversion effect (free shipping → +20% conversion)
base_conversion_rate = 0.10
conversion_rate = np.where(
(free_shipping_treatment & (treatment == 1)) | (free_shipping_control & (treatment == 0)),
base_conversion_rate * 1.20,
base_conversion_rate
)
converted = rng.binomial(1, conversion_rate)
# Naive analysis
naive_t = converted[treatment == 1]
naive_c = converted[treatment == 0]
_, p_naive = stats.ttest_ind(naive_t, naive_c)
naive_rate_t = naive_t.mean()
naive_rate_c = naive_c.mean()
print(f"Naive: T conv={naive_rate_t:.4f}, C conv={naive_rate_c:.4f}, p={p_naive:.4f}")
# Triggered analysis (cart $25-$35 only)
triggered_t = converted[triggered_mask & (treatment == 1)]
triggered_c = converted[triggered_mask & (treatment == 0)]
_, p_triggered = stats.ttest_ind(triggered_t, triggered_c)
triggered_rate_t = triggered_t.mean()
triggered_rate_c = triggered_c.mean()
print(f"Triggered ($25-$35): T conv={triggered_rate_t:.4f}, C conv={triggered_rate_c:.4f}, p={p_triggered:.4f}")
print(f"Triggered N: {triggered_mask.sum()}")
# Run all
pattern_1_geo_partial()
pattern_2_checkout_conditional()
pattern_3_coverage_increase()각 pattern 의 결과:
5.0.0.1 Pattern 1 (Geo-partial)
Naive (all users): lift 약 1.5% (US only effect 의 dilute)
Triggered (US): lift 약 5% (full effect)
Sensitivity:
Naive p: marginal (effect dilute)
Triggered p: strong (full effect)
5.0.0.2 Pattern 2 (Checkout conditional)
Naive: 거의 0% (대부분 사용자 가 checkout 안 함)
Triggered: ~50% conversion 의 명확한 차이
→ Checkout 사용자 만 분석 시 effect detect 가능
5.0.0.3 Pattern 3 (Coverage increase)
Naive: ~2% effect (cart 외 영역 의 dilute)
Triggered (cart $25~$35): full effect
→ 정확한 free shipping effect 측정
5.0.0.4 통합 메시지
모든 pattern 에서:
Triggered analysis 가 더 sensitive
Effect 의 진정 magnitude 측정
False negative 회피
이 차이가 niche feature 분석의 ROI.
6 관련 주제
선행
다음 글
관련 챕터
다른 카테고리 연결