Baselines and seasonality
Forecasting & evaluation of infectious disease dynamics
Good — compared to what?
Before asking “is my model any good?”, ask “good compared to what?”
A baseline (reference) model is a deliberately simple, naive forecast that a useful model ought to beat.
- Sets a floor — beat it, or something’s wrong
- Simple assumptions, computationally cheap, hard to overfit
- A shared baseline lets everyone measure “skill” on the same yardstick
Three simple baselines
- Persistence — “nothing changes”, predicts the most recent observation
- Mean — “reverts to normal”, predicts the long-run average
- Seasonal — “this time of year looks like it usually does”, predicts the typical seasonal pattern
We keep the fourth-root transformation so every model is on the same footing.
Persistence & mean
![]()
Persistence extends the last value; the mean ignores where we are.
The data are seasonal
A seasonal baseline: harmonic regression
ARIMA(y ~ pdq(0,0,0) + fourier(period = "year", K = 3))
- No AR / differencing / MA — only sine & cosine curves with a 1-year period
- Forecast = a smooth “seasonal climatology”; still ignores the most recent weeks
Improving on the baselines
ARIMA(y ~ pdq(2,0,0) + fourier(period = "year", K = 3))
- AR(2) anchors to recent values; Fourier pulls toward the seasonal shape
All together
![]()
The combined model captures the seasonal shape and starts from the right level — but “looks better” isn’t proof.
Did it work? Check the residuals
If a model captured the structure, its residuals should look like white noise — flat ACF, especially at the seasonal lag ~52.
![]()
- top panel: white noise in the residuals
- bottom left: no significant residual autocorrelation
- bottom right: Normal, symmetric distrbution of residuals
Your Turn
- Build the three baselines:
RW(), MEAN(), and an fourier() seasonal model.
- Add recent dynamics with an
ARIMA() + fourier() model and compare against the baselines.
- Use
gg_tsresiduals() to check whether the model captured the structure.