In [1]:
from __future__ import division
import math
from probability import *
def normal_approximation_to_binomial(n, p):
mu = p*n
sigma = math.sqrt(p * (1-p) * n)
return mu, sigma
In [2]:
normal_approximation_to_binomial(5000, 0.5)
Out[2]:
In [3]:
normal_prob_below = normal_cdf
def normal_prob_above(lo, mu = 0, sigma = 1):
return 1 - normal_cdf(lo, mu, sigma)
def normal_prob_between(lo, hi, mu = 0, sigma = 1):
return normal_cdf(hi, mu, sigma) - normal_cdf(lo, mu, sigma)
def normal_prob_outside(lo, hi, mu = 0, sigma = 1):
1 - normal_prob_between(lo, hi, mu, sigma)
In [4]:
def normal_upper_bound(p, mu = 0, sigma = 1):
return inverse_normal_cdf(p, mu, sigma)
def normal_lower_bound(p, mu = 0, sigma = 1):
return inverse_normal_cdf(1 - p, mu, sigma)
def normal_two_sided_bounds(p, mu = 0, sigma = 1):
tail_prob = (1 - p) / 2
upper_bound = normal_lower_bound(tail_prob, mu, sigma)
lower_bound = normal_upper_bound(tail_prob, mu, sigma)
return lower_bound, upper_bound
In [5]:
mu_0, sigma_0 = normal_approximation_to_binomial(1000, 0.5)
In [6]:
# H_0 range
normal_two_sided_bounds(0.95, mu_0, sigma_0)
Out[6]:
In [7]:
#power
lo, hi = normal_two_sided_bounds(0.95, mu_0, sigma_0)
mu_1, sigma_1 = normal_approximation_to_binomial(1000, 0.55)
type_2_prob = normal_prob_between(lo, hi, mu_1, sigma_1)
power = 1 - type_2_prob
In [8]:
power
Out[8]:
In [9]:
def two_sided_p_value(x, mu = 0, sigma = 1):
if x >= mu:
return 2 * normal_prob_above(x, mu, sigma)
else:
return 2 * normal_prob_below(x, mu, sigma)
In [10]:
two_sided_p_value(529.5, mu_0, sigma_0)
Out[10]:
In [11]:
extreme_value_count = 0
for _ in xrange(100000):
num_heads = sum(1 if random.random() < 0.5 else 0
for _ in xrange(1000))
if num_heads >= 530 or num_heads <= 470:
extreme_value_count += 1
print extreme_value_count / 100000
In [12]:
two_sided_p_value(531.5, mu_0, sigma_0)
Out[12]:
In [13]:
def run_experiment():
return [random.random() < 0.5 for _ in xrange(1000)]
def reject_fairness(experiment):
num_heads = len([flip for flip in experiment if flip])
return num_heads < 469 or num_heads > 531
In [14]:
random.seed(0)
experiments = [run_experiment() for _ in xrange(1000)]
num_rejections = len([experiment
for experiment in experiments
if reject_fairness(experiment)])
print num_rejections
In [15]:
def estimated_parameters(N, n):
p = n / N
sigma = math.sqrt(p * (1-p) / N)
return p, sigma
def a_b_test_statistic(N_A, n_A, N_B, n_B):
p_A, sigma_A = estimated_parameters(N_A, n_A)
p_B, sigma_B = estimated_parameters(N_B, n_B)
return (p_B - p_A) / math.sqrt(sigma_A**2 + sigma_B**2)
In [19]:
z = a_b_test_statistic(1000,200,1000,150)
In [20]:
two_sided_p_value(z)
Out[20]:
In [22]:
def B(alpha, beta):
return math.gamma(alpha) * math.gamma(beta) / math.gamma(alpha + beta)
def beta_pdf(x, alpha, beta):
if x < 0 or x > 1:
return 0
return x**(alpha - 1) * (1 - x)**(beta -1) / B(alpha, beta)
In [ ]: