Monocurl Essays
Series Download

What a 95% confidence interval does and does not say

We derive the interval mean ± 1.96 standard errors, test its 95% coverage by simulation, and go through the common misreadings and why each is wrong.

21 min·High school and early college·

AssumesStandard error: how 1,000 people speak for a countryThe normal distribution and the 68-95-99.7 rule

A simulation of 100 random samples of 25 men from a population whose true mean height is 176 cm (green line). Each bar is the 95% confidence interval computed from one sample. Most bars cross the green line, and the red ones are the samples whose interval missed it.
Monocurl source
let Run = |k| {
    let kk = to_int(floor(k + 0.0001))
    return [
        Bars(kk, Z95),
        Tally(kk, Z95),
        center{[-1.45, 2.0, 0]} scale{1.1} color{INK} Number(kk, 0)
    ]
}
mesh scale_ = Scale
mesh labels = [
    TallyLabels,
    center{[-2.3, 2.0, 0]} Cap("samples:", 0.76, INK),
    center{[0.35, -2.03, 0]} Note("one bar = the interval from one sample;  green line = true mean", 0.7)
]
mesh run = Run(k: 0)

slide "run"
    play Wait(0.5)
    run.k = 100
    play Lerp(7.5, [&run], linear)
    play Wait(2)

Uses the shared definitions for this lesson's figures.

A health survey measures the heights of 25 men chosen at random and reports: mean 174.6 cm, 95% confidence interval 171.8 to 177.3 cm. Ask what the “95%” means and most people, including many who publish such intervals, answer that there is a 95% chance that the true average height lies between 171.8 and 177.3.

There is something odd about that answer. The true average height of the population is one fixed number. It does not change when we take a sample, and it either lies between 171.8 and 177.3 or it does not. Nothing in that sentence is left to chance, so what is the 95% the probability of? The answer takes some care to state, and the care matters, because the usual careless version leads to wrong conclusions that this lesson will exhibit with numbers.

What we know about a sample mean

We need a population where we know the truth, so that we can check a method against it. Take the heights of men used in the lesson on the normal distribution: the population mean is $\mu = 176$ cm and the standard deviation is $\sigma = 7$ cm. A researcher who does not know $\mu$ draws $n = 25$ men at random and computes their mean height $\bar X$.

The lesson on standard error proved two facts about $\bar X$. Its expected value is $\mu$, so it is right on average. And its standard deviation, called the standard error, is

$$ \operatorname{SE} = \frac{\sigma}{\sqrt n} = \frac{7}{\sqrt{25}} = 1.4 \text{ cm}. $$

Individual men differ from the mean by 7 cm or so, but the average of 25 of them differs from it by only about 1.4 cm. The central limit theorem adds the shape: for a sample of reasonable size, $\bar X$ is approximately normally distributed around $\mu$. (If the population is itself exactly normal, $\bar X$ is exactly normal for every $n$, and heights come close to that.)

A simulation of 200 samples of 25 men. Each dot is one sample’s mean height. The means pile up in a bell around the true mean of 176 cm, the orange curve is the normal distribution with standard deviation 1.4 cm, and the purple lines stand 1.96 standard errors (2.74 cm) either side of the truth.
Monocurl source
let LO = 171
let BINW = 0.25
let NB = 40
let X0 = -3.2
let DX = 0.16
let Y0 = -1.3
let R = 0.05
let INSIDE = count(MEANS, |m| abs(m - MU) <= M95)
let xof = |v| X0 + (v - LO) / BINW * DX
let Pile = |k| {
    let kk = to_int(floor(k + 0.0001))
    var h = map(range(0, NB), |i| 0)
    var parts = []
    for (i in range(0, kk)) {
        let b = to_int(floor((MEANS[i] - LO) / BINW))
        if (b >= 0 and b < NB) {
            parts .= Pt([X0 + (b + 0.5) * DX, Y0 + R + 0.03 + h[b] * 2 * R, 0], AZURE, R)
            h[b] = h[b] + 1
        }
    }
    parts .= center{[-2.55, 0.95, 0]} scale{1.35} color{INK} Number(kk, 0)
    return parts
}
mesh axis = [
    Seg([X0, Y0, 0], [X0 + NB * DX, Y0, 0], SLATE, 2.5),
    map(range(172, 181, 2), |v| [
        Seg([xof(v), Y0 - 0.08, 0], [xof(v), Y0 + 0.08, 0], SLATE, 2),
        center{[xof(v), Y0 - 0.32, 0]} Math(to_string(v), 0.72, SLATE)
    ]),
    center{[0, Y0 - 0.7, 0]} Note("mean height of the sample (cm)", 0.74),
    center{[-2.55, 1.45, 0]} Cap("samples taken", 0.78, INK),
    center{[2.6, 1.45, 0]} Note("each dot: the mean", 0.74),
    center{[2.6, 1.13, 0]} Note("of one sample of 25", 0.74)
]
mesh truth = [
    stroke{LEAF, 3} dashed{[0.14, 0.09]} Line([xof(MU), Y0, 0], [xof(MU), 1.68, 0]),
    center{[xof(MU), 1.92, 0]} Cap("true mean: 176 cm", 0.8, LEAF)
]
mesh pile = Pile(k: 0)
mesh band = []

slide "means"
    play Wait(0.5)
    pile.k = 200
    play Lerp(6, [&pile], linear)
    band = [
        Path(map(sample(LO, LO + NB * BINW, 120), |v| [xof(v), Y0 + 0.03 + 200 * BINW * phi((v - MU) / SE) / SE * 2 * R, 0]), EMBER, 3.5),
        Seg([xof(MU - M95), Y0, 0], [xof(MU - M95), 0.8, 0], PLUM, 3),
        Seg([xof(MU + M95), Y0, 0], [xof(MU + M95), 0.8, 0], PLUM, 3),
        center{[2.72, 0.5, 0]} Cap("between the lines:", 0.72, PLUM),
        center{[2.72, 0.1, 0]} Math(str_join([to_string(INSIDE), "\text{ of }200"]), 0.95, PLUM)
    ]
    play Fade(0.8, [&band])
    play Wait(2)

Uses the shared definitions for this lesson's figures.

Where 1.96 comes from

A normal distribution puts a fixed share of its probability within any given number of standard deviations of its mean. The 68-95-99.7 rule says that about 95% lies within two standard deviations. For an interval that is meant to catch exactly 95%, we want the multiplier to more decimal places.

The standard normal curve. The blue region between -1.96 and 1.96 has area 0.95, and each red tail has area 0.025. A normally distributed quantity therefore lands within 1.96 standard deviations of its mean 95% of the time.
The standard normal curve. The blue region between $-1.96$ and $1.96$ has area 0.95, and each red tail has area 0.025. A normally distributed quantity therefore lands within 1.96 standard deviations of its mean 95% of the time.
Monocurl source
let fz = Frame(-3.7, 3.7, 0, 0.45, [0.15, 0.2, 0], 6.6, 2.85)
let AREA = simpson(phi, -Z95, Z95, 200)
let Fill = |a, b, col| {
    var pts = [at(fz, a, 0)]
    for (x in sample(a, b, 60)) {
        pts .= at(fz, x, phi(x))
    }
    pts .= at(fz, b, 0)
    return fill{col} stroke{alpha{0} col, 0} Polygon(pts)
}
mesh grid = GridLines(fz, [-3, -2, -1, 0, 1, 2, 3], [0.1, 0.2, 0.3, 0.4])
mesh fills = [
    Fill(-Z95, Z95, tint(AZURE, 0.3)),
    Fill(-3.7, -Z95, tint(ROSE, 0.6)),
    Fill(Z95, 3.7, tint(ROSE, 0.6))
]
mesh axes = [
    Seg(at(fz, -3.7, 0), at(fz, 3.7, 0), SLATE, 2.5),
    Seg(at(fz, -3.7, 0), at(fz, -3.7, 0.45), SLATE, 2.5),
    map([-3, -1, 0, 1, 3], |v| center{[fx(fz, v), fy(fz, 0) - 0.3, 0]} Math(to_string(v), 0.72, SLATE)),
    map([0.1, 0.2, 0.3, 0.4], |v| center{[fx(fz, -3.7) - 0.36, fy(fz, v), 0]} Math(to_string(v, 1), 0.72, SLATE)),
    center{[fx(fz, 0), fy(fz, 0) - 0.68, 0]} Note("z: standard deviations from the mean", 0.74),
    center{[fx(fz, -3.7) + 0.55, fy(fz, 0.45) + 0.3, 0]} Note("density", 0.74)
]
mesh curve = Path(map(sample(-3.7, 3.7, 160), |x| at(fz, x, phi(x))), AZURE, 4)
mesh marks = [
    Seg(at(fz, -Z95, 0), at(fz, -Z95, phi(Z95)), PLUM, 3),
    Seg(at(fz, Z95, 0), at(fz, Z95, phi(Z95)), PLUM, 3),
    center{[fx(fz, -Z95), fy(fz, 0) - 0.3, 0]} Math("-1.96", 0.76, PLUM),
    center{[fx(fz, Z95), fy(fz, 0) - 0.3, 0]} Math("1.96", 0.76, PLUM),
    center{at(fz, 0, 0.15)} Math(str_join(["\text{area } ", to_string(AREA, 3)]), 1.0, AZURE),
    center{at(fz, -2.85, 0.13)} Math("0.025", 0.85, ROSE),
    center{at(fz, 2.85, 0.13)} Math("0.025", 0.85, ROSE),
    Tip(at(fz, -2.8, 0.105), at(fz, -2.3, 0.02), ROSE, 2.5, 0.13),
    Tip(at(fz, 2.8, 0.105), at(fz, 2.3, 0.02), ROSE, 2.5, 0.13)
]

Uses the shared definitions for this lesson's figures.

If $Z$ is a standard normal variable (mean 0, standard deviation 1), then

$$ P(-1.96 \le Z \le 1.96) = 0.9500. $$

The area under the normal curve has no formula in elementary functions, so this number comes from numerical integration, the same way every normal table is made; the figure computes it. With multiplier 2 the area would be 0.9545. Applied to $\bar X$, whose mean is $\mu$ and whose standard deviation is 1.4 cm, it says that 95% of samples give a mean within $1.96 \times 1.4 = 2.74$ cm of $\mu$. In the simulation, 192 of the 200 sample means fell between the purple lines.

Turning the statement around

So far the statement runs from the truth to the sample: if $\mu = 176$, the sample mean will probably land between 173.26 and 178.74. The researcher is in the opposite position. She holds a sample mean and wants to say something about $\mu$.

Pause and try

The researcher’s sample of 25 men has mean $\bar x = 174.56$ cm. She does not know $\mu$, but she knows that 95% of samples land within 2.74 cm of it. Find all the values of $\mu$ for which her sample would be one of those 95%.

Show answerHide answer

Her sample is within 2.74 of $\mu$ exactly when $\mu$ is within 2.74 of her sample, because distance is the same in both directions. So the values are those between $174.56 - 2.74 = 171.82$ and $174.56 + 2.74 = 177.30$.

The whole construction rests on that symmetry. “The sample mean is within 2.74 cm of the truth” and “the truth is within 2.74 cm of the sample mean” are the same event. So if the researcher builds an interval reaching 2.74 cm either side of whatever sample mean she gets, the interval contains $\mu$ on exactly the occasions when her sample mean lands inside the band around $\mu$.

A sample mean (blue dot) slides along the axis, carrying an interval that reaches 2.74 cm to each side. The interval contains the true mean, 176 cm, exactly while the dot is inside the green band that reaches 2.74 cm either side of 176, and turns red the moment the dot leaves the band.
Monocurl source
let X0 = -3.6
let U = 0.6
let xof = |v| X0 + (v - 170) * U
let Carry = |m| {
    let off = abs(m - MU)
    let ok = off <= M95
    let col = [ROSE, AZURE][ok]
    return [
        stroke{col, 2} dashed{[0.08, 0.07]} Line([xof(m), -0.45, 0], [xof(m), 0.75, 0]),
        Seg([xof(m - M95), 0.75, 0], [xof(m + M95), 0.75, 0], col, 6),
        Seg([xof(m - M95), 0.6, 0], [xof(m - M95), 0.9, 0], col, 4),
        Seg([xof(m + M95), 0.6, 0], [xof(m + M95), 0.9, 0], col, 4),
        Pt([xof(m), -0.45, 0], col, 0.12),
        center{[2.2, 1.52, 0]} scale{1.15} color{col} Number(off, 2),
        center{[2.45, 1.1, 0]} Cap(["interval misses 176", "interval contains 176"][ok], 0.74, col)
    ]
}
mesh band = [
    Region([[xof(MU - M95), -1.3, 0], [xof(MU + M95), -1.3, 0], [xof(MU + M95), 0.1, 0], [xof(MU - M95), 0.1, 0]], tint(LEAF, 0.16)),
    center{[xof(MU) - 0.82, -1.02, 0]} Cap("95%% of samples", 0.7, LEAF),
    center{[xof(MU) + 0.78, -1.02, 0]} Cap("land in here", 0.7, LEAF)
]
mesh axis = CmAxis(X0, U, 170, 182, 2, -1.3, "height (cm)")
mesh truth = [
    Seg([xof(MU), -1.3, 0], [xof(MU), 1.72, 0], LEAF, 3.5),
    center{[xof(MU), 1.97, 0]} Cap("true mean: 176 cm", 0.78, LEAF)
]
mesh fixed = [
    center{[-2.5, 1.95, 0]} Note("each arm of the interval", 0.72),
    center{[-2.5, 1.52, 0]} Math("2.74\text{ cm}", 0.95, INK),
    center{[2.45, 1.95, 0]} Note("sample mean is off by", 0.72),
    center{[2.95, 1.52, 0]} Math("\text{cm}", 0.9, INK)
]
mesh carry = Carry(m: 177)

slide "slide"
    play Wait(0.6)
    carry.m = 179.1
    play Lerp(2.2, [&carry])
    carry.m = 172.9
    play Lerp(4.5, [&carry])
    carry.m = 175.2
    play Lerp(2.2, [&carry])
    play Wait(1.2)

Uses the shared definitions for this lesson's figures.

The precise statement

Read the clauses against the picture. “Computed from the sample alone” means the researcher can find $L$ and $U$ without knowing $\mu$. In $P(L \le \mu \le U)$ the random objects are the endpoints $L$ and $U$; $\mu$ stands still while the interval lands in different places. “For every possible value of $\mu$” is needed because we do not know which value is the real one, so the guarantee must hold whichever it is.

The proof is exact when $\bar X$ is exactly normal. When $\bar X$ is only approximately normal, by the central limit theorem, the coverage is approximately 95%, and the approximation improves as $n$ grows. The quantity $1.96\operatorname{SE}$ is the margin of error.

For the researcher’s sample, the interval is $174.56 \pm 2.74$, which is the “171.8 to 177.3” of the opening report.

What the 95% refers to

Pause and try

A hundred researchers each draw their own sample of 25 men from this population and each computes $\bar x \pm 2.74$. How many of the hundred intervals do you expect to contain 176? Should you expect exactly that many?

Show answerHide answer

Each interval contains 176 with probability 0.95, independently of the others, so the number that do is binomial with $n = 100$ and $p = 0.95$. Its mean is 95 and its standard deviation is $\sqrt{100 \times 0.95 \times 0.05} \approx 2.2$, so anything from about 91 to 99 would be ordinary.

The figure at the top of the page runs that experiment once. Of the 100 intervals in this run, 96 contain 176 and 4 miss: two because the sample happened to run tall, two because it ran short. The researcher from our report owns the leftmost bar. She cannot see the green line. All she knows is that her bar was produced by a method whose bars cross the line 95 times in 100.

After the sample is drawn there is one specific interval, and it either contains $\mu$ or it does not. “95% confidence” is the name for our position at that point: we are using a method that succeeds 95% of the time, and we do not know whether this is one of the successes.

Three misreadings

”There is a 95% probability that $\mu$ is between 171.82 and 177.30.” In this sentence nothing is random. Both endpoints are now fixed numbers and so is $\mu$, so the statement is true or false, and the theorem assigns it no probability. You might object that this is hair-splitting, since we are still uncertain. But to turn uncertainty about $\mu$ into a probability you need an account of how likely each value of $\mu$ was before the data, which is the prior of Bayes’ theorem, and the answer then depends on that prior. A researcher who already knew from a census that $\mu$ lies between 175 and 177 would not think it 95% likely to be in her interval if the interval came out as 177.9 to 183.4. The last problem gives a case where a “50%” interval can be seen to contain the truth with certainty.

”95% of the men are between 171.82 and 177.30 cm.” The interval is about the mean, and says nothing of the kind about individuals.

The same population sampled twice. Top: the 25 heights in the researcher's sample, with her 95% interval for the mean drawn as the purple bar. Bottom: a sample of 400 men with its interval. The heights spread across some 40 cm, while the interval for the mean narrows as the sample grows.
The same population sampled twice. Top: the 25 heights in the researcher’s sample, with her 95% interval for the mean drawn as the purple bar. Bottom: a sample of 400 men with its interval. The heights spread across some 40 cm, while the interval for the mean narrows as the sample grows.
Monocurl source
let X0 = -2.3
let U = 0.12
let xof = |v| X0 + (v - 156) * U
let BIG = heights(0, 400, 14)
let SMALL = heights(0, N, SALT)
let Row = |xs, y, r, salt| {
    let m = mean(xs)
    let half = Z95 * SIGMA / sqrt(len(xs))
    let inside = count(xs, |x| abs(x - m) <= half)
    return [
        map(range(0, len(xs)), |i| Pt([xof(xs[i]), y + (rnd(i + 1, salt) - 0.5) * 0.6, 0], alpha{0.75} AZURE, r)),
        Seg([xof(m - half), y - 0.55, 0], [xof(m + half), y - 0.55, 0], PLUM, 7),
        Seg([xof(m - half), y - 0.68, 0], [xof(m - half), y - 0.42, 0], PLUM, 3.5),
        Seg([xof(m + half), y - 0.68, 0], [xof(m + half), y - 0.42, 0], PLUM, 3.5),
        center{[-3.25, y + 0.14, 0]} Cap(to_string(len(xs)), 0.9, INK),
        center{[-3.25, y - 0.2, 0]} Note("men", 0.72),
        center{[3.15, y + 0.3, 0]} Math(str_join([to_string(inside), "\text{ of }", to_string(len(xs))]), 0.9, PLUM),
        center{[3.15, y - 0.08, 0]} Note("inside the", 0.72),
        center{[3.15, y - 0.36, 0]} Note("interval", 0.72)
    ]
}
mesh axis = CmAxis(X0, U, 156, 196, 4, -1.42, "height (cm)")
mesh truth = [
    stroke{LEAF, 3} dashed{[0.14, 0.09]} Line([xof(MU), -1.42, 0], [xof(MU), 1.7, 0]),
    center{[xof(MU), 1.95, 0]} Cap("true mean: 176 cm", 0.78, LEAF)
]
mesh rows = [
    Row(SMALL, 1.05, 0.075, 3),
    Row(BIG, -0.4, 0.045, 4)
]

Uses the shared definitions for this lesson's figures.

Only 5 of the 25 men in the sample have heights inside the interval. With 400 men the interval for the mean shrinks to $\pm 0.69$ cm and holds an even smaller share of the data. A range that holds 95% of individuals is $\mu \pm 1.96\sigma$, about 162 to 190 cm, and it does not shrink with $n$.

”If the study were repeated, 95% of the new sample means would fall between 171.82 and 177.30.”

Pause and try

Our researcher’s interval is centered at 174.56, which is 1.44 cm below the truth. New sample means are centered on 176, with standard deviation 1.4. Will more or fewer than 95% of them land in her interval? Estimate the share by finding how many standard errors each end of her interval is from 176.

Show answerHide answer

Her interval runs from 171.82 to 177.30. In standard errors from 176 these are $(171.82 - 176)/1.4 = -2.99$ and $(177.30 - 176)/1.4 = 0.93$. A normal variable is below 0.93 about 82% of the time and below $-2.99$ almost never, so about 82% of new means land inside, well short of 95%.

Two of the 100 intervals from the opening simulation, each compared with the means of the 199 other samples. Interval A is the researcher's and contains the truth. Interval B is one of the four that missed. New sample means cluster around 176, not around the center of either interval.
Two of the 100 intervals from the opening simulation, each compared with the means of the 199 other samples. Interval A is the researcher’s and contains the truth. Interval B is one of the four that missed. New sample means cluster around 176, not around the center of either interval.
Monocurl source
let X0 = -3.55
let U = 0.4
let xof = |v| X0 + (v - 170) * U
let Row = |k, y, name, salt| {
    let c = MEANS[k]
    let others = filter(range(0, 200), |i| i != k)
    let inside = count(others, |i| abs(MEANS[i] - c) <= M95)
    return [
        Region([[xof(c - M95), y - 0.5, 0], [xof(c + M95), y - 0.5, 0], [xof(c + M95), y + 0.5, 0], [xof(c - M95), y + 0.5, 0]], tint(PLUM, 0.16)),
        Seg([xof(c - M95), y - 0.5, 0], [xof(c - M95), y + 0.5, 0], PLUM, 3),
        Seg([xof(c + M95), y - 0.5, 0], [xof(c + M95), y + 0.5, 0], PLUM, 3),
        map(others, |i| Pt([xof(MEANS[i]), y + (rnd(i + 1, salt) - 0.5) * 0.8, 0], alpha{0.8} [EMBER, AZURE][abs(MEANS[i] - c) <= M95], 0.05)),
        center{[3.02, y + 0.36, 0]} Cap(name, 0.76, PLUM),
        center{[3.02, y - 0.04, 0]} Math(str_join([to_string(inside), "\text{ of }", to_string(len(others))]), 0.9, AZURE),
        center{[3.02, y - 0.4, 0]} Note("new means inside", 0.7)
    ]
}
mesh axis = CmAxis(X0, U, 170, 184, 2, -1.42, "mean height of a sample (cm)")
mesh rows = [
    Row(0, 1.0, "interval A", 5),
    Row(15, -0.45, "interval B", 6)
]
mesh truth = [
    stroke{LEAF, 3} dashed{[0.14, 0.09]} Line([xof(MU), -1.42, 0], [xof(MU), 1.72, 0]),
    center{[xof(MU), 1.97, 0]} Cap("true mean: 176 cm", 0.78, LEAF)
]

Uses the shared definitions for this lesson's figures.

In the simulation, 160 of the other 199 sample means fall inside the researcher’s interval, which is 80%. For interval B, one of the four that missed, the count is 20 of 199. Averaged over all the intervals one might start from, the share is 83%: the difference between two independent sample means has variance $2\operatorname{SE}^2$, so it is within $1.96\operatorname{SE}$ with probability $P(|Z| \le 1.96/\sqrt2) = P(|Z| \le 1.386) \approx 0.834$. The interval is built to catch $\mu$, and nothing in its construction aims it at other samples.

Choosing the confidence level

Nothing forces the level to be 95%. Replacing 1.96 by another multiplier $z^*$ gives another level: $z^* = 1.282$ for 80%, $1.645$ for 90%, $2.576$ for 99%. Each is found the same way, as the point where the central area under the normal curve reaches the level.

  1. At the 80%% level each bar reaches 1.282 standard errors either side of its sample mean. The bars are short, and 18 of the 100 miss the true mean.
  2. At the 95%% level the bars reach 1.96 standard errors. Now 96 contain the true mean and 4 miss.
  3. At the 99%% level the bars reach 2.576 standard errors. Only 1 misses, and every bar is almost a third longer than at 95%%.
The same 100 samples as in the opening figure, with intervals at three confidence levels. Raising the level lengthens every bar, so fewer miss the true mean, and each bar says less about where the mean is.
Monocurl source
let Level = |z| [
    Bars(100, z),
    Tally(100, z)
]
mesh scale_ = Scale
mesh labels = TallyLabels
mesh level = Level(z: 1.282)
mesh name = center{[-1.75, 2.0, 0]} Math("80\%%\text{ level: }\bar x \pm 1.282\,\mathrm{SE}", 0.82, INK)

slide "At the 80%% level each bar reaches 1.282 standard errors either side of its sample mean. The bars are short, and 18 of the 100 miss the true mean."
    play Fade(0.6)

slide "At the 95%% level the bars reach 1.96 standard errors. Now 96 contain the true mean and 4 miss."
    name = []
    play Fade(0.3, [&name])
    level.z = 1.96
    play Lerp(1.6, [&level])
    name = center{[-1.75, 2.0, 0]} Math("95\%%\text{ level: }\bar x \pm 1.96\,\mathrm{SE}", 0.82, INK)
    play Fade(0.4, [&name])

slide "At the 99%% level the bars reach 2.576 standard errors. Only 1 misses, and every bar is almost a third longer than at 95%%."
    name = []
    play Fade(0.3, [&name])
    level.z = 2.576
    play Lerp(1.6, [&level])
    name = center{[-1.75, 2.0, 0]} Math("99\%%\text{ level: }\bar x \pm 2.576\,\mathrm{SE}", 0.82, INK)
    play Fade(0.4, [&name])

Uses the shared definitions for this lesson's figures.

Confidence is bought with width. A 100% interval would have to run from minus infinity to infinity. The only way to get a narrower interval at the same level is a smaller standard error, which means a larger sample: because $\operatorname{SE} = \sigma/\sqrt n$, halving the width costs four times the data.

When $\sigma$ is unknown: the $t$ correction

The theorem assumed that $\sigma$ is known. A researcher who does not know the population mean rarely knows the population standard deviation. The natural repair is to estimate $\sigma$ by the sample standard deviation

$$ s = \sqrt{\frac{1}{n-1}\sum_{i=1}^{n}(x_i - \bar x)^2} $$

from the first lesson of this series, and to use $\bar x \pm 1.96\, s/\sqrt n$. For large samples this works, because $s$ is then close to $\sigma$. For small samples it fails, and a simulation shows how badly.

Coverage of two procedures, each tested on 2000 simulated samples at every sample size, from a normal population with \sigma treated as unknown. Red: \bar x \pm 1.96\,s/\sqrt n, which falls well short of 95% for small samples. Green: the same interval with 1.96 replaced by the t multiplier for n - 1 degrees of freedom.
Coverage of two procedures, each tested on 2000 simulated samples at every sample size, from a normal population with $\sigma$ treated as unknown. Red: $\bar x \pm 1.96\,s/\sqrt n$, which falls well short of 95% for small samples. Green: the same interval with 1.96 replaced by the $t$ multiplier for $n - 1$ degrees of freedom.
Monocurl source
let NS = [3, 5, 10, 25, 50]
let TS = [4.303, 2.776, 2.262, 2.064, 2.010]
let TRIALS = 2000
let cover = |k| {
    let n = NS[k]
    var cz = 0
    var ct = 0
    for (t in range(0, TRIALS)) {
        let xs = heights(t, n, 30 + n)
        let ratio = abs(mean(xs) - MU) / (ssd(xs) / sqrt(n))
        if (ratio <= Z95) {
            cz = cz + 1
        }
        if (ratio <= TS[k]) {
            ct = ct + 1
        }
    }
    return [100 * cz / TRIALS, 100 * ct / TRIALS]
}
let COV = map(range(0, 5), |k| cover(k))
let fc = Frame(0.4, 5.6, 78, 100, [0.2, 0.05, 0], 6.2, 3.0)
mesh frame = [
    GridLines(fc, [1, 2, 3, 4, 5], [80, 85, 90, 95, 100]),
    Seg(at(fc, 0.4, 78), at(fc, 5.6, 78), SLATE, 2.5),
    Seg(at(fc, 0.4, 78), at(fc, 0.4, 100), SLATE, 2.5),
    map(range(0, 5), |k| center{[fx(fc, k + 1), fy(fc, 78) - 0.3, 0]} Math(to_string(NS[k]), 0.76, SLATE)),
    map([80, 85, 90, 95, 100], |v| center{[fx(fc, 0.4) - 0.42, fy(fc, v), 0]} Math(str_join([to_string(v), "\%%"]), 0.72, SLATE)),
    center{[fx(fc, 3), fy(fc, 78) - 0.68, 0]} Note("sample size n", 0.74),
    center{[fx(fc, 0.4) + 1.75, fy(fc, 100) + 0.33, 0]} Note("share of intervals containing the true mean", 0.72)
]
mesh target = stroke{SLATE, 2.5} dashed{[0.14, 0.09]} Line(at(fc, 0.4, 95), at(fc, 5.6, 95))
mesh lines = [
    Path(map(range(0, 5), |k| at(fc, k + 1, COV[k][0])), ROSE, 4),
    Path(map(range(0, 5), |k| at(fc, k + 1, COV[k][1])), LEAF, 4),
    map(range(0, 5), |k| [
        Pt(at(fc, k + 1, COV[k][0]), ROSE, 0.1),
        Pt(at(fc, k + 1, COV[k][1]), LEAF, 0.1),
        center{at(fc, k + 1, COV[k][0]) + [0.3, -0.3, 0]} Math(to_string(COV[k][0], 1), 0.8, ROSE),
        center{at(fc, k + 1, COV[k][1]) + [0, 0.33, 0]} Math(to_string(COV[k][1], 1), 0.8, LEAF)
    ])
]
mesh legend = [
    center{at(fc, 4.1, 87.5)} Math("\bar x \pm 1.96\,\frac{s}{\sqrt n}", 0.95, ROSE),
    center{at(fc, 4.1, 82.5)} Math("\bar x \pm t^*\,\frac{s}{\sqrt n}", 0.95, LEAF)
]

Uses the shared definitions for this lesson's figures.

With $n = 5$ the “95%” interval contains the true mean only 88% of the time, and with $n = 3$ only 81%. The reason is that $s$ is itself computed from the sample and so varies from sample to sample. In a small sample it is often well below $\sigma$, and those are the samples whose intervals come out too short. Dividing $\bar X - \mu$ by the random quantity $s/\sqrt n$ in place of the fixed $\sigma/\sqrt n$ produces a ratio that is more spread out than a standard normal variable.

William Gosset, a chemist at the Guinness brewery writing under the name “Student”, found the distribution of that ratio in 1908, by a mix of algebra and simulated samples; Fisher proved it in 1925. We state his result without proof.

The second sentence follows from the first by the rearrangement in our earlier proof, with $s/\sqrt n$ in the role of $\operatorname{SE}$. The $t$ distributions are bell-shaped with heavier tails than the normal, so $t^*$ exceeds 1.96, and it comes from a table:

$n$351025501000
degrees of freedom2492449999
$t^*$ for 95%4.3032.7762.2622.0642.0101.962

The green line in the figure uses these multipliers, and its simulated coverage stays within a quarter of a point of 95% at every sample size. By $n = 50$ the correction is under 3%, which is why 1.96 is used freely for large samples. The theorem needs a normal population. For small samples from a strongly skewed population neither multiplier is trustworthy.

Worked examples

Where the procedure breaks

The coverage guarantee is a theorem with hypotheses: a random sample, and a sample mean that is normal or nearly so. A biased sample moves every interval the same way, and the 95% is then meaningless however large $n$ is.

The normal approximation can also fail outright. Suppose 5% of a factory’s parts are defective and an inspector checks 20. With probability $0.95^{20} \approx 0.358$ she finds none. Then $\hat p = 0$, the estimated standard error is $\sqrt{0 \times 1/20} = 0$, and the “95% interval” is the single point 0, which is wrong. Working through the other counts, the interval $\hat p \pm 1.96\sqrt{\hat p(1 - \hat p)/20}$ contains 0.05 only when she finds 1, 2, 3 or 4 defectives, which happens with probability 0.639. A procedure labeled 95% that covers 64% of the time is a broken procedure. A common rule is to require at least 10 successes and 10 failures before trusting the formula for a proportion.

Stepping back

The hard part was a matter of grammar. A probability statement about the sample mean, given the truth, had to be turned into a statement about the truth that someone holding one sample could use. The symmetry of distance does the turning, and the price is that the probability stays attached to the sampling. We end with a guarantee about a method.

That pattern, judging one result by the long-run behavior of the procedure that produced it, runs through classical statistics. The next lesson meets it again in hypothesis tests, where the question becomes whether the data are compatible with one particular value of $\mu$.

Check yourself

A study reports a 95% confidence interval of 12.1 to 15.3 mg for the mean dose a treatment requires. Which statement is correct?

Problems

The first three apply the formula. The next four ask what the interval means and when it holds. The last is a challenge.

Problem 1

Light bulb lifetimes from a production line have standard deviation 120 hours. A random sample of 64 bulbs has mean lifetime 1010 hours. Find the 95% confidence interval for the mean lifetime.

Show solutionHide solution

$\operatorname{SE} = 120/\sqrt{64} = 15$ hours. The margin is $1.96 \times 15 = 29.4$ hours, so the interval is $1010 \pm 29.4$: from 980.6 to 1039.4 hours.

Problem 2

For the bulbs of the previous problem, find the 90% and the 99% confidence intervals, and the ratio of their widths.

Show solutionHide solution

At 90% the multiplier is 1.645, giving a margin of $1.645 \times 15 \approx 24.7$: from 985.3 to 1034.7 hours. At 99% it is 2.576, giving $2.576 \times 15 \approx 38.6$: from 971.4 to 1048.6 hours. The ratio of widths is $2.576/1.645 \approx 1.57$. Going from 90% to 99% confidence makes the interval 57% wider.

Problem 3

In a random sample of 400 students, 120 walk to school. Find a 95% confidence interval for the proportion of all students who walk.

Show solutionHide solution

$\hat p = 0.30$, and the estimated standard error is $\sqrt{0.30 \times 0.70/400} = \sqrt{0.000525} \approx 0.0229$. The margin is $1.96 \times 0.0229 \approx 0.045$, so the interval is 0.255 to 0.345. There are 120 successes and 280 failures, far more than 10 of each, so the formula is safe.

Problem 4

Heights have standard deviation 7 cm. How many men must be sampled for the 95% confidence interval for the mean height to reach at most 1 cm either side of the sample mean?

Show solutionHide solution

We need $1.96 \times 7/\sqrt n \le 1$, that is, $\sqrt n \ge 13.72$, so $n \ge 188.2$. Since $n$ is a whole number, 189 men are needed. Check: $1.96 \times 7/\sqrt{189} \approx 0.998$. Compare with the lesson’s $n = 25$, which gave 2.74 cm: cutting the margin by a factor of 2.74 costs $2.74^2 \approx 7.5$ times the sample.

Problem 5

Two research teams independently sample the same population and each computes a 95% confidence interval for $\mu$. (a) What is the probability that both intervals contain $\mu$? (b) If twenty teams do this, what is the expected number of intervals that miss, and what is the probability that none of them misses?

Show solutionHide solution

(a) The samples are independent, so the two coverage events are independent, and the probability that both happen is $0.95^2 = 0.9025$. (b) The number of misses is binomial with $n = 20$ and $p = 0.05$. Its expected value is $20 \times 0.05 = 1$. The probability of no misses is $0.95^{20} \approx 0.358$. So among twenty honest 95% intervals, it is more likely than not (probability 0.642) that at least one fails to contain the truth.

Problem 6

A sample of 16 measurements has mean 52.0 and sample standard deviation 6.0. The population is roughly normal and its standard deviation is unknown. Find a 95% confidence interval for the mean, using $t^* = 2.131$ for 15 degrees of freedom. Explain why 1.96 is the wrong multiplier.

Show solutionHide solution

The estimated standard error is $6.0/\sqrt{16} = 1.5$. The margin is $2.131 \times 1.5 \approx 3.20$, so the interval is 48.8 to 55.2. The multiplier 1.96 is correct when the standard error is known exactly. Here it is estimated from 16 values, and $s$ varies from sample to sample. Samples in which $s$ comes out small produce short intervals that miss too often, so $\bar x \pm 1.96\,s/\sqrt n$ would cover less than 95% of the time. The larger multiplier restores the coverage.

Problem 7

A report states: “The mean commute is 31 minutes (95% CI 28 to 34), based on a random sample of 400 workers.” Decide whether each statement follows, and explain. (a) About 95% of workers commute between 28 and 34 minutes. (b) If the standard deviation of commutes is $\sigma$, then $\sigma$ is about 30 minutes. (c) A sample of 1600 workers would give an interval about half as wide. (d) The true mean cannot be 35 minutes.

Show solutionHide solution

(a) No. The interval is about the mean. (b) Yes. The margin is 3 minutes, so $\operatorname{SE} = 3/1.96 \approx 1.53$, and $\sigma = \operatorname{SE}\sqrt n \approx 1.53 \times 20 \approx 30.6$ minutes. Individual commutes vary by about half an hour, ten times the margin of error. (c) Yes. The standard error is proportional to $1/\sqrt n$, and $\sqrt{1600/400} = 2$. (d) No. One interval in twenty misses the truth. A true mean of 35 would put the sample mean $4/1.53 \approx 2.6$ standard errors below it, which is unusual but possible.

Problem 8

(A 50% interval that is sometimes certain.) Let $X_1$ and $X_2$ be independent, each uniformly distributed on the interval from $\theta - \frac12$ to $\theta + \frac12$, where $\theta$ is unknown. Consider the interval from the smaller observation to the larger. (a) Show that it is a 50% confidence interval for $\theta$. (b) Suppose the two observations come out 0.8 apart. Show that the interval is then certain to contain $\theta$. (c) What does this say about reading the confidence level as the probability that a particular computed interval is right?

Show solutionHide solution

(a) The interval from $\min(X_1, X_2)$ to $\max(X_1, X_2)$ contains $\theta$ exactly when one observation is below $\theta$ and the other above. Each observation is below $\theta$ with probability $\frac12$, independently, so this has probability $2 \times \frac12 \times \frac12 = \frac12$, whatever $\theta$ is.

(b) Every observation is within $\frac12$ of $\theta$, so $\theta \ge \max - \frac12$ and $\theta \le \min + \frac12$. If $\max = \min + 0.8$, then $\theta \ge \min + 0.3$ and $\theta \le \min + 0.5 = \max - 0.3$. So $\theta$ lies strictly between the two observations, with certainty.

(c) The procedure covers $\theta$ in exactly 50% of samples, as the definition requires. Yet some of the intervals it produces can be recognized, from the data alone, as certain to be right, and others (when the observations are very close together) as very likely to be wrong. The confidence level describes the procedure averaged over all samples. It is not the probability that the particular interval in hand contains the parameter.

Shared definitions used by this lesson's figures
# house kit: prepended to every essay figure after the std imports

# palette. AZURE and EMBER are the two actors, LEAF marks an answer, ROSE a problem
let PAPER = [1, 1, 1, 1]
let INK = [0.08, 0.09, 0.11, 1]
let SLATE = [0.40, 0.44, 0.50, 1]
let MIST = [0.85, 0.86, 0.88, 1]
let AZURE = [0.13, 0.42, 0.68, 1]
let EMBER = [0.89, 0.42, 0.12, 1]
let LEAF = [0.13, 0.55, 0.36, 1]
let ROSE = [0.78, 0.22, 0.24, 1]
let PLUM = [0.47, 0.30, 0.66, 1]
let GOLD = [0.85, 0.62, 0.08, 1]

background = PAPER

# an opaque pastel of col; use for fills so overlaps do not darken
let tint = |col, amount = 0.18| [
    1 - (1 - col[0]) * amount,
    1 - (1 - col[1]) * amount,
    1 - (1 - col[2]) * amount,
    1
]

# text: Cap for labels, Note for quiet labels, Math for typeset maths
let Cap = |txt, size = 0.75, col = INK| color{col} Text(txt, size, "Charter")
let Note = |txt, size = 0.65| color{SLATE} Text(txt, size, "Charter")
let Math = |tex, size = 0.9, col = INK| color{col} Tex(tex, size)

# a paper rectangle to sit behind text that crosses lines
let Plate = |pos, size| center{pos} fill{PAPER} stroke{alpha{0} PAPER, 0} Rect(size)

# shapes with fill and stroke both set, so no stray black appears
let Pt = |pos, col = INK, r = 0.075| center{pos} fill{col} stroke{col, 1} Circle(r, 48)
let Ring = |pos, col = INK, r = 0.1, w = 3| center{pos} fill{PAPER} stroke{col, w} Circle(r, 48)
let Seg = |a, b, col = INK, w = 3| stroke{col, w} Line(a, b)
let Path = |pts, col = INK, w = 3| stroke{col, w} Polyline(pts)
let Region = |pts, col| fill{col} stroke{alpha{0} col, 0} Polygon(pts)
let Outline = |pts, col = INK, w = 3| fill{alpha{0} PAPER} stroke{col, w} Polygon(pts)
let Shape = |pts, col, amount = 0.18, w = 3| fill{tint(col, amount)} stroke{col, w} Polygon(pts)
let Disc = |pos, r, col, amount = 0.18, w = 3| center{pos} fill{tint(col, amount)} stroke{col, w} Circle(r, 96)
let Box = |pos, size, col, amount = 0.18, w = 3| center{pos} fill{tint(col, amount)} stroke{col, w} Rect(size)
# a line from a to b ending in a small solid arrowhead
let Tip = |a, b, col = INK, w = 3, head = 0.17| {
    let d = normalize([b[0] - a[0], b[1] - a[1], 0])
    let n = [-d[1], d[0], 0]
    let base = [b[0] - d[0] * head, b[1] - d[1] * head, 0]
    return [
        stroke{col, w} Line(a, base),
        fill{col} stroke{col, 1} Polygon([
            b,
            [base[0] + n[0] * head * 0.42, base[1] + n[1] * head * 0.42, 0],
            [base[0] - n[0] * head * 0.42, base[1] - n[1] * head * 0.42, 0]
        ])
    ]
}

# plots. a frame is [x0, x1, y0, y1, centre, width, height]: a data window and the scene box it fills
let Frame = |x0, x1, y0, y1, c = [0, 0, 0], w = 6.4, h = 3.6| [x0, x1, y0, y1, c, w, h]
let fx = |fr, x| fr[4][0] + (x - (fr[0] + fr[1]) / 2) * fr[5] / (fr[1] - fr[0])
let fy = |fr, y| fr[4][1] + (y - (fr[2] + fr[3]) / 2) * fr[6] / (fr[3] - fr[2])
let at = |fr, x, y| [fx(fr, x), fy(fr, y), 0]

# axes through the data origin (or the nearest edge of the window), with optional names
let Axes = |fr, x_name = "", y_name = "", col = SLATE| {
    let ox = clamp(fr[0], 0, fr[1])
    let oy = clamp(fr[2], 0, fr[3])
    var parts = [
        Tip(at(fr, fr[0], oy), [fx(fr, fr[1]) + 0.25, fy(fr, oy), 0], col, 2.5, 0.15),
        Tip(at(fr, ox, fr[2]), [fx(fr, ox), fy(fr, fr[3]) + 0.25, 0], col, 2.5, 0.15)
    ]
    if (x_name != "") {
        parts .= center{[fx(fr, fr[1]) + 0.5, fy(fr, oy), 0]} Math(x_name, 0.8, col)
    }
    if (y_name != "") {
        parts .= center{[fx(fr, ox), fy(fr, fr[3]) + 0.5, 0]} Math(y_name, 0.8, col)
    }
    return parts
}

# tick marks with numbers at the listed data values
let XTicks = |fr, xs, col = SLATE, places = 0| block {
    let oy = fy(fr, clamp(fr[2], 0, fr[3]))
    for (x in xs) {
        . Seg([fx(fr, x), oy - 0.07, 0], [fx(fr, x), oy + 0.07, 0], col, 2)
        . center{[fx(fr, x), oy - 0.33, 0]} Math(to_string(x, places), 0.72, col)
    }
}
let YTicks = |fr, ys, col = SLATE, places = 0| block {
    let ox = fx(fr, clamp(fr[0], 0, fr[1]))
    for (y in ys) {
        . Seg([ox - 0.07, fy(fr, y), 0], [ox + 0.07, fy(fr, y), 0], col, 2)
        . center{[ox - 0.36, fy(fr, y), 0]} Math(to_string(y, places), 0.72, col)
    }
}

# faint grid lines at the listed data values
let GridLines = |fr, xs, ys, col = MIST| block {
    for (x in xs) {
        . Seg(at(fr, x, fr[2]), at(fr, x, fr[3]), col, 1.5)
    }
    for (y in ys) {
        . Seg(at(fr, fr[0], y), at(fr, fr[1], y), col, 1.5)
    }
}

# the graph of f over [a, b], drawn in the frame. values are clamped to the window
let Graph = |fr, f, a, b, col = AZURE, w = 4, n = 160|
    stroke{col, w} Polyline(map(sample(a, b, n), |x| at(fr, x, clamp(fr[2], f(x), fr[3]))))

# the region between the graph of f and the x axis over [a, b]
let AreaUnder = |fr, f, a, b, col = AZURE, amount = 0.2, n = 80| {
    var pts = [at(fr, a, 0)]
    for (x in sample(a, b, n)) {
        pts .= at(fr, x, clamp(fr[2], f(x), fr[3]))
    }
    pts .= at(fr, b, 0)
    return fill{tint(col, amount)} stroke{alpha{0} col, 0} Polygon(pts)
}

let rnd = |i, salt| mod(seeded_random(i, salt) + 1, 1)
# one simulated standard normal value (Box-Muller)
let std_normal = |i, salt| sqrt(-2 * ln(max(rnd(i, salt), 0.000000001))) * cos(TAU * rnd(i, salt + 1))
# the running example: heights of men, true mean 176 cm, sd 7 cm, samples of 25
let MU = 176
let SIGMA = 7
let N = 25
let SE = SIGMA / sqrt(N)
let Z95 = 1.96
let M95 = Z95 * SE
let SALT = 13
let heights = |t, n, salt| map(range(0, n), |j| MU + SIGMA * std_normal(t * n + j + 1, salt))
let MEANS = map(range(0, 200), |t| mean(heights(t, N, SALT)))
let phi = |z| exp(-z * z / 2) / sqrt(TAU)
let simpson = |f, a, b, n| {
    let h = (b - a) / n
    var s = f(a) + f(b)
    for (i in range(1, n)) {
        s = s + f(a + i * h) * (2 + 2 * mod(i, 2))
    }
    return s * h / 3
}
# sample standard deviation (divides by n - 1)
let ssd = |xs| {
    let m = mean(xs)
    return sqrt(sum(map(xs, |x| (x - m) ^ 2)) / (len(xs) - 1))
}
# a horizontal centimeter axis: value v sits at x0 + (v - lo) * u
let CmAxis = |x0, u, lo, hi, step, y, name| block {
    . Seg([x0 - 0.1, y, 0], [x0 + (hi - lo) * u + 0.1, y, 0], SLATE, 2.5)
    for (v in range(lo, hi + 1, step)) {
        . Seg([x0 + (v - lo) * u, y - 0.08, 0], [x0 + (v - lo) * u, y + 0.08, 0], SLATE, 2)
        . center{[x0 + (v - lo) * u, y - 0.32, 0]} Math(to_string(v), 0.72, SLATE)
    }
    . center{[x0 + (hi - lo) / 2 * u, y - 0.7, 0]} Note(name, 0.74)
}
# the first 100 samples' intervals, drawn as upright bars against a vertical cm scale
let YV = |v| -1.72 + (v - 169) * 0.22
let XI = |i| -2.72 + i * 0.0636
let Scale = [
    map(range(170, 185, 2), |v| [
        Seg([-3.0, YV(v), 0], [3.66, YV(v), 0], MIST, 1.5),
        Seg([-3.08, YV(v), 0], [-2.92, YV(v), 0], SLATE, 2),
        center{[-3.38, YV(v), 0]} Math(to_string(v), 0.72, SLATE)
    ]),
    Seg([-3.0, YV(169), 0], [-3.0, YV(184.6), 0], SLATE, 2.5),
    center{[-3.8, YV(176.5), 0]} rotate{PI / 2} Note("height (cm)", 0.72),
    Seg([-3.0, YV(MU), 0], [3.66, YV(MU), 0], LEAF, 3.5)
]
let Bars = |k, z| block {
    for (i in range(0, k)) {
        let m = MEANS[i]
        let col = [ROSE, AZURE][abs(m - MU) <= z * SE]
        . Seg([XI(i), YV(m - z * SE), 0], [XI(i), YV(m + z * SE), 0], col, 3)
        . Pt([XI(i), YV(m), 0], col, 0.026)
    }
}
let hits = |k, z| count(take(MEANS, k), |m| abs(m - MU) <= z * SE)
let TallyLabels = [
    center{[0.55, 2.0, 0]} Cap("contain 176:", 0.76, AZURE),
    center{[2.75, 2.0, 0]} Cap("miss:", 0.76, ROSE)
]
let Tally = |k, z| [
    center{[1.62, 2.0, 0]} scale{1.1} color{AZURE} Number(hits(k, z), 0),
    center{[3.3, 2.0, 0]} scale{1.1} color{ROSE} Number(k - hits(k, z), 0)
]