A/B Test 설계와 결과 검증
해당 포스팅은 A/B Test를 설계할 때 주의점과, A/B Test를 검증하는 방법에 대해 소개합니다.
- A/B Test 설계
- RCT(Randomized control trial)
- 검정력(Power of the test)
- 표본크기 계산
- A/B Test 검증
- 추정값의 표준오차
- 신뢰구간 (confidence interval)
- 가설검정
무작위 배정으로 독립성 확보
- 잠재적 결과가 처치와 독립인 경우에 연관관계와 인과관계가 동일해짐
- 하지만 처치와 결과 사이의 독립성을 의미하는 것이 아님. 처치와 결과가 독립적이면 처치는 결과에 영향을 끼치지 못함.
- 만약 새로운 기능을 처치로 사용시간이 결과라면 새로운 기능과 사용시간이 독립이라면 실험군/대조군 상관없이 새로운기능은 결과에 아무 영향이 없음
- 따라서 잠재적 결과가 처치와 독립적이어야 함.
- 실험군이 처치를 받았다면 결과가 실제로 처치받았는지 여부와 무관하다는 뜻.
- 즉 독립성가정은 실험군과 대조군이 비교 가능함을 의미. 이는 실험군과 대조군의 결과 차이를 유발한 요인이 처치라는 것을 의미.
- 랜덤화 : 무작위로 처치를 하면 실험군과 대조군의 기대값은 거의 비교가능해짐. 두 그룹간의 유일한 차이는 처치밖에 없기 때문.
A/B Test설계 및 시행
- RCT(Randomized control trial)을 의미
EX) 이메일 발송이 프로모션에 효과적인가
문제점 : 이메일을 받은 고객 자체가 다른 고객 보다 더 많이 전환될 수 있음. (편향)
1. 무작위 분배
- 따라서 이메일을 받은 고객과 받지 않은 고객을 비교 가능하도록 하여야 함.
- 이때 필요한게 랜덤화/무작위임.
- 무직위로 보내면 두 그룹의 전환율은 평균적으로 동일해짐
2. 실험군과 대조군이 비슷한 그룹인지 확인
- 실험대상 집단 사이의 정규화 차이(normalized difference) 를 계산(다른 방법도 많음)
- 특성별(gender, age)별로 각 그룹의 차이가 크지 않아야 함. 명확힌 임계값(threshold)는 없지만 경험적으로는 0.5정도가 적절함
- short그룹은 성별차이가 크고, long그룹은 나이차이가 큼
3. 각 그룹의 전환율을 계산해서 인과효과 추정
- long는 대조군보다 1.3%p, short는 대조군보다 8.3% 증가의 효과가 관찰되었음
표준편차에 대한 드무아브르의 공식
SE공식 (SE는 평균의 표준오차, σ는 표준편차, n은 표본크기)
EX) 시험점수와 학교의 학생수와의 관계
- 단순히 데이터만 보면 성적 상위 1%의 학교들은 다른학교에 비해 규모가 작다.
- 하지만 하위 1%역시 확인해야한다. 하위 1%의 학교 역시 학생수가 적었기 때문
- 학생수가 증가함에 따라 점수는 점점 정확해진다.
- 학생수가 적은 학교(표본이 적은 학교)에서는 우연때문에 점수가 매우 높거나 낮을 수 있음. 하지만 규모가 큰 학교는 우연이 작용될 가능성이 적음.
- 즉, 표본이 적으면 불확실성이 높아짐
- 이 불확실성을 정량화 하는 방법은 추정값의 분산을 계산하는것.
CF) 오차의 종류
- 체계적 오차(systematic error) : 모든 측정값에 동일한 방식으로 영향을 끼치는 일관된 편향. 데이터를 더 많이 수집한다고 해서 줄지 않음
- 무작위 오차(random error) : 우연히 생긴 예측 불가능한 변동. 표본 크기가 증가함에 따라 줄어듬. 통계학은 무작위 오차에서 오는 불확실성을 다루기에 통계를 사용하여 불확실성을 보완할 수 있음
추정값의 표준오차
- RCT는 인과관계 식별에 유용하지만 실험표본이 작으면 추론하는 것이 어려워짐.
- 상단 이메일 효과( long는 대조군보다 1.3%p, short는 대조군보다 8.3% 증가의 효과가 관찰)가 우연에 따른 것이 아닌지 확인하여야함
- 즉 통계적으로 유의(statistically significant)한지 확인 필요
- 이를 위해 SE를 추정하여야함. python에서는 sem함수를 사용하면 구할 수 있음
신뢰구간 (confidence interval)
- 신뢰구간 : 모수가 어느 범위 안에 있는지를 확률적으로 보여주는 방법.
- 예를들어 신뢰수준 95%에서 투표자의 35%~45%가 A후보를 지지하고 있다."라고 할 때 100번 test를 했을때 95번은 A후보자의 지지율이 35%~45%사이에 위치한다는 의미
- 실험의 평균값은 실제 이상적인 평균과 항상 일치하지 않음. 하지만 표준오차를 사용해 진행하는 실험의 95%에서 실제 평균을 포함하는 구간을 만들 수 있음
- 현실에서는 동일한 실험을 시뮬레이션하기 어려움. 하지만 여러 실험을 시뮬레이션하는 아이디어를 바탕으로 신뢰구간을 구성할 수 있음
- 위에서 계산한 표준오차에 2를 곱하고 실험평균에서 더하고 빼면 실제 평균에 대한 95%신롸구간을 구성할 수 있음
def ci(y: pd.Series):
return (y.mean() - 2 * y.sem(), y.mean() + 2 *y.sem())
print("95% CI for Short Email:", ci(short_email))
print("95% CI for Long Email:", ci(long_email))
print("95% CI for No Email:", ci(no_email))
- 여기서 세 그룹의 95% 신뢰구간이 겹치는것을 확인할 수 있음.
- 만약 이 구간이 겹치지 않았다면 그룹 간 전환율 차이가 단지 우연이 아닐 가능성이 높다고 할 수 있음
- 즉, 이메일 발송이 전환율에 통계적으로 유의한 영향을 미친다고 할 수 있음
- 하지만 구간이 겹쳤기 때문에 위와 같은 결론을 내리기 어려움. 물론 겹쳤다고 해서 그룹간의 차이가 통계쩍으로 유의하지 않다고 단정할 수는 없음.
- 99%도 구할 수 있음. 표준편차에 정규분초의 질량중 99%를 포함하는 계수를 곱하면 됨.
- python의 scipy 패키지의 ppf함수를 이용하면 됨
from scipy import stats
z = np.abs(stats.norm.ppf((1-.99)/2))
print(z)
ci = (exp_mu - z * exp_se, exp_mu + z * exp_se)
ci
2.5758293035489004
(0.04690870373460816, 0.20309129626539185)
가설검정
- 불확실성을 반영하는 또 다른 방법.
- 두 그룹간의 평균차이가 0(혹은 다른 특정값)과 통계적으로 유의한 차이가 있는지 확인
- 이를 위해 두 독립 정규분포의 합이나 차이 역시 정규분포가 되어야 함.
diff_mu = short_email.mean() - no_email.mean()
diff_se = np.sqrt(no_email.sem()**2 + hort_email.sem()**2)
ci = (diff_mu - 1.96*diff_se, diff_mu + 1.96*diff_se)
print(f"95% CI for the difference (short email - no mail):\n{ci}")
귀무가설 (null hypothesis)
- 신뢰구간을 이용하는 귀무가설에 관한 질문에 답할 수 있음
- 귀무가설(H0)예시 : Short email을 받은 그룹과 이메일을 받지 않은 그룹의 전환율 차이가 없음
- 위 전환율 차이에 대한 95%신뢰구간에는 0이 포함되어 있지 않음
- 귀무가설에 따르면 이 차이는 0이어야 하지만 신뢰구간이 0을 완전히 벗어나 있음
- 즉, 유의수준 a=0.05(95% 신뢰도)하에서 귀무가설을 기갈 할 수 있음
- 귀무가설을 다르게 적용할 수 있음.
- 이메일발송은 비용이 드는 것이기에 1%이상 차이가 나야 효과가 있다고 가정할 수 있음
- 귀무가설(H0) 예시 : Short email을 받은 그룹과 이메일을 받지 않은 그룹의 전환율 차이는 1%이다.
- 이를 검증하려면 평균차이에서 1%를 빼서 신뢰구간을 이동하면 됨.
# shifting the CI
diff_mu_shifted = short_email.mean() -no_email.mean() - 0.01
diff_se = np.sqrt(no_email.sem()**2 +short_email.sem()**2)
ci = (diff_mu_shifted - 1.96*diff_se, diff_mu_shifted+ 1.96*diff_se)
print(f"95% CI 1% difference between (short email - no email):\n{ci}")
- 이 95% 신뢰구간도 0보다 크므로 귀무가설을 기각할 수 있음.
- 하지만 만약 귀무가설이 2%차이다라고 가정하면 이는 기각하지 못함.
검정통계량(test statistic)
- 검정통계량을 사용하여 귀무가설을 기각할 수 있음.
- 값이 클수록 귀무가설을 기각하는 방향으로 설정
- 널리 사용되는 통계량은 t-statistic임. 이 통계량은 신뢰구간을 형성하는 분포를 정규화함으로써 정의
- 위 식의 분자 : 관측한 평균차이와 귀무가설 사이에 대한 차이.
- 분모 : 표준오차로 통계량의 분산이 1이 되도록 정규화
- 귀무가설이 참인 경우 : 분자의 기댓값은 0이되고, 위 t값은 표준정규분포 N(0,1)을 따르게 됨.
- 귀무가설하에서 t값은 0이 중심이기에 1.96보다 높거나 -1.96보다 낮은 값은 매우 드물게 나타남(전체경우의 95%에서 나타나지 않음)
- 따라서 극단적인 t값이 나오면 귀무가설을 기갈할 수 있음. 주로 유의수준 a=0.05하에서 기각함
t_stat = (diff_mu - 0) / diff_se
t_stat
2.2379512318715364
P-value
- p값은 극단적인 값이 관측된 확률을 알 수 있는 값임
- 즉 귀무가설이 참인 경우 극단적인 데이터가 나타날 확률을 의미 (주의. 귀무가설이 참일 확률이 아님)
- 단측 귀무가설 : 차이가 x보다 크다 or 차이가 x보다 작다 중 하나만 확인하는 경우. 표준정규분포에서 검정통계량 전에 해당하는 넓이를 계산
- 양측 귀무가설 : 차이가 x이다. 즉 양 사이드를 모두 확인하는 경우. 단측 귀무가설 넓이의 2를 곱함
print("p-value:", (1 - stats.norm.cdf(t_stat))*2)
P-value: 0.025224235562152142
- 해석 : 차이가 실제로 0이라면 극단적인 검정통계량이 관측될 확률은 단 2.5%다.
- 유의수준 0.05하에서 귀무가설을 기각한다. (가능성이 별로 없는 수치이다)
검정력(Power of the test)
- 귀무가설을 올바르게 기각할 확률을 의미
- 실험에 필요한 표본 크기를 파악하거나 제대로 실행하지 않은 실험에서 문제를 발견할때 활용
- 통계적 유의성과 관련 있음.
- CF) 1종오류와 2종오류
- 1종오류(유의수준 α) : 귀무가설이 참인데도 이를 기각하는 1종오류를 범할 확률
- 특정유의수준 (ex. 5%)를 목표로한다면 분석 과정 중에 추정값을 중심으로 1- α 신뢰구간(95%)를 구성해야함
- 2종오류( β) : 귀무가설이 거짓인데 이를 채택하는 2종 오류를 범할 확률
- 1종오류(유의수준 α) : 귀무가설이 참인데도 이를 기각하는 1종오류를 범할 확률
- 검정력 (1- β) : 귀무가설이 거짓인 경우 이를 올바르게 기각할 확률
- 검정력의 일번적인 기준은 80%
- 즉 귀무가설이 거짓일 때 80%확률로 귀무가설을 기각해야함.
- 즉 유의한 차이(결과)가 전체 실험의 80%에서 나타야아함. -> 95% 신뢰구간의 하한이 0보다 높은 경우가 전체실험의 80%에 달해야함
- 95% 신뢰구간 하한의 분포는 표준오차와 같은 분산을 가지며 평균은 σ - 1.96SE임.
- 따라서 σ - 1.96SE > 0 의 경우가 80%가 되려면(검정력 80%), 차이가 0에서 1.96SE + 0.84SE만큼 떨어저야 함
- 1.96은 95% 신뢰구간을 확보하기위한 값, 0.84는 신뢰구간의 하한이 0을 초과하는 경우가 전체의 80%에 해당하도록 하기 위함.
stats.norm.cdf(0.84)
0.7995458067395503
표본크기 계산
- 귀무가설이 거짓일 때 귀무가설과 관측된 추정값의 차이인 σ을 감지하여야함.
- 만약 8%차이를 감지하고자 하는 실험을 설계한다면 적어도 8%=2.82SE를 감지할 표본 크기를 확보해야함.
- 만약 80%의 검정력과 95%의 신뢰도를 원할 때 표본크기를 결정하고 싶다면 아래 공식을 사용하면 됨.
np.ceil(16 * no_email.std()/0.08**2)
103.0
data.groupby("cross_sell_email").size()
- 표본은 103개 있어야 하며 long, short그룹모드 103개 이상이니 이 실험은 적절하게 진행되었다고 볼 수 있음
해당 포스팅은 [Causal Inference in Python / 실무로 통하는 인과추론]을 참고하여 작성하였습니다
728x90
반응형
'Data Analysis & ML > 인과추론' 카테고리의 다른 글
[인과추론] 그래프 인과모델 (0) | 2025.02.02 |
---|---|
[인과추론] 인과추론의 기본개념 (0) | 2025.01.29 |
[인과추론] A/B Test 설계 시 실험군 간의 누출 및 간섭 (1) | 2024.06.01 |
[인과추론] A/B Test와 지표(목표지표, 동인지표, 가드레일지표, 종합 평가 기준 (OEC)) (1) | 2024.04.21 |
[인과추론] Structural Causal Model(SCMs) (구조적 인과모형) (0) | 2023.12.03 |