A/B 테스트 개요

Online Controlled Experiment — 데이터 기반 의사결정의 핵심 방법론

A/B 테스트의 정의, 역학적 원류(RCT), 통계적 프레임워크(가설 검정, 표본 크기, 검정력), 실험 설계부터 분석까지의 전체 파이프라인, 그리고 실무에서 마주하는 도전을 개관한다. 이 포스트는 A/B 테스트 시리즈의 진입점으로서, 각 세부 주제로의 학습 경로를 제시한다.

Experimentation
Statistics
저자

Kwangmin Kim

공개

2026년 03월 20일

1 정의

정의: A/B 테스트 (A/B Test)

A/B 테스트는 사용자를 무작위로 두 개 이상의 그룹(변형, variant)에 배정하고, 각 그룹에 서로 다른 경험(처치, treatment)을 제공한 뒤, 사전 정의한 지표(metric)의 차이를 통계적으로 검정하여 인과적 효과를 추정하는 온라인 대조 실험이다.

  • 역학 용어: Randomized Controlled Trial (RCT)의 IT 버전
  • 다른 이름: Online Controlled Experiment, Split Test, Bucket Test
  • 핵심 원리: 무작위 배정(randomization) → 교란 변수 통제 → 인과 추론 가능

A/B 테스트는 “A가 좋은가, B가 좋은가?”라는 단순한 질문처럼 보이지만, 그 뒤에는 역학(Epidemiology)의 실험 설계, 통계학의 가설 검정, 인과추론의 수학적 프레임워크가 결합된 정교한 방법론이 있다.


2 개념 및 원리

2.1 역학적 원류: RCT에서 A/B 테스트로

A/B 테스트는 갑자기 등장한 것이 아니다. 수백 년에 걸친 실험 설계의 진화 위에 서 있다.

시기 사건 의의
1747 James Lind의 괴혈병 실험 최초의 대조 실험
1920s R.A. Fisher의 실험 설계 이론 무작위화, 분산 분석(ANOVA) 정립
1948 Streptomycin Trial (MRC) 최초의 현대적 RCT
1990s Amazon, Google의 온라인 실험 A/B 테스트의 대규모 산업 적용
2000s~ Experimentation Platform 시대 Optimizely, Google Optimize, 자체 플랫폼

이 계보를 이해하면, A/B 테스트의 각 구성 요소가 왜 그렇게 설계되었는지 자연스럽게 납득된다.

2.2 인과추론 프레임워크

A/B 테스트의 수학적 기반은 Rubin Causal Model (잠재적 결과 프레임워크)이다.

핵심 개념: 잠재적 결과 (Potential Outcomes)

각 사용자 \(i\) 에 대해 두 가지 잠재적 결과가 존재한다:

  • \(Y_i(1)\): 처치(새 디자인)를 받았을 때의 결과
  • \(Y_i(0)\): 대조(기존 디자인)를 받았을 때의 결과

개인 처치 효과(Individual Treatment Effect):

\[ \tau_i = Y_i(1) - Y_i(0) \]

문제: 한 사용자는 처치 또는 대조 중 하나만 경험한다. \(Y_i(1)\)\(Y_i(0)\) 을 동시에 관측할 수 없다 — 이것이 인과추론의 근본 문제(Fundamental Problem of Causal Inference)이다.

개인 효과를 알 수 없으므로, 집단 수준의 평균 처치 효과(Average Treatment Effect, ATE)를 추정한다:

\[ \text{ATE} = E[Y(1) - Y(0)] = E[Y(1)] - E[Y(0)] \]

무작위 배정이 이 추정을 가능하게 한다. 처치군과 대조군이 평균적으로 동일한 특성을 가지므로:

\[ \underbrace{E[Y \mid T=1] - E[Y \mid T=0]}_{\text{관측 가능한 차이}} = \underbrace{E[Y(1)] - E[Y(0)]}_{\text{인과적 효과 (ATE)}} \]

무작위 배정이 없으면 이 등식이 성립하지 않는다 — 관측된 차이에 선택 편향(selection bias)이 섞이기 때문이다.

2.3 핵심 가정: SUTVA

SUTVA (Stable Unit Treatment Value Assumption)
  1. 간섭 없음(No Interference): 한 사용자의 처치 배정이 다른 사용자의 결과에 영향을 주지 않는다
  2. 처치의 단일 버전(No Hidden Variations): 같은 처치를 받은 사용자는 동일한 경험을 한다

위반 사례: - 소셜 네트워크에서 친구가 새 기능을 쓰면 대조군 사용자의 행동도 변한다 (간섭) - 서버 부하로 인해 처치군 내에서도 경험이 다르다 (처치 변이)

2.4 A/B 테스트의 통계적 프레임워크

A/B 테스트는 가설 검정(hypothesis testing)으로 형식화된다.

2.4.1 가설 설정

\[ H_0: \mu_T - \mu_C = 0 \quad \text{(처치 효과 없음)} \] \[ H_1: \mu_T - \mu_C \neq 0 \quad \text{(처치 효과 있음)} \]

2.4.2 네 가지 핵심 파라미터

이 네 파라미터는 서로 연결되어 있으며, 세 개를 정하면 나머지 하나가 결정된다:

파라미터 기호 의미 일반적 설정
유의수준 \(\alpha\) 효과가 없는데 “있다”고 판단할 확률 (제1종 오류) 0.05
검정력 \(1 - \beta\) 효과가 있을 때 “있다”고 판단할 확률 0.80
최소감지효과 MDE 감지하고 싶은 최소한의 효과 크기 비즈니스 맥락에서 결정
표본 크기 \(n\) 각 그룹에 필요한 대상 수 위 세 파라미터로 계산

2.4.3 표본 크기 공식

두 비율의 차이를 검정하는 경우 (이항 지표):

\[ n = \frac{(Z_{1-\alpha/2} + Z_{1-\beta})^2 \cdot (\hat{p}_C(1-\hat{p}_C) + \hat{p}_T(1-\hat{p}_T))}{(\hat{p}_T - \hat{p}_C)^2} \]

두 평균의 차이를 검정하는 경우 (연속 지표):

\[ n = \frac{(Z_{1-\alpha/2} + Z_{1-\beta})^2 \cdot 2\sigma^2}{\delta^2} \]

여기서 \(\delta = \mu_T - \mu_C\) 는 MDE이다.

실무 감각
  • 전환율 5%에서 상대적 5% 개선(5.25%)을 감지하려면 그룹당 약 120,000명이 필요하다
  • MDE를 절반으로 줄이면 필요 표본 크기는 4배로 늘어난다
  • 분산이 큰 지표(매출)는 분산이 작은 지표(클릭률)보다 훨씬 많은 표본이 필요하다

3 직관적 설명

직관: A/B 테스트는 “동시에 두 가지를 시도해보고 어느 쪽이 나은지 과학적으로 판단하는 것”이다.

새 랜딩 페이지가 더 좋은지 궁금하다면, 모든 사용자를 한꺼번에 바꾸지 말고 반은 기존(A), 반은 새 것(B)을 보여준 뒤 전환율을 비교한다. 동시에 비교하므로 계절성이나 외부 이벤트의 영향을 배제할 수 있고, 무작위로 나누므로 두 그룹의 특성이 비슷해져 공정한 비교가 된다.

“어제 vs 오늘”이 아니라 “같은 시간에 A vs B” — 이것이 핵심이다.

3.1 왜 전후 비교(Before-After)로는 안 되는가

전후 비교의 문제:

시간 →  [기존 디자인]  [새 디자인 적용]
               ↓              ↓
         전환율 3%       전환율 3.5%  → "0.5%p 효과!"

하지만...
- 계절성: 원래 이 시기에 전환율이 오른다면?
- 외부 이벤트: 경쟁사가 서비스를 중단했다면?
- 자연적 추세: 사용자 기반이 성장하고 있었다면?

A/B 테스트의 해결:

같은 시간  ─── 대조군(A): 기존 디자인 → 전환율 3.0%
          ─── 처치군(B): 새 디자인   → 전환율 3.5%

두 그룹이 동시에 같은 외부 조건을 경험하므로,
차이 0.5%p는 디자인 변경의 인과적 효과로 귀속할 수 있다.

4 왜 필요한가

4.1 의사결정의 세 가지 방식 비교

방식 장점 단점 예시
HiPPO (Highest Paid Person’s Opinion) 빠르다 편향, 검증 불가 “대표님이 파란색 좋다고 하셨다”
데이터 분석 (관찰) 패턴 발견 가능 인과 판단 불가 (상관 ≠ 인과) “파란색 버튼 페이지에서 전환율이 높다”
A/B 테스트 (실험) 인과적 효과 추정 시간, 트래픽 필요 “파란색으로 바꾸면 전환율이 0.5%p 오른다”

4.2 A/B 테스트가 필요한 순간

  • 변경의 영향을 정량화해야 할 때: “이 기능이 실제로 KPI를 개선하는가?”
  • 의사결정의 리스크를 줄이고 싶을 때: “출시하면 역효과가 나지는 않는가?”
  • 반복적 개선(iteration)을 추구할 때: “어느 버전이 더 나은가?”

4.3 A/B 테스트가 어려운 / 불가능한 상황

상황 이유 대안
트래픽이 적다 표본 크기 부족으로 검정력 부족 베이지안 방법, MAB
네트워크 효과가 강하다 SUTVA 위반 (간섭) 클러스터 무작위화, Geo-experiment
장기 효과를 봐야 한다 실험 기간 제한 장기 홀드아웃, 서로게이트 지표
윤리적 문제가 있다 처치가 해로울 수 있다 관찰 연구, 준실험 설계
가역 불가능한 변경이다 되돌릴 수 없다 단계적 롤아웃, Stepped Wedge

5 응용 분야

분야 실험 대상 핵심 지표 구체적 예시
제품 UI/UX 변경 전환율, DAU, 세션 시간 버튼 색상, 레이아웃, 온보딩 흐름
성장 퍼널 최적화 가입률, 활성화율 회원가입 단계 수 축소
마케팅 메시지/크리에이티브 CTR, CPA, ROAS 이메일 제목, 광고 이미지
검색/추천 알고리즘 변경 CTR, 체류 시간, 만족도 추천 알고리즘 업데이트
가격 가격/요금제 전환율, ARPU, LTV 구독 가격 변경
인프라 성능 최적화 로딩 시간, 에러율 CDN 변경, 캐시 전략
임상의학 치료법 비교 생존율, 재발율, 부작용 신약 vs 위약 RCT

6 예시

6.1 예시: 결제 버튼 색상 A/B 테스트

상황: 이커머스 사이트에서 결제 버튼을 초록색(A)에서 파란색(B)으로 바꾸면 전환율이 오를지 검증한다.

Step 1. 가설 설정

  • \(H_0\): 버튼 색상은 전환율에 영향을 주지 않는다 (\(p_B = p_A\))
  • \(H_1\): 버튼 색상이 전환율에 영향을 준다 (\(p_B \neq p_A\))

Step 2. 실험 설계

  • 현재 전환율: \(p_A = 3.0\%\)
  • 최소감지효과 (MDE): 상대적 10% 개선 → \(p_B = 3.3\%\)
  • \(\alpha = 0.05\), Power = \(0.80\)

표본 크기 계산:

\[ n = \frac{(1.96 + 0.84)^2 \times (0.03 \times 0.97 + 0.033 \times 0.967)}{(0.033 - 0.03)^2} = \frac{7.84 \times 0.0611}{0.000009} \approx 53{,}248 \]

그룹당 약 53,000명, 총 106,000명 필요.

Step 3. 결과 분석

그룹 사용자 수 전환 수 전환율
A (초록) 55,000 1,650 3.00%
B (파란) 55,000 1,848 3.36%
  • 차이: \(3.36\% - 3.00\% = 0.36\%p\) (상대적 12% 개선)
  • 95% 신뢰구간: \([0.06\%p, 0.66\%p]\)
  • p-value: \(0.019\)

Step 4. 의사결정

\(p = 0.019 < 0.05\) 이므로 \(H_0\) 를 기각한다. 파란색 버튼이 전환율을 통계적으로 유의하게 개선한다. 다만, 실무적으로 0.36%p가 비즈니스적으로 의미 있는 크기인지도 함께 판단해야 한다.


7 코드 예시

7.1 Step 1: 순수 Python 구현 (원리 이해)

import math

def sample_size_two_proportions(p_c, p_t, alpha=0.05, power=0.80):
    """
    두 비율 비교를 위한 표본 크기를 순수 Python으로 계산한다.
    Lachin (1981) 공식 기반.
    """
    # 표준 정규 분포의 임계값 (근사)
    z_alpha = {0.01: 2.576, 0.05: 1.960, 0.10: 1.645}
    z_beta = {0.80: 0.842, 0.85: 1.036, 0.90: 1.282, 0.95: 1.645}

    z_a = z_alpha[alpha]
    z_b = z_beta[power]

    numerator = (z_a + z_b) ** 2 * (p_c * (1 - p_c) + p_t * (1 - p_t))
    denominator = (p_t - p_c) ** 2

    n = math.ceil(numerator / denominator)
    return n

def z_test_two_proportions(n_c, x_c, n_t, x_t):
    """
    두 비율의 차이에 대한 z-검정을 순수 Python으로 구현한다.
    """
    p_c = x_c / n_c
    p_t = x_t / n_t
    p_pool = (x_c + x_t) / (n_c + n_t)

    se = math.sqrt(p_pool * (1 - p_pool) * (1/n_c + 1/n_t))
    z_stat = (p_t - p_c) / se

    # 양측 검정 p-value (표준 정규 분포 근사)
    # erfc를 이용한 p-value 계산
    p_value = math.erfc(abs(z_stat) / math.sqrt(2))

    # 95% 신뢰구간 (차이)
    se_diff = math.sqrt(p_c * (1 - p_c) / n_c + p_t * (1 - p_t) / n_t)
    ci_lower = (p_t - p_c) - 1.96 * se_diff
    ci_upper = (p_t - p_c) + 1.96 * se_diff

    return {
        "p_control": p_c,
        "p_treatment": p_t,
        "difference": p_t - p_c,
        "relative_lift": (p_t - p_c) / p_c,
        "z_statistic": z_stat,
        "p_value": p_value,
        "ci_95": (ci_lower, ci_upper),
        "significant": p_value < 0.05
    }

# --- 실험 설계 ---
print("=== 표본 크기 계산 ===")
n = sample_size_two_proportions(p_c=0.03, p_t=0.033)
print(f"그룹당 필요 표본 크기: {n:,}")
print(f"총 필요 표본 크기: {2 * n:,}")

# --- 결과 분석 ---
print("\n=== 실험 결과 분석 ===")
result = z_test_two_proportions(
    n_c=55000, x_c=1650,   # 대조군
    n_t=55000, x_t=1848    # 처치군
)

print(f"대조군 전환율: {result['p_control']:.2%}")
print(f"처치군 전환율: {result['p_treatment']:.2%}")
print(f"절대 차이: {result['difference']:.2%}p")
print(f"상대 개선: {result['relative_lift']:.1%}")
print(f"z 통계량: {result['z_statistic']:.3f}")
print(f"p-value: {result['p_value']:.4f}")
print(f"95% 신뢰구간: [{result['ci_95'][0]:.4f}, {result['ci_95'][1]:.4f}]")
print(f"유의 여부 (α=0.05): {result['significant']}")

7.2 Step 2: statsmodels 구현 (실무 활용)

import numpy as np
from statsmodels.stats.power import NormalIndPower
from statsmodels.stats.proportion import proportions_ztest, proportion_confint

# --- 표본 크기 계산 ---
# Cohen's h: 효과 크기 계산
p_c, p_t = 0.03, 0.033
cohens_h = 2 * (np.arcsin(np.sqrt(p_t)) - np.arcsin(np.sqrt(p_c)))

power_analysis = NormalIndPower()
n = power_analysis.solve_power(
    effect_size=cohens_h,
    alpha=0.05,
    power=0.80,
    alternative='two-sided'
)
print(f"그룹당 필요 표본 크기: {int(np.ceil(n)):,}")

# --- 결과 분석 ---
# 관측 데이터
successes = np.array([1848, 1650])   # [처치군, 대조군]
trials = np.array([55000, 55000])

# z-검정
z_stat, p_value = proportions_ztest(successes, trials, alternative='two-sided')
print(f"\nz 통계량: {z_stat:.3f}")
print(f"p-value: {p_value:.4f}")

# 각 그룹의 신뢰구간
for label, s, n_i in [("대조군", 1650, 55000), ("처치군", 1848, 55000)]:
    ci_low, ci_high = proportion_confint(s, n_i, alpha=0.05, method='normal')
    print(f"{label} 전환율 95% CI: [{ci_low:.4f}, {ci_high:.4f}]")

# 차이의 신뢰구간
p_t_obs = 1848 / 55000
p_c_obs = 1650 / 55000
se_diff = np.sqrt(p_t_obs * (1 - p_t_obs) / 55000 + p_c_obs * (1 - p_c_obs) / 55000)
diff = p_t_obs - p_c_obs
print(f"\n차이: {diff:.4f} ({diff/p_c_obs:.1%} relative)")
print(f"차이 95% CI: [{diff - 1.96*se_diff:.4f}, {diff + 1.96*se_diff:.4f}]")

8 A/B 테스트의 전체 파이프라인

실무에서 A/B 테스트는 다음 단계를 따른다:

1. 가설 수립
   ├── 비즈니스 문제 → 측정 가능한 가설로 변환
   ├── 핵심 지표(Primary Metric) 선정
   └── 가드레일 지표(Guardrail Metric) 선정

2. 실험 설계
   ├── MDE 결정 (비즈니스적으로 의미 있는 최소 효과)
   ├── 표본 크기 계산 (α, power, MDE, 현재 분산)
   ├── 실험 기간 결정 (주간 주기 고려, 최소 1-2주)
   ├── 무작위 배정 단위 결정 (사용자, 세션, 디바이스)
   └── 트래픽 비율 결정 (50/50 또는 비대칭)

3. 실험 실행
   ├── A/A 테스트로 플랫폼 검증
   ├── 점진적 롤아웃 (1% → 10% → 50%)
   ├── SRM(Sample Ratio Mismatch) 모니터링
   └── 가드레일 지표 모니터링

4. 결과 분석
   ├── SRM 체크 (배정 비율 검증)
   ├── 가설 검정 (z-test / t-test)
   ├── 신뢰구간 계산
   ├── 세그먼트 분석 (HTE)
   └── 실무적 유의성 판단 (통계적 유의성 ≠ 실무적 유의성)

5. 의사결정
   ├── 출시(Ship) / 반복(Iterate) / 중단(Kill) 결정
   ├── 장기 효과 고려 (novelty effect, learning effect)
   └── 문서화 및 지식 축적

9 A/B 테스트 방법론 체계

이 시리즈에서 다룰 방법론을 개관한다.

A/B 테스트
├── 기초 (Classical)
│   ├── 가설 검정 프레임워크         ← 제1종/2종 오류, p-value, 검정력
│   ├── 표본 크기 계산              ← MDE, 비율/평균 검정
│   ├── 무작위 배정                 ← 단순, 층화, 해싱
│   ├── 분석 방법                   ← z-test, t-test, 카이제곱
│   └── 실험 기간 결정              ← 주기성, peeking 문제
│
├── 고급 (Advanced)
│   ├── Sequential Testing          ← Group Sequential, SPRT, Alpha Spending
│   ├── Bayesian A/B Testing        ← 사전/사후 분포, 확률적 우위
│   ├── Multivariate Testing        ← 요인 설계, 교호작용
│   └── A/A Testing                 ← 플랫폼 검증, SRM 탐지
│
├── 분산 감소 (Variance Reduction)
│   ├── 사전: 층화, 매칭, 블로킹
│   └── 사후: CUPED, CUPAC, 회귀 보정, DiD
│
├── 인과추론 확장 (Causal Inference)
│   ├── Potential Outcomes          ← Rubin Causal Model
│   ├── DAG                         ← Pearl's Framework
│   ├── 간섭(Interference) 처리     ← 클러스터 무작위화, Switchback
│   └── 이질적 처치효과 (HTE)       ← Causal Forest, Meta-learner
│
├── Multi-Armed Bandit (MAB)
│   ├── Classical: Epsilon-Greedy, UCB, Thompson Sampling
│   ├── Contextual Bandit
│   └── A/B vs MAB 비교             ← 탐색-활용 트레이드오프
│
├── 실무 도전 (Practical Challenges)
│   ├── 지표 선정                   ← North Star, Proxy, Guardrail
│   ├── Novelty/Primacy Effect
│   ├── Network Effect / Interference
│   └── SRM (Sample Ratio Mismatch)
│
└── 플랫폼 (Platform)
    ├── 배정 서비스 (Assignment)
    ├── 로깅 파이프라인
    ├── 분석 엔진
    └── 대시보드 / 자동화

9.1 학습 경로 제안

Phase 1: 기초 (2-3주)
├── 역학 기초: RCT의 원리, 편향, 교란
├── 가설 검정: α, β, power, p-value
├── 표본 크기: MDE, 비율/평균 공식
└── 기본 분석: z-test, 신뢰구간

Phase 2: 설계와 실행 (2-3주)
├── 무작위 배정: 해싱, 층화
├── 지표 선정: Primary, Guardrail, Proxy
├── 실험 기간: 주기성, 최소 기간
└── A/A 테스트: 플랫폼 검증

Phase 3: 고급 분석 (3-4주)
├── Sequential Testing: 조기 종료
├── 분산 감소: CUPED, 회귀 보정
├── HTE: 세그먼트별 효과 분석
└── 간섭 처리: 네트워크 효과

Phase 4: 확장 (2-3주)
├── Bayesian A/B Testing
├── Multi-Armed Bandit
├── 인과추론: DiD, IV, RDD
└── 플랫폼 설계

10 역학-통계-IT 용어 매핑

A/B 테스트는 multi-disciplinary 영역이다. 같은 개념이 분야마다 다른 이름으로 불린다:

개념 역학 (Epidemiology) 통계학 (Statistics) IT/비즈니스
실험 대상 Subject/Participant Observation/Unit User/Visitor
처치 Treatment/Exposure Treatment Variant/Feature Flag
대조 Control/Placebo Control Baseline/Default
결과 변수 Outcome/Endpoint Response Variable Metric/KPI
무작위 배정 Randomization Random Assignment Bucketing/Hashing
처치 효과 Treatment Effect Parameter of Interest Lift/Uplift
교란 변수 Confounder Lurking Variable Confound/Bias
배정 분석 Intention-to-Treat (ITT) - Intent-to-Treat
처치 순응 분석 Per-Protocol - As-Treated
외적 타당성 External Validity Generalizability Generalizability
효과 수정 Effect Modification Interaction HTE (Heterogeneous TE)

11 관련 주제

카테고리 내 기존 포스트

시리즈 내 후속 포스트 (예정)

다른 카테고리 연결 (Multi-disciplinary)

참고 문헌

  • Kohavi, R., Tang, D. & Xu, Y. (2020). Trustworthy Online Controlled Experiments. Cambridge University Press.
  • Imbens, G.W. & Rubin, D.B. (2015). Causal Inference for Statistics, Social, and Biomedical Sciences. Cambridge University Press.
  • Lattimore, T. & Szepesvari, C. (2020). Bandit Algorithms. Cambridge University Press.
  • Hernan, M.A. & Robins, J.M. (2020). Causal Inference: What If. Chapman & Hall/CRC.
  • Deng, A. et al. (2013). “Improving the Sensitivity of Online Controlled Experiments by Utilizing Pre-Experiment Data” (CUPED). WSDM.

Subscribe

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