A/B 테스트
중급고급
학습 목표
- A/B 테스트 설계
- 표본 크기 산정
- 전환율/평균 비교 검정
- 결과 해석
0. 사전 준비 (Setup)
데이터 실습을 위해 CSV 파일을 로드합니다.
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from scipy import stats
# Load Data
orders = pd.read_csv('src_orders.csv', parse_dates=['created_at'])
items = pd.read_csv('src_order_items.csv')
products = pd.read_csv('src_products.csv')
users = pd.read_csv('src_users.csv')
# Merge for Analysis
df = orders.merge(items, on='order_id').merge(products, on='product_id').merge(users, on='user_id')
# Simulate AB Test Data for Examples
np.random.seed(42)
df['experiment_group'] = np.random.choice(['control', 'treatment'], size=len(df))
# Add slight effect to treatment
df.loc[df['experiment_group'] == 'treatment', 'sale_price'] *= 1.05
df['order_amount'] = df['sale_price'] # Alias for example1. A/B 테스트란?
정의
A/B 테스트는 두 가지 버전(A: 대조군, B: 실험군)을 비교하여 어느 것이 더 효과적인지 검증하는 실험입니다.
활용 예시
- 웹사이트 버튼 색상
- 이메일 제목
- 가격 정책
- 추천 알고리즘
2. 표본 크기 산정
검정력 분석
실험 전에 필요한 표본 크기를 계산합니다.
from statsmodels.stats.power import TTestIndPower
# 파라미터
effect_size = 0.2 # 효과 크기 (작음: 0.2, 중간: 0.5, 큼: 0.8)
alpha = 0.05 # 유의수준
power = 0.8 # 검정력
# 표본 크기 계산
analysis = TTestIndPower()
sample_size = analysis.solve_power(
effect_size=effect_size,
power=power,
alpha=alpha,
alternative='two-sided'
)
print(f"필요 표본 크기 (그룹당): {int(sample_size)}")
print(f"총 필요 표본: {int(sample_size * 2)}")실행 결과
필요 표본 크기 (그룹당): 393 총 필요 표본: 786
3. 전환율 비교 (비율 검정)
Z-검정
from statsmodels.stats.proportion import proportions_ztest
# 데이터
# A그룹: 1000명 중 50명 전환
# B그룹: 1000명 중 65명 전환
conversions = [50, 65]
n_observations = [1000, 1000]
# Z-검정
z_stat, p_value = proportions_ztest(conversions, n_observations, alternative='two-sided')
# 전환율
rate_a = conversions[0] / n_observations[0]
rate_b = conversions[1] / n_observations[1]
lift = (rate_b - rate_a) / rate_a * 100
print(f"A그룹 전환율: {rate_a:.2%}")
print(f"B그룹 전환율: {rate_b:.2%}")
print(f"상대적 증가: {lift:.1f}%")
print(f"p-value: {p_value:.4f}")
if p_value < 0.05:
print("→ B그룹이 유의미하게 더 좋음!")
else:
print("→ 유의미한 차이 없음")실행 결과
A그룹 전환율: 5.00% B그룹 전환율: 6.50% 상대적 증가: 30.0% p-value: 0.1496 → 유의미한 차이 없음
4. 평균 비교 (t-검정)
주문 금액 비교
from scipy import stats
# 그룹별 데이터
group_a = df[df['experiment_group'] == 'control']['order_amount']
group_b = df[df['experiment_group'] == 'treatment']['order_amount']
# t-검정
t_stat, p_value = stats.ttest_ind(group_a, group_b)
print(f"A그룹 평균: ${group_a.mean():.2f}")
print(f"B그룹 평균: ${group_b.mean():.2f}")
print(f"차이: ${group_b.mean() - group_a.mean():.2f}")
print(f"p-value: {p_value:.4f}")
# 효과 크기 (Cohen's d)
pooled_std = np.sqrt((group_a.std()**2 + group_b.std()**2) / 2)
cohens_d = (group_b.mean() - group_a.mean()) / pooled_std
print(f"Cohen's d: {cohens_d:.3f}")실행 결과
A그룹 평균: $59.49 B그룹 평균: $62.97 차이: $3.48 p-value: 0.0000 Cohen's d: 0.050
5. 결과 해석
의사결정 프레임워크
1. p < 0.05 인가?
- No → 유의미한 차이 없음, 추가 실험 필요
- Yes → 다음 단계로
2. 효과 크기가 실무적으로 의미있는가?
- 전환율 0.1% 증가 vs 10% 증가
- 비즈니스 임팩트 계산
3. 비용 대비 효과가 있는가?
- 구현 비용
- 예상 수익 증가주의사항
⚠️
A/B 테스트 주의사항
- 피킹(Peeking): 실험 도중 결과 확인 후 조기 종료 금지
- 다중 비교: 여러 지표 동시 검정 시 보정 필요 (Bonferroni)
- 노출 편향: 그룹 간 특성 불균형 확인
- 외부 요인: 시즌, 프로모션 등 영향 고려
퀴즈
문제
A/B 테스트 결과가 다음과 같을 때, 새 디자인(B)을 적용해야 할까요?
- A그룹: 5000명, 전환 150명
- B그룹: 5000명, 전환 175명
정답 보기
from statsmodels.stats.proportion import proportions_ztest
conversions = [150, 175]
n = [5000, 5000]
z_stat, p_value = proportions_ztest(conversions, n)
rate_a = 150/5000
rate_b = 175/5000
lift = (rate_b - rate_a) / rate_a * 100
print(f"A 전환율: {rate_a:.2%}")
print(f"B 전환율: {rate_b:.2%}")
print(f"상대적 증가: {lift:.1f}%")
print(f"p-value: {p_value:.4f}")
if p_value < 0.05:
print("\n결론: B를 적용하세요!")
print(f"- 전환율 {lift:.1f}% 증가")
print(f"- 통계적으로 유의미함")
else:
print("\n결론: 추가 실험이 필요합니다")실행 결과
A 전환율: 3.00% B 전환율: 3.50% 상대적 증가: 16.7% p-value: 0.1586 결론: 추가 실험이 필요합니다
정리
A/B 테스트 체크리스트
- 가설 명확히 설정
- 필요 표본 크기 계산
- 무작위 배정 확인
- 충분한 기간 실험
- 적절한 통계 검정 선택
- 효과 크기와 비즈니스 임팩트 함께 고려
다음 단계
통계분석 섹션을 완료했습니다! ML 기초 섹션에서 머신러닝 기법을 배워보세요.
Last updated on