[DA] 파이썬 A/B 테스트 실습
디자인 시안 A, B에 따른 유저의 체류 시간, 전환율 차이 A/B 테스트
참고 | https://data101.oopy.io/ab-test-python-or-without-code
예제 1. 디자인 시안 A, B에 따른 유저의 체류시간 테스트
design_A | design_B |
---|---|
16.4 | 12.1 |
12.6 | 11.8 |
17.5 | 14.7 |
18.8 | 13.1 |
12.1 | 13.8 |
13.2 | 10.1 |
14.5 | 9.1 |
12.4 | 13.5 |
17.5 | 11.2 |
25.4 | 13.7 |
9.3 | .. |
10.4 | .. |
평균:15.00초 | 평균:12.31초 |
- A,B 모집 데이터 개수 달라도 됨
디자인 A의 평균 체류 시간이 더 길다고해서 A 디자인이 더 좋은 것이 아니다.
디자인 A의 시간이 더 긴 것은 우연의 결과가 아니었을까? 하며 검정해보는 것이 옳다.
파이썬을 이용한 검정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from scipy import stats
# 데이터
design_A = [16.4, 12.6, 17.5, 18.8, 12.1, 13.2, 14.5, 12.4, 17.5, 25.4, 9.3, 10.4]
design_B = [12.1, 11.8, 14.7, 13.1, 13.8, 10.1, 9.1, 13.5, 11.2, 13.7]
# 검정 코드
stats.ttest_ind(design_A,
design_B,
equal_var=False)
# output
>>> TtestResult(statistic=1.933374622222914, pvalue=0.07227304704557012, df=15.013970219253618)
pvalue
는 “평균 차이는 사실 없었다” 라는 결론이 나올 확률로, 전통적인 통계학에서는 0.05를 기준으로 그보다 낮으면 그 결론을 기각할 만 하다고 본다.
이를 “이 평균 차이는 통계적으로 유의하다”고 표현할 수 있다.
-> pvalue
가 0.05 보다 높으면 디자인 A가 더 낫다고 말할 수 없다.
“평균 차이는 사실 없었다 (D = 0)” 를 가설로 설정하고, 그것을 검정한다. 검정 방법론은 “독립 t 검정 (t - test)”라고 불린다. 클래스 이름이 ttest_ind()인 것인 이유이다. (t test, independent)
위 A/B테스트의 pvalue
는 약 0.07로 0.05보다 높기 때문에, 디자인 A와 B의 체류시간 차이는 우연적인 결과로 나온 것이며, 통계적으로 유의미하다고 볼 수 없다.
A/B 테스트의 표면적 결과는 A의 체류시간이 평균 2.7초 정도 높게 나왔지만, A 디자인이 더 좋아 반영할만 하다고는 볼 수 없는 것이다.
만약 데이터가 DataFrame 형식이고, null 값이 있다면
결측값을 채워야한다.
예제 2. 디자인 시안 A, B에 따른 유저의 전환율(클릭) 차이 테스트
user_id | design_A | design_B |
---|---|---|
1 | 1 | |
2 | 0 | |
3 | 0 | |
4 | 0 | |
5 | 1 | |
6 | 0 | |
7 | 0 | |
8 | 1 | |
9 | 0 | |
10 | 0 | |
11 | 1 | |
12 | 0 | |
13 | 1 | |
… | … | … |
전환율: | 13/244 (5.32%) | 23/287(8.01%) |
- A,B 모집 데이터 개수 달라도 됨
- 클릭 = 1, 클릭 안 함 = 0
예제 1과 마찬가지로, 디자인 B의 클릭 전환율이 더 높다고 해서 B 디자인이 더 좋은 것이 아니라 B의 클릭 전환이 더 잘 된 것은 우연의 결과가 아니었는지 검정해보는 것이 옳은 것이다.
파이썬을 이용한 검정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pandas as pd
from scipy.stats import chi2_contingency # 카이제곱
def click_abtest(a_click, total_a, b_click, total_b):
click = [a_click, b_click] # A와 B의 클릭한 유저 수
no_click = [total_a - a_click, total_b - b_click] # A와 B의 클릭 안 한 유저 수
cont_table = pd.DataFrame([click, no_click], columns=['A', 'B'], index=['click', 'no_click'])
chi2, p_val, d_f, expected = chi2_contingency([click, no_click])
print("카이제곱 통계량 :", format(chi2, '.5f'))
print("pvalue :", format(p_val, '.5f'))
# A의 클릭수(13)와 A의 데이터 전체 개수(244)
# B의 클릭수(23)와 A의 데이터 전체 개수(287)를 정의한 클래스에 넣어줌
click_abtest(13, 244, 23, 287)
# output
>>> 카이제곱 통계량 : 1.11053
>>> pvalue : 0.29197
pvalue
가 0.05보다 높다면 디자인 B가 더 낫다고 말할 수 없다.
특정 값으로 평균 내기 어려운 데이터를 nominal하다 혹은 명목범주의 데이터라고 한다.
이 때 사용되는 방법을 카이제곱검정이라고 한다.
- AB테스트 설계 시, 비교를 위한 데이터를 어느 정도 모아야 하는지 알기 위해서는 효과크기와 검정력 개념을 알아야함.
Leave a comment