Tae Hyun Kim (Lowell)

A/B Testing

2분 읽기 #experiments#rct#ab-testing

정의

A/B 테스트는 무작위 대조 실험(RCT)을 온라인에 적용한 것으로, 둘 이상의 변형(variant)을 사용자에게 무작위로 노출해 인과 효과를 추정하는 방법이다.

  • Control (A): 기존 버전
  • Treatment (B): 새로운 버전

ATE=E[Y(1)Y(0)]=YˉBYˉAATE = E[Y(1) - Y(0)] = \bar{Y}_B - \bar{Y}_A

무작위 배정 덕분에 단순 평균 차이가 인과 효과의 불편 추정량이 된다.

직관적 이해

A/B 테스트는 “인과 관계를 밝히는 황금 표준”이다.

관측 데이터에서는 가격과 수요의 상관관계가 교란변수(confounder) 탓에 왜곡될 수 있다. 반면 무작위 실험에서는 처치와 모든 교란변수 사이의 상관관계가 사라진다.

핵심 성질

실험을 택하는 이유

접근법가정위험
관측 연구무교란성(unconfoundedness), 배제 제한가정 위반 시 편향
A/B 테스트SUTVA만 필요윤리·비용 제약

가격 실험의 특수성

도전 과제설명완화 전략
윤리적 우려같은 제품에 다른 가격을 매기면 불공정하다지역·시간 기반 실험
간섭(interference)고객끼리 정보를 공유한다클러스터 무작위화
장기 효과브랜드·충성도에 미치는 효과장기 추적
표본 오염한 사용자의 여러 기기·계정결정론적 할당

결정론적 무작위 할당

def randomize(user_id, experiment_name, treatment_prob=0.5):
    """해시 기반 결정론적 할당"""
    hash_value = hash(f"{user_id}_{experiment_name}") % 100
    return 'treatment' if hash_value < treatment_prob * 100 else 'control'

같은 사용자는 항상 같은 그룹에 배정되므로 일관된 경험을 받는다.

예시

가격 A/B 테스트

class PricingExperiment:
    def __init__(self, control_price, treatment_price):
        self.control_price = control_price
        self.treatment_price = treatment_price
        self.results = {'control': [], 'treatment': []}

    def get_price(self, user_id):
        group = self.randomize(user_id)
        return self.treatment_price if group == 'treatment' else self.control_price

    def analyze(self):
        from scipy import stats
        control = np.array(self.results['control'])
        treatment = np.array(self.results['treatment'])

        t_stat, p_value = stats.ttest_ind(treatment, control)
        effect = treatment.mean() - control.mean()

        return {'effect': effect, 'p_value': p_value}

결과 분석

  • 전환율(CVR) 차이: τ^=YˉBYˉA\hat{\tau} = \bar{Y}_B - \bar{Y}_A
  • 통계적 유의성: p-value < 0.05
  • 실용적 유의성: 효과 크기(effect size)가 비즈니스 관점에서 의미가 있는가?

관련 개념

참고 문헌

  • Kohavi, R., Tang, D., & Xu, Y. (2020). Trustworthy Online Controlled Experiments.
  • Comprehensive Personalized Pricing Guide, Part V, §13

연결 그래프