Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
probml
GitHub Repository: probml/pyprobml
Path: blob/master/deprecated/scripts/ab_test_demo.py
1192 views
1
# Example 5.1 from "Test and roll: profit maximizing A/B tests"
2
# https://pubsonline.informs.org/doi/abs/10.1287/mksc.2019.1194
3
4
5
#import superimport
6
7
import numpy as np
8
import matplotlib.pyplot as plt
9
import pyprobml_utils as pml
10
11
def optimal_sample_size(N, s, sigma):
12
# eqn 10
13
t = (s/sigma)**2
14
n = np.sqrt(0.25*N*t + (0.75*t)**2) - 0.75*t
15
return n
16
17
def prob_error(n1, n2, s, sigma):
18
# eqn 12
19
x = np.sqrt(2)*sigma/s * np.sqrt(n1*n2/(n1 +n2 +1e-10))
20
p = 0.25 - 1/(2*np.pi)*np.arctan(x)
21
return 2*p # could have m1<m2 or m1>m2
22
23
def eprofit_deploy(N, n1, n2, s, mu, sigma):
24
# eqn 9
25
numer = np.sqrt(2)*sigma**2
26
tmp = 2*sigma**2 + (n1+n2) / (n1*n2 + 1e-10) * (s**2)
27
denom = np.sqrt(np.pi)*np.sqrt(tmp)
28
return (N-n1-n2)*(mu + numer/denom)
29
30
def eprofit_test(N, n1, n2, s, mu, sigma):
31
# eqn 7
32
return (n1+n2)*mu
33
34
def eprofit_total(N, n1, n2, s, mu, sigma):
35
p1 = eprofit_test(N, n1, n2, s, mu, sigma)
36
p2 = eprofit_deploy(N, n1, n2, s, mu, sigma)
37
return p1+p2
38
39
40
mu = 0.68
41
sigma = 0.03
42
N = 100000
43
s = np.sqrt(mu*(1-mu))
44
nopt = optimal_sample_size(N, s, sigma)
45
print(nopt) # 2283.9
46
47
n1 = nopt
48
n2 = nopt
49
p = prob_error(n1, n2, s, sigma)
50
print(p) # 0.10
51
52
53
print(eprofit_test(N, n1, n2, s, mu, sigma)) # 3106
54
print(eprofit_deploy(N, n1, n2, s, mu, sigma)) # 66429.9
55
eprofit_opt = eprofit_total(N, n1, n2, s, mu, sigma)
56
error_rate_opt = prob_error(n1, n2, s, sigma)
57
58
ns = np.linspace(0, 50000, 1000)
59
K = len(ns)
60
eprofit = np.zeros(K)
61
error_rate = np.zeros(K)
62
for k, n in enumerate(ns):
63
n1 = n; n2 = n
64
eprofit[k] = eprofit_total(N, n1, n2, s, mu, sigma)
65
error_rate[k] = prob_error(n1, n2, s, sigma)
66
67
plt.figure();
68
plt.plot(ns, eprofit)
69
plt.xlabel('Test size')
70
plt.ylabel('Expected #conversions')
71
plt.axvline(nopt)
72
plt.axhline(eprofit_opt)
73
plt.text(nopt, eprofit_opt, 'n*={:0.1f}'.format(nopt))
74
pml.savefig('ab_profit.pdf')
75
pml.savefig('ab_profit.png')
76
plt.show()
77
78
plt.figure();
79
plt.plot(ns, error_rate)
80
plt.xlabel('Test size')
81
plt.ylabel('Expected error rate')
82
plt.axvline(nopt)
83
plt.axhline(error_rate_opt)
84
plt.text(nopt, error_rate_opt, 'n*={:0.1f}'.format(nopt))
85
pml.savefig('ab_error.pdf')
86
pml.savefig('ab_error.png')
87
plt.show()
88