Statistics

[STAT 101] 베이지안 AB Test의 전환율 검정과 기대수익 분석

thebuck104 2024. 8. 13. 12:27

베이지안 확률 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