A pointwise confidence interval covers the true mean at each location with 95% probability. But it makes no guarantee about the curve as a whole. A simultaneous band is wider: it is constructed so that the entire true curve lies inside the band with 95% probability. Use simultaneous bands when you are making statements about curve shape, such as “the smooth is everywhere positive” or “the effect peaks between times 20 and 40.”
Fit
Fit a single-smooth GAM on the motorcycle helmet dataset.
import whittaker as wk
import numpy as np
data = wk.load_dataset("mcycle")
model = wk.GAM("accel ~ s(times)").fit(data)
model.summary()
GAM fit summary
============================================================
Formula: accel ~ s(times)
Family: Gaussian(link='identity')
Inference: GCV
Observations: 133
Coefficients: 10
Parametric coefficients:
Term Estimate Std.Err t value p-value
------------------------ ---------- ---------- ---------- ----------
(Intercept) -45.6924 1.8364 -24.882 < 1e-16
Approximate significance of smooth terms:
Term EDF Ref.df Chi.sq p-value
------------------------ ------ ------ ---------- ----------
s(times) 7.92 8 663.379 < 1e-16
Total EDF: 8.92
Scale est: 448.520495
Deviance: 55654.5201
Null dev: 357878.4929
Dev. expl: 84.4%
GCV score: 480.746115
AIC: 1198.44
BIC: 1224.21
Build a prediction grid
Create a dense grid across the full range of times to evaluate both band types.
grid = {"times": np.linspace(data["times"].min(), data["times"].max(), 300)}
Pointwise confidence interval
Pass interval="confidence" to get the standard pointwise band.
# Predict with pointwise confidence intervals
pw = model.predict(grid, interval="confidence")
# Compute mean band width
pw_width = (pw.upper - pw.lower).mean().round(3)
pw_width
This is the average width of the pointwise interval across the grid.
Simultaneous confidence band
Pass interval="simultaneous" to get the wider joint-coverage band.
# Predict with simultaneous confidence bands
sim = model.predict(grid, interval="simultaneous")
# Compute mean band width
sim_width = (sim.upper - sim.lower).mean().round(3)
sim_width
The simultaneous band is uniformly wider. The ratio below shows how much the correction inflates the interval to achieve joint coverage.
# Compute width inflation ratio
round(sim_width / pw_width, 3)
A ratio above 1 confirms the simultaneous band is wider. The magnitude of the inflation depends on the effective degrees of freedom of the smooth (more wiggly smooths require a larger correction).
Compare band widths at every grid point
Look at the width difference across the curve to see where the inflation is largest.
# Compute pointwise width difference across the grid
width_diff = (sim.upper - sim.lower) - (pw.upper - pw.lower)
# Show range of the difference
(width_diff.min().round(3), width_diff.max().round(3))
(np.float64(8.193), np.float64(22.552))
The inflation is not uniform: it is typically largest near the tails where the smooth is less constrained by data.
When to use simultaneous bands
Use interval="simultaneous" whenever your inference involves the curve as a whole:
- Claiming a smooth is everywhere positive (or negative) over a range.
- Identifying where an effect peaks or crosses zero.
- Comparing two smooth curves and asking whether one is uniformly above the other.
Use interval="confidence" when you only need to characterise the mean at a specific, pre-chosen covariate value. For example, reporting the predicted mean at the observed data points.