베이지안 확률 Bayesian Probability
동전을 여러번 던졌을 때 앞면이 나올 확률 처럼 시행 횟수를 여러번 할 수 있는 빈도 확률 (Frequentist Probability)와는 다르게, 예를 들어 화산 폭발의 확률 처럼 세상에는 빈도수를 늘릴 수 없는 일이 많다.
일어나지 않ㄴ은 일에 대한 확률을 불확실성 (Uncertainty)의 개념, 즉 사건과 관련된 여러 확률을 도합적으로 이용해 새롭게 일어날 사건을 추정하는 것이 베이지안 확률이다.
P(A) 사전 확률 Prior Probability: 결과가 나타나기 전에 결정되어 있는 A(원인)의 확률
P(B|A) 우도 확률 Likelihood Probability: A(원인)가 발생했다는 조건 하에 B가 발생할 확률
P(A|B) 사후 확률 Posterior Probability: B(결과)가 발생했다는 조건 하에 A가 발생했을 확률
# 머신러닝에서의 베이지안 확률은
데이터 셋이 주어졌을 때 특정 사건 혹은 가설의 확률을 높여줄 수 있는 최적의 모델을 찾는 것을 목적으로 한다.
즉, 주어징 정보를 베이지안 확률로 계속해서 업데이트 해가면서, 최적의 사후확률을 계산하는 것이다.
AB Test
A와 B의 대안이 있을 때, 어떤 대안이 더 효과적인지 확인하기 위해
전체 표본을 대조군 (Control Group)과 실험군 (Experimental Group)으로 나눠 그 효과를 비교하는 방법론이다.
A와 B에 따라 관심 있는 지표가 어떻게 바뀌는지를 알아보는 실험으로,
클릭율 (CTR) 이나 구매 혹은 다음 페이지로의 전환율 (Conversion Rate) 등이 주요 지표로 사용된다.
그렇다면 B가 A보다 더 얼마나 나은 지표를 가지고 있어야 하는가?
이를 AB Test를 통해 알아볼 수 있다.
이를 위해 AB Test는 다음과 같은 절차로 이루어진다.
1. 사용자 및 지표 선정
2. 실제 환경 선정
3. 사용자 무작위 선정
4. 사용자에게 무작위로 A와 B 노출
5. 결과 분석 및 검증
Bayesian AB Test
01) 전환율 검정 Conversion Testing
웹사이트 방문자에게 A와 B를 보여주고, 어느 디자인에 더 현혹되어 구매버튼을 누르게 되는지를 보는 것.
이 때의 가설은
"A보다 B가 구매로의 전환율이 높을 것이다"
가 된다.
가능도 Likelihood
가능도는 관측하는 데이터의 함수를 의미한다.
위의 경우에는 가능도로는 이항 분포 (Binomial Distribution)을 선택할 수 있다.
우리가 찾고자 하는 것이
"n명의 사람 중 구매 버튼 클릭에 성공한 사람 수"
를 의미 하기 때문에, 이항 분포를 따른다 가정할 수 있는 것이다.
n명의 사람 중 성공한 사람의 수를 X라고 하고, 그 성공 확률이 p라고 한다면 이항 분포는 다음과 같이 정의될 수 있다.
사전 분포 Prior
베이지안은 모수에 사전분포를 가정해서, 모수는 실제값이 하나가 아니라
"사람들의 믿음이나 신념에 따라 달라지는 분포 형태를 띠고 있다"고 가정한다.
위의 경우에 사전분포는 베타분포 (Beta Distribution)으로 가정할 수 있으며,
0과 1 의 사이값을 가지는 베타 분포는 성공 확률 분포의 자연스러운 가정이 될 수 있으며,
다음과 가티 정의될 수 있다.
베타 함수는 알파와 베타에 따라 "어느 값에 밀집되어 있을 것이다."가 달라지기 때문에
전환율을 안다면 베타 함수에 어떤 알파값과 어떤 베타값을 쓸 지 사전지식을 부여할 수 있다.
예컨대, 전환율이 0.12 부근이라는 배경 지식이 있다면,
해당 그림의 주황색 그래프인 Beta(2, 8)를 사전분포로 사용할 수 있다.
무정보 사전 분포 Non-informative Prior
하지만
1. 전환율에 대한 사전지식이 없을 때
2. 데이터만으로 모수를 추정하고 싶을 때
즉, 특별한 사전 지식이 없다면 무정보 사전 분포 (Non-informative Prior)를 주는 것이 일반적이다.
베타 분포의 무정보 사전분포는 a = 1, b = 1에 해당하고,
위 그림에서 보이듯, 균등 분포인 Uniform(0, 1)과 동일하다.
즉 이는 다시 말해
"전환율이 0과 1 사이 어딘가에 랜덤하게 있을 것이다."
를 뜻하기도 한다.
사후 분포 Posterior Distribution
AB Test에 있어 사전 분포는 베타 분포, 가능도는 이항 분포로 둔다면
사후 분포를 구했을 때 그 형태가 사전분포와 같은 분포, 즉 켤래성 (Conjugacy)를 띄게 된다.
사후 분포는 조건부 정리를 통해 구할 수 있는데,
이는 결국 사후 분포가 " 가능도 X 사전분포 " 에 비례함을 알려준다.
따라서 가능도가 이항분포고, 사전분포가 베타 분포일 경우,
사후 분포는 Beta(α+x, β+n-x) 를 따르게 된다.
여기서 x는 성공횟수, n-x는 실패 횟수를 뜻한다.
A 디자인을 본 방문자가 1300명, 그 중 120명이 구매를 했고,
B 디자인을 본 방문자는 1270명, 그중 125명이 구매를 했다면
Beta(1, 1)의 무정보 사전 분포를 따른다 가정했을 때,
A 디자인에 따른 전환율의 사후 분포는 Beta(1+120, 1+1300-120) = Beta(121, 1181)이 되고,
B 디자인에 따른 전환율의 사후 분포는 Beta(1+125, 1+1275-125) = Beta(126, 1151)이 된다.
이를 파이썬으로 활용하면
from IPython.core.pylabtools import figsize
from matplotlib import pyplot as plt
from scipy import stats as st
import numpy as np
visit_A = 1300
visit_B = 1275
conversion_A = 120
conversion_B = 125
alpha = 1
beta = 1
n_samples = 1000
print(alpha)
posterior_A = st.beta(alpha+conversion_A,beta+visit_A-conversion_A)
posterior_B = st.beta(alpha+conversion_B,beta+visit_B-conversion_B)
posterior_samples_A = st.beta(alpha+conversion_A,beta+visit_A-conversion_A).rvs(n_samples)
posterior_samples_B = st.beta(alpha+conversion_B,beta+visit_B-conversion_B).rvs(n_samples)
# posterior mean
print((posterior_samples_A > posterior_samples_B).mean())
[Output] 0.31355
결과값을 확인하면,
A 디자인의 전환율이 B 디자인의 전환율보다 높을 확률이 31.36% 정도라는 것을 알 수 있다.
즉, B 디자인의 전환율이 A 디자인의 전환율보다 높을 확률이 68.64%인 것이다.
이를 파이썬을 통해 그림으로 그리면 다음과 같다.
# Posterior Dist of A and B
fig,axes = plt.subplots(1,2,figsize=(10,4))
x = np.linspace(0,1,1000)
i=0
for ax in axes:
ax.plot(x, posterior_A.pdf(x), label = "posterior of A: Beta(121,1181)")
ax.plot(x, posterior_B.pdf(x), label = "posterior of B: Beta(126,1151)")
ax.set_xlabel("Value")
ax.set_ylabel("Density")
if i==1:
ax.set_xlim(0.05, 0.15)
i+=1
axes[0].legend()
Bayesian AB Test
02) 기대 수익 분석 Expected Revenue Analysis
기대 수익 분석을 베이지안 관점에서 본다면 다음과 같은 수식을 떠올릴 수 있다.
P들은 각각의 플랜을 선택할 확률이고, P4는 아무 플랜도 선택하지 않을 확률이다.
이 확률들은 모두 더하면 1이 된다.
이 때의 가능도 함수와 사전분포는, 위에서 본 이항 분포와 베타 분포의 확장판인
다항 분포 (Multinomial Distribution)과 디리클레 분포 (Dirichlet Distribution)이 된다.
가능도: 다항 분포
n명의 사람이 각각의 플랜 중 하나를 선택할 때,
플랜 별 사람 수를 x1, x2, x3이라 하고, 선택하지 않은 사람의 수를 x4라 하면
가능도는 다항분포를 따르고, 다음과 같이 정의될 수 있다.
사전 분포: 디리클레 분포
디리클레 분포는 베타 분포의 확장판으로, 다음과 같이 모수 α1, α2, α3, α4 를 가진다.
베타 분포와 마찬가지로, Dirichlet(1,1,1,1)도 무정보 사전분포에 해당한다.
사후 분포: 디리클레 분포
사전 분포로 Dirichlet(1,1,1,1) 을 따르고, 가능도로 (x1, x2, x3, x4)의 다항 분포를 따른다 할 때,
사후 분포는 켤래성으로 인해 다시 디리클레 분포 Dirichlet(1+x1, 1+x2,1+x3,1+x4) 를 따른다.
디자인 | 총 사람 수 | 79 선택 | 49 선택 | 25 선택 | 선택 없음 |
A | 1000 | 10 | 49 | 80 | 864 |
B | 2000 | 45 | 84 | 200 | 1671 |
합계 | 3000 | 55 | 133 | 280 | 2535 |
이 때, 두 디자인의 확률 분포는 모두 Dirichlet(1,1,1,1)로 가정한다.
A는 방문자수 Na = 1000, 각 플랜 선택자 수 X1a = 10, X2a = 49, X3a = 80, X4a = 864 가 되고,
B는 방문자수 Nb = 2000, 각 플랜 선택자 수 X1b = 45, X2b = 84, X3b = 200, X4b = 1671 가 된다.
켤레성에 따라 사후 분포역시 디리클레 분포를 따르게 되며, 이때
- A 디자인: Dirichlet(1+x1A,1+x2A,1+x3A,1+x4A) = Dirichlet(11,50,81,865)
- B 디자인: (1+x1B,1+x2B,1+x3B,1+x4B) = Dirichlet(45,84,200,1671)
를 따르게 된다.
위와 같이 사전, 가능도, 사후 분포를 가정하고
테이블과 같은 데이터가 주어졌다고 했을 때, 이를 파이썬을 활용하면 다음과 같다.
import scipy.stats as st
import numpy as np
n_A = 1000
x1_A= 10
x2_A= 46
x3_A= 80
x4_A=n_A-x1_A-x2_A-x3_A
n_B = 2000
x1_B= 45
x2_B= 84
x3_B= 200
x4_B=n_B-x1_B-x2_B-x3_B
alpha_A=np.array([1+x1_A,1+x2_A,1+x3_A,1+x4_A])
alpha_B=np.array([1+x1_B,1+x2_B,1+x3_B,1+x4_B])
p_A = st.dirichlet(alpha_A).rvs(n_samples)
p_B = st.dirichlet(alpha_B).rvs(n_samples)
# 기대 수익 함수
ER_A=expected_revenue(p_A)
ER_B=expected_revenue(p_B)
print((ER_B>ER_A).mean())
[Output] 0.981
이 때 p_A와 p_B는 사후 분포의 랜덤 샘플이 된다.
이 사후 분포의 랜덤 샘플과 기대수익 함수를 통해
기대 수익을 구하고, 두 그룹 간의 기대수익 차이를 알아볼 수 있다.
위와 같이 B 디자인의 기대 수익이 A 디자인의 기대수익보다 높을 확률이 98.1%로 매우 높게 나왔다.
이를 아래 처럼 시각화 할 수 있다.
from matplotlib import pyplot as plt
plt.hist(ER_A,label="E[R] of A",bins=50,histtype="stepfilled",alpha=.8)
plt.hist(ER_B,label="E[R] of B",bins=50,histtype="stepfilled",alpha=.8)
plt.xlabel("Value"); plt.ylabel("Density")
plt.legend(loc="best")
기대 수익이 얼마나 더 높은지에 대한 시각화는 다음과 같이
기대수익들의 차의 사후분포를 보는 것으로 진행할 수 있다.
plt.hist(ER_B-ER_A,histtype="stepfilled",color="red",alpha=0.5,bins=50)
plt.vlines(0,0,70,linestyle='solid')
plt.xlabel("Value")
plt.ylabel("Density")
plt.ylim(0,70)
plt.title("Posterior Distribution of Difference of E[$R_B$]-E[$R_A$]")
print((ER_B-ER_A).mean().round(3)) #1.168
본 페이지는 다음 블로그를 참고해 작성되었습니다.
https://playinpap.github.io/bayesian-abtest/
베이지안 A/B 테스트 in Python
베이지안 관점에서 AB Test를 하는 방법에 대해 정리했습니다. 전체 코드는 여기 에서 확인할 수 …
playinpap.github.io
'Statistics' 카테고리의 다른 글
[STAT 101] ANOVA 검정과 다중 검정의 문제 (0) | 2024.08.13 |
---|---|
[STAT 101] T 검정과 BEST검정 (0) | 2024.08.13 |
[STAT 101] 베르누이 분포와 이항 분포, 그리고 포아송 분포 (0) | 2024.08.12 |
[STAT 101] 정규분포(Normal Distribution)와 t분포(Student's t-distribution) (0) | 2024.08.09 |
[STAT 101] 모집단과 표본, 그 속 통계 값들과 표본 추출 방법 (0) | 2024.08.07 |