Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Suppose you have a large i.i.d. sample X1,X2,,XnX_1, X_2, \ldots, X_n, and let Xˉn\bar{X}_n be the sample mean. The CLT implies that with chance about 95%, the sample mean is within 2 SDs of the population mean:

P(Xˉn(μ2σn,   μ+2σn))   0.95P\big(\bar{X}_n \in (\mu - 2\frac{\sigma}{\sqrt{n}}, ~~~ \mu + 2\frac{\sigma}{\sqrt{n}}) \big) ~ \approx ~~ 0.95

where μ=E(X1)\mu = E(X_1) and σ=SD(X1)\sigma = SD(X_1) are fixed but possibly unknown parameters.

🎥 See More
Loading...
<Figure size 432x288 with 1 Axes>

This can be expressed in a different way:

P(Xˉnμ<2σn)   0.95P\big(\vert \bar{X}_n - \mu \vert < 2\frac{\sigma}{\sqrt{n}}\big) ~ \approx ~~ 0.95

Distance is symmetric, so this is the same as saying:

P(μ(Xˉn2σn,   Xˉn+2σn))   0.95P\big(\mu \in (\bar{X}_n - 2\frac{\sigma}{\sqrt{n}}, ~~~ \bar{X}_n + 2\frac{\sigma}{\sqrt{n}})\big) ~ \approx ~~ 0.95

That is why the interval “sample mean ± 2 measures of spread” is used as an interval of estimates of μ\mu.

The interval Xˉn± 2σ/n\bar{X}_n \pm ~ 2 \sigma/\sqrt{n} is called an approximate 95% confidence interval for the parameter μ\mu, the population mean. The interval has a confidence level of 95%. The level determines the use of z=2z = 2 as the multiplier of the SD of the sample mean.

14.6.1Changing the Confidence Level

You could choose a different confidence level, say 80%. With that choice you would expect the interval to be narrower. To find out exactly how many SDs you have to go on either side of the center to pick up a central area of about 80%, you have to find the corresponding zz on the standard normal curve, as shown below.

<Figure size 432x288 with 1 Axes>

As you know from Data 8 and can see in the figure, the interval runs from the 10th percentile to the 90th percentile of the distribution. So zz is the 90th percentile of the standard normal curve.

stats.norm.ppf(.9)
1.2815515655446004

Therefore an approximate 80% confidence interval for the population mean μ\mu is given by “sample mean ± 1.28σ/n\pm ~ 1.28\sigma/\sqrt{n}”.

Let’s double check that 2 is a good choice of zz for a 95% interval. The zz that we need is the 97.5 percent point:

stats.norm.ppf(.975)
1.959963984540054
🎥 See More
Loading...

14.6.2Confidence Interval for Population Mean

Let λ\lambda% be any confidence level. Let zλz_\lambda be the point such that the interval (zλ, zλ)(-z_\lambda, ~ z_\lambda) contains λ\lambda% of the area under the standard normal curve. In our example above, λ\lambda was 80 and zλz_\lambda was 1.28.

Let p=λ/100p = \lambda/100 be the value of λ\lambda converted into a proportion. For example if λ=80\lambda = 80 then p=0.8p = 0.8. Then

zλ = Φ1(p+0.5(1p))z_\lambda ~ = ~ \Phi^{-1}(p + 0.5(1-p))

because all of the area to the left of zλz_\lambda is the area pp between zλz_\lambda and zλ-z_\lambda plus the tail to the left of zλ-z_\lambda.

If nn is large,

p  P(μ(Xˉnzλσn,   Xˉn+zλσn))p ~ \approx ~ P\big(\mu \in (\bar{X}_{n} - z_{\lambda} \frac{\sigma}{\sqrt{n}}, ~~~ \bar{X}_n + z_\lambda \frac{\sigma}{\sqrt{n}})\big)

The random interval Xˉ_n ± zλσ/n\bar{X}\_{n} ~ \pm ~ z_{\lambda} \sigma/\sqrt{n} is called an approximate λ\lambda% confidence interval for the population mean μ\mu. There is about a λ\lambda% chance that this random interval contains the parameter μ\mu.

The only difference between confidence intervals of different levels is the choice of zλz_\lambda which depends on the level λ\lambda. The other two components are the sample mean and its SD.

14.6.3A Data 8 Example Revisited

Let’s return to an example very familiar from Data 8: a random sample of 1,174 pairs of mothers and their newborns.

baby = Table.read_table('baby.csv')
baby
Loading...

The third column consists of the ages of the mothers. Let’s construct an approximate 95% confidence interval for the mean age of mothers in the population. We did this in Data 8 using the bootstrap, so we will be able to compare results.

We can apply the methods of this section because our data come from a large random sample.

ages = baby.column('Maternal Age')

samp_mean = np.mean(ages)
samp_mean
27.228279386712096
n = baby.num_rows
n
1174

The observed value of Xˉn\bar{X}_n in the sample is 27.23 years. We know that n=1174n = 1174, so all we need is the population SD σ\sigma and then we can complete our calculation.

But of course we don’t know the population SD σ\sigma. We only have a sample.

As data scientists, we are used to lifting ourselves by our own bootstraps. Notice that the SD of the sample mean is σ/n\sigma/\sqrt{n}. If we estimate σ\sigma by the SD of the data, there will be some error in the estimate but the error will be divided by n\sqrt{n} and therefore won’t have much effect.

That means we can use “sample SD divided by n\sqrt{n}” as an estimate of σ/n\sigma/\sqrt{n}.

The sample SD, our estimate of σ\sigma, is about 5.82 years.

sigma_estimate = np.std(ages)
sigma_estimate
5.815360404190897

An approximate 95% confidence interval for the mean weight of mothers in the population is (26.89,27.57)(26.89, 27.57) years.

sd_sample_mean = sigma_estimate/(n ** 0.5)

ci_95_pop_mean = samp_mean + 1.96 * make_array(-1, 1) * sd_sample_mean
ci_95_pop_mean
array([26.89562086, 27.56093791])

No bootstrapping required!

🎥 See More
Loading...

Now let’s compare our interval to the interval we got in Data 8 by using the bootstrap percentile method. Here is the function bootstrap_mean from Data 8.

def bootstrap_mean(original_sample, label, replications):
    
    """Displays approximate 95% confidence interval for population mean.
    original_sample: table containing the original sample
    label: label of column containing the variable
    replications: number of bootstrap samples
    """
    just_one_column = original_sample.select(label)
    n = just_one_column.num_rows
    
    means = make_array()
    for i in np.arange(replications):
        bootstrap_sample = just_one_column.sample()
        resampled_mean = np.mean(bootstrap_sample.column(0))
        means = np.append(means, resampled_mean)
        
    left = percentile(2.5, means)
    right = percentile(97.5, means)
    
    resampled_means = Table().with_column(
    'Bootstrap Sample Mean', means
    )
    resampled_means.hist(bins=15)
    print('Approximate 95% confidence interval for population mean:')
    print(np.round(left, 2), 'to', np.round(right, 2))
    plt.plot(make_array(left, right), make_array(0, 0), color='yellow', lw=8);

Let’s construct a bootstrap 95% confidence interval for the population mean. We will use 5000 bootstrap samples as we did in Data 8.

bootstrap_mean(baby, 'Maternal Age', 5000)
Approximate 95% confidence interval for population mean:
26.89 to 27.56
<Figure size 432x288 with 1 Axes>

The bootstrap confidence interval is essentially identical to the interval (26.89, 27.57) that we got by using the normal approximation.

As we did in Data 8, let’s observe that the distribution of maternal ages in the sample is far from normal:

baby.select('Maternal Age').hist()
<Figure size 432x288 with 1 Axes>

But the empirical distribution of the sample mean, displayed as the output of the previous cell, is roughly bell shaped. That is because the probability distribution of the mean of the large sample is approximately normal by the Central Limit Theorem, even though the distribution of the population is skewed.

Note on the bootstrap

Why did we use the bootstrap for creating confidence intervals in Data 8, if the intervals can be calculated as simply as in this section?

The reason is that the methods of this section apply only to confidence intervals for the population mean, based on large i.i.d. samples. If you want to estimate a population median instead, as we did in Data 8, then the simple method above doesn’t work. The calculation and estimation of the SD is harder. But the bootstrap takes care of that for us by using resampling to find the variability in our estimates. It allows us to construct confidence intervals in some situations where theoretical methods are intractable.

The bootstrap is a powerful process. However, if all we are doing is estimating a population mean, the methods of this section are simpler.