Skip to content

Confidence Intervals (CI)

What a confidence interval means

A 95% confidence interval is not:

  • “There is a 95% probability the true mean is in this interval.”

It is:

  • “If we repeat this sampling process many times, ~95% of such intervals will contain the true mean.”

CI for a mean (using t-distribution)

Use when:

  • Population std is unknown (common)
  • Sample size is small-ish
CI for mean
import numpy as np
from scipy import stats
 
x = np.array([12, 13, 10, 9, 11, 12, 14, 8, 13, 11])
 
n = len(x)
mean = x.mean()
se = x.std(ddof=1) / np.sqrt(n)
 
alpha = 0.05
 
t_crit = stats.t.ppf(1 - alpha/2, df=n-1)
ci = (mean - t_crit * se, mean + t_crit * se)
 
print("mean:", mean)
print("95% CI:", ci)
CI for mean
import numpy as np
from scipy import stats
 
x = np.array([12, 13, 10, 9, 11, 12, 14, 8, 13, 11])
 
n = len(x)
mean = x.mean()
se = x.std(ddof=1) / np.sqrt(n)
 
alpha = 0.05
 
t_crit = stats.t.ppf(1 - alpha/2, df=n-1)
ci = (mean - t_crit * se, mean + t_crit * se)
 
print("mean:", mean)
print("95% CI:", ci)

CI for a proportion

Example: conversion rate.

CI for proportion (normal approx)
import numpy as np
 
# 60 conversions out of 1000
x = 60
n = 1000
p_hat = x / n
 
alpha = 0.05
z = 1.96
 
se = np.sqrt(p_hat * (1 - p_hat) / n)
ci = (p_hat - z * se, p_hat + z * se)
 
print("p_hat:", p_hat)
print("95% CI:", ci)
CI for proportion (normal approx)
import numpy as np
 
# 60 conversions out of 1000
x = 60
n = 1000
p_hat = x / n
 
alpha = 0.05
z = 1.96
 
se = np.sqrt(p_hat * (1 - p_hat) / n)
ci = (p_hat - z * se, p_hat + z * se)
 
print("p_hat:", p_hat)
print("95% CI:", ci)

Practical notes

  • CI width depends on sample size: larger n → tighter CI.
  • CI helps decision-making: overlap/non-overlap gives a quick signal (not a full test).

If this helped you, consider buying me a coffee ☕

Buy me a coffee

Was this page helpful?

Let us know how we did