We've started to investigate hypothesis testing, p-values and their use for accepting or rejecting the null hypothesis. Building upon this, we can develop a concept of the power of a statistical test, as the test's ability to detect a difference, when one exists. In the case of our coin flipping example, the power of our statistical test would be the probability of rejecting the null hypothesis "this coin is fair" when the coin was unfair. As you might assume, the power of this statistical test would thus depend on several factors including our p-value threshold for rejecting the null hypothesis, the size of our sample and the 'level of unfairness' of the coin in question.
You will be able to:
- Describe the concept of “Power” in relation to p-value and effect size for hypothesis testing
- Understand and critically evaluate the factors influencing the power of an experiment
- Perform Power calculation using SciPy and Python
- Demonstrate the impact of sample size on statistical power using simulations
- Demonstrate the combined effect of sample size and effect size on statistical power using simulations
The power of a statistical test is defined as the probability of rejecting the null hypothesis, given that it is indeed false. As with any probability, the power of a statistical test therefore ranges from 0 to 1, with 1 being a perfect test that gaurantees rejecting the null hypothesis when it is indeed false.
With that, let's recreate our previous coin flip simulation, and use it to plot some relationships between power, sample size, and our p-value cutoff.
import numpy as np
import scipy.stats as st
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('darkgrid')
%matplotlib inline
#What does the power increase as we increase sample size?
powers = []
cutoff = .95 #Set the p-value threshold for rejecting the null hypothesis
#Iterate through various sample sizes
unfair_coin_prob = .75
for n in range(1,50):
#Do multiple runs for that number of samples to compare
p_val = []
for i in range(200):
n_heads = np.random.binomial(n, unfair_coin_prob)
mu = n / 2
sigma = np.sqrt(n*.5*(1-.5))
z = (n_heads - mu) / (sigma / np.sqrt(n))
p_val.append(st.norm.cdf(np.abs(z)))
cur_power = sum([1 if p >= cutoff else 0 for p in p_val])/200
powers.append(cur_power)
plt.plot(list(range(1,50)), powers)
plt.title('Power of Statistical Tests of a .75 Unfair Coin by Number of Trials using .95 threshold')
plt.ylabel('Power')
plt.xlabel('Number of Coin Flips')
Text(0.5,0,'Number of Coin Flips')
As you can see, the statistical power of this test is wonderful once we take a sample of just 20 flips! You can also imagine how this power might change if we require a p-value of .99 to reject the null hypothesis:
#What does the power increase as we increase sample size?
powers = []
cutoff = .99 #Set the p-value threshold for rejecting the null hypothesis
#Iterate through various sample sizes
unfair_coin_prob = .75
for n in range(1,50):
#Do multiple runs for that number of samples to compare
p_val = []
for i in range(200):
n_heads = np.random.binomial(n, unfair_coin_prob)
mu = n / 2
sigma = np.sqrt(n*.5*(1-.5))
z = (n_heads - mu) / (sigma / np.sqrt(n))
p_val.append(st.norm.cdf(np.abs(z)))
cur_power = sum([1 if p >= cutoff else 0 for p in p_val])/200
powers.append(cur_power)
plt.plot(list(range(1,50)), powers)
plt.title('Power of Statistical Tests of a .75 Unfair Coin by Number of Trials using .99 threshold')
plt.ylabel('Power')
plt.xlabel('Number of Coin Flips')
Text(0.5,0,'Number of Coin Flips')
or if we are trying to detect a only slightly unfair coin:
#What does the power increase as we increase sample size?
powers = []
cutoff = .95 #Set the p-value threshold for rejecting the null hypothesis
#Iterate through various sample sizes
unfair_coin_prob = .55
for n in range(1,50):
#Do multiple runs for that number of samples to compare
p_val = []
for i in range(200):
n_heads = np.random.binomial(n, unfair_coin_prob)
mu = n / 2
sigma = np.sqrt(n*.5*(1-.5))
z = (n_heads - mu) / (sigma / np.sqrt(n))
p_val.append(st.norm.cdf(np.abs(z)))
cur_power = sum([1 if p >= cutoff else 0 for p in p_val])/200
powers.append(cur_power)
plt.plot(list(range(1,50)), powers)
plt.title('Power of Statistical Tests of a .55 Unfair Coin by Number of Trials using .95 threshold')
plt.ylabel('Power')
plt.xlabel('Number of Coin Flips')
Text(0.5,0,'Number of Coin Flips')
In this lesson, we discussed the idea of "statistical power" and how sample size, p_value and effect size impact the power of an experiment. Remember, the power of a statistical test is the probability of rejecting the null hypothesis when it is indeed false.