Section D.2 Difference in Means
Before we test whether men are more variable than women, let’s warm up by confirming that men are taller than women, on average. We’ll use bootstrap resampling to estimate the sampling distribution of the difference in means. The following is a utility function that computes the difference between the first two elements of a sequence.
def diff(seq):
"""Difference between the first two elements of a sequence.
seq: sequence
returns: float
"""
return np.diff(seq)[0]
We’ll use it to compute the difference in means in a sample, which is the “test statistic”.
def diff_means(sample):
"""Difference in average height (M minus F).
sample: DataFrame with _SEX and HTM4 columns
returns: float
"""
grouped_heights = sample.groupby("_SEX")["HTM4"]
return -diff(grouped_heights.mean())
The difference is defined so a positive value indicates that men are taller. Here’s an example using the bootstrapped sample.
$ diff_means(sample)
14.455796580284954
Men are about 14 cm taller than women, on average.
The following function takes a
DataFrame and a function that computes a test statistic. It runs resample many times, computes the test statistic for each sample, and returns a list of test statistics.
def sampling_dist(df, test_stat, iters=201):
"""Generate bootstrap samples and compute test statistic.
df: DataFrame
test_stat: function that takes a DataFrame
iters: number of samples
returns: list of float
"""
return [test_stat(resample(df)) for i in range(iters)]
Here’s how we call it. The result is a sample from the sampling distribution of differences in means.
$ t1 = sampling_dist(brfss, diff_means)
np.mean(t1)
14.433755828000592
The following function uses KDE to estimate the density of the sampling distribution, uses the estimated density to compute a confidence interval, and generates a plot that shows the sampling distribution, the mean, and the 95% CI.
from scipy.stats import gaussian_kde
from empiricaldist import Pmf
def plot_sampling_distribution(data, format_str=".2f", **options):
"""Plot the sampling distribution, mean and CI."""
m, s = np.mean(data), np.std(data)
qs = np.linspace(m - 4 * s, m + 4 * s, 501)
ps = gaussian_kde(data)(qs)
pmf = Pmf(ps, qs)
pmf.normalize()
low, high = pmf.make_cdf().inverse([0.025, 0.975])
pmf.plot(**options)
Here are the results for the sampling distribution of the difference in means.
plot_sampling_distribution(t1)
plt.title("Difference in means (cm)", fontsize=14)
The difference in means is about 14.4 cm. If we simulate the data collection process and compute the difference in means many times, it varies a little, but it is never close to zero.
The following function estimates the probability that a value from this distribution exceeds 0, which is the p-value for the hypothesis that men are taller than women on average.
from scipy.stats import norm
def p_value(t):
m, s = np.mean(t), np.std(t)
if m > 0:
return norm.cdf(0, m, s)
else:
return norm.sf(0, m, s)
$ p_value(t1)
0.0
The p-value is so close to zero we can’t compute it with floating-point arithmetic, which means it is truly negligible.
This result means that if we collect another sample this size from the same population, it is practically impossible that the women in the sample would be taller, on average.
