# Set up packages for lecture. Don't worry about understanding this code,
# but make sure to run it if you're following along.
import numpy as np
import babypandas as bpd
import pandas as pd
from matplotlib_inline.backend_inline import set_matplotlib_formats
import matplotlib.pyplot as plt
set_matplotlib_formats("svg")
plt.style.use('ggplot')
np.set_printoptions(threshold=20, precision=2, suppress=True)
pd.set_option("display.max_rows", 7)
pd.set_option("display.max_columns", 8)
pd.set_option("display.precision", 2)
np.random.multinomial
¶A randomly selected member of our population is Black with probability 0.26 and not Black with probability 1 - 0.26 = 0.74.
demographics = [0.26, 0.74]
Each time we run the following cell, we'll get a new random sample of 100 people from this population.
np.random.multinomial(100, demographics)
array([29, 71])
We also need to calculate our statistic, which in this case is the number of Black men in the random sample of 100.
np.random.multinomial(100, demographics)[0]
22
counts
.counts = np.array([])
for i in np.arange(10000):
count = np.random.multinomial(100, demographics)[0]
counts = np.append(counts, count)
counts
array([30., 31., 25., ..., 35., 23., 21.])
Was a jury panel with 8 Black men suspiciously unusual?
(bpd.DataFrame().assign(count_black_men=counts)
.plot(kind='hist', bins = np.arange(9.5, 45, 1),
density=True, ec='w', figsize=(10, 5),
title='Empiricial Distribution of the Number of Black Men in Simulated Jury Panels of Size 100'));
observed_count = 8
plt.axvline(observed_count, color='black', linewidth=4, label='Observed Number of Black Men in Actual Jury Panel')
plt.legend();
# In 10,000 random experiments, the panel with the fewest Black men had how many?
counts.min()
11.0
Let's suppose we find a coin on the ground and we aren't sure whether it's a fair coin.
Out of curiosity (and boredom), we flip it 400 times.
flips_400 = bpd.read_csv('data/flips-400.csv')
flips_400
flip | outcome | |
---|---|---|
0 | 1 | Tails |
1 | 2 | Tails |
2 | 3 | Tails |
... | ... | ... |
397 | 398 | Heads |
398 | 399 | Heads |
399 | 400 | Tails |
400 rows × 2 columns
flips_400.groupby('outcome').count()
flip | |
---|---|
outcome | |
Heads | 188 |
Tails | 212 |
In the examples we've seen so far, our goal has been to choose between two views of the world, based on data in a sample.
</small>
n
flips of a fair coin using np.random.multinomial(n, [0.5, 0.5])
, but we can't simulate n
flips of an unfair coin.# Computes a single simulated test statistic.
np.random.multinomial(400, [0.5, 0.5])[0]
217
# Computes 10,000 simulated test statistics.
results = np.array([])
for i in np.arange(10000):
result = np.random.multinomial(400, [0.5, 0.5])[0]
results = np.append(results, result)
results
array([213., 183., 198., ..., 194., 186., 206.])
Let's visualize the empirical distribution of the test statistic $\text{number of heads}$.
bpd.DataFrame().assign(results=results).plot(kind='hist', bins=np.arange(160, 240, 4),
density=True, ec='w', figsize=(10, 5),
title='Empirical Distribution of the Number of Heads in 400 Flips of a Fair Coin');
plt.legend();
If we observed close to 200 heads, we'd think our coin is fair.
There are two cases in which we'd think our coin is unfair:
This means that the histogram above is divided into three regions, where two of them mean the same thing (we think our coin is unfair).
It would be a bit simpler if we had a histogram that was divided into just two regions. How do we create such a histogram?
Let's define a function that computes a single value of our test statistic. We'll do this often moving forward.
def num_heads_from_200(arr):
return abs(arr[0] - 200)
num_heads_from_200([188, 212])
12
Now, we'll repeat the act of flipping a fair coin 10,000 times again. The only difference is the test statistic we'll compute each time.
results = np.array([])
for i in np.arange(10000):
result = num_heads_from_200(np.random.multinomial(400, [0.5, 0.5]))
results = np.append(results, result)
results
array([14., 9., 7., ..., 5., 5., 22.])
Let's visualize the empirical distribution of our new test statistic, $| \text{number of heads} - 200 |$.
bpd.DataFrame().assign(results=results).plot(kind='hist', bins=np.arange(0, 60, 4),
density=True, ec='w', figsize=(10, 5),
title=r'Empirical Distribution of | Num Heads - 200 | in 400 Flips of a Fair Coin');
plt.axvline(12, color='black', linewidth=4, label='observed statistic (12)')
plt.legend();
In black, we've drawn our observed statistic, 12. Does 12 seem like a reasonable value of the test statistic – that is, how rare was it to see a test statistic of 12 or larger in our simulations?
Since we're using the number of heads as our test statistic again, our simulation code is the same as it was originally.
results = np.array([])
for i in np.arange(10000):
result = np.random.multinomial(400, [0.5, 0.5])[0]
results = np.append(results, result)
results
array([203., 199., 202., ..., 213., 198., 192.])
Let's visualize the empirical distribution of the test statistic $\text{number of heads}$, one more time.
bpd.DataFrame().assign(results=results).plot(kind='hist', bins=np.arange(160, 240, 4),
density=True, ec='w', figsize=(10, 5),
title='Empirical Distribution of the Number of Heads in 400 Flips of a Fair Coin');
plt.axvline(188, color='black', linewidth=4, label='observed statistic (188)')
plt.legend();
We'll look more closely at how to draw a conclusion from a hypothesis test and come up with a more precise definition of being "consistent" with the empirical distribution of test statistics generated according to the model.