{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"tags": [
"remove_input"
]
},
"outputs": [],
"source": [
"# NO CODE\n",
"\n",
"from datascience import *\n",
"from prob140 import *\n",
"%matplotlib inline\n",
"import matplotlib.pyplot as plt\n",
"plt.style.use('fivethirtyeight')\n",
"import numpy as np\n",
"from scipy import stats\n",
"\n",
"import warnings\n",
"warnings.filterwarnings('ignore')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## A/B Testing: Fisher's Exact Test ##"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*A/B testing* is a term used to describe tests of hypotheses that involve comparing the distributions of two random samples. Although the term is relatively new, the ideas and methods have been used by statisticians for a very long time.\n",
"\n",
"In this section we revisit a test of hypotheses performed in Data 8 using random permutations. We will show how the test can be performed using a method devised by Sir Ronald Fisher early in the 20th century.\n",
"\n",
"Recall a [randomized controlled experiment](https://www.inferentialthinking.com/chapters/12/3/Causality.html) to study a potential treatment for chronic back pain. The treatment was the botulinum toxin A, a very potent toxin that can be used as medication in tiny doses.\n",
"\n",
"A total of 31 patients participated in the study. Of these, a simple random sample of 15 were assigned to the treatment group and the remaining 16 to the control group. Eight weeks after treatment, 9 of the 15 in the treatment group had pain relief compared to 2 out of 16 in the control group.\n",
"\n",
"In other words, of the 11 patients who had pain relief, 9 were in the treatment group and 2 in the control group. What does this tell us about the treatment?\n",
"\n",
"We can answer this question by performing a test of hypotheses. In scientific experiments, the hypotheses must be posed before the experiment is run, so that they are not biased by the observed data. Therefore the hypotheses are:\n",
"\n",
"- $H_0$: The treatment does nothing; any difference between the two groups is due to the random assignment of patients to treatment and control.\n",
"\n",
"- $H_A$: The treatment does something. Note that the \"something\" could be good or bad; we are not specifying the nature of the effect.\n",
"\n",
"These are the same hypotheses we tested in Data 8, and also the same as in the paper.\n",
"\n",
"We now have to come up with a test statistic. It is natural to start by considering the number of treated patients who have pain relief. Let's call this number $X$. We might have to adjust it to get our test statistic, but let's see what we can say about it first.\n",
"\n",
"We will start by finding the distribution of $X$ under $H_0$.\n",
"\n",
"Under $H_0$, the treatment does nothing different from the control. So among the 31 patients in the study, 11 would have had pain relief anyway, regardless of the group to which they were assigned. Among those 11, $X$ would end up in the treatment group due to the random assignment of patients to groups.\n",
"\n",
"The treatment group consists of a simple random sample of 15 of the 31 patients. Therefore under $H_0$, the distribution of $X$ is hypergeometric with the following parameters:\n",
"\n",
"- N = 31, the population size\n",
"- G = 11, the total number of \"pain relief\" patients\n",
"- n = 15, the size of the treatment group\n",
"\n",
"Therefore\n",
"\n",
"$$\n",
"E_{H_0}(X) ~ = ~ 15 \\times \\frac{11}{31} ~ \\approx ~ 5.32\n",
"$$\n",
"\n",
"If the null hypothesis were true we would expect to get 5.32 \"pain relief\" patients in the treatment group. To distinguish between the null and alternative hypotheses, a good statistic to use is\n",
"\n",
"$$\n",
"T ~ = ~ \\vert X - 5.32 \\vert\n",
"$$\n",
"\n",
"This statistic $T$ is the distance between the observed count and the expected count under the null hypothesis. Large values of $T$ favor the alternative hypothesis.\n",
"\n",
"The observed value of the test statistic is\n",
"\n",
"$$\n",
"\\vert 9 - 5.32 \\vert ~ = ~ 3.68\n",
"$$\n",
"\n",
"Therefore the $p$-value is\n",
"\n",
"$$\n",
"\\begin{align*}\n",
"P_{H_0}(T \\ge 3.68) ~ &= ~ P(\\vert X - 5.32 \\vert \\ge 3.68) \\\\\n",
"&= ~ P(X \\le 5.32 - 3.68) + P(X \\ge 5.32 + 3.68) \\\\\n",
"&= ~ P(X \\le 1.64) + P(X \\ge 9) \\\\\n",
"&= ~ P(X \\le 1) + P(X \\ge 9) \\\\ \\\\\n",
"&= ~ \\sum_{g=0}^1 \\frac{\\binom{11}{g}\\binom{20}{15-g}}{\\binom{31}{15}} ~ + ~ \\sum_{g=9}^{11} \\frac{\\binom{11}{g}\\binom{20}{15-g}}{\\binom{31}{15}} \\\\ \\\\\n",
"&\\approx ~ 0.00915\n",
"\\end{align*}\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.009147039383534013"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sum(stats.hypergeom.pmf(make_array(0, 1, 9, 10, 11), 31, 11, 15))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"That's a very small $p$-value, which implies that the data support the alternative hypothesis more than they support the null. The conclusion is that treatment did something – it wasn't just the same as the control. \n",
"\n",
"This is consistent with the conclusion of the researchers and also with our own analysis in Data 8. But the approach to getting the $p$-value is different in the three analyses.\n",
"\n",
"- The calculations in the research paper involve some approximations. The reported $p$-value is $0.009$.\n",
"- In Data 8 we simulated the difference between the two group proportions under the null hypothesis, by pooling the two groups and randomly permuting the pooled sample. Our conclusion was based on an empirical, approximate $p$-value of $0.0085$.\n",
"- Our calculation in this section requires neither simulation nor approximation and produces the exact $p$-value.\n",
"\n",
"The method we have used is called *Fisher's exact test*. That's the same Sir Ronald Fisher who formalized tests of hypotheses, suggested cutoffs for $p$-values, and so on. The method can be used for any sample size and any randomized controlled experiment with a binary response."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"celltoolbar": "Edit Metadata",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}