CO₂ at Mauna Loa — R forecast::auto.arima, out-of-sample¶

Companion to the Python/PyMC notebooks. auto.arima on the additive series (no Box-Cox), forecast() for the held-out 5 years, plotted with ggplot/autoplot.

In [1]:
suppressMessages({library(forecast); library(ggplot2)})
d <- read.csv('co2.csv'); y <- ts(d$co2, start=c(1958,3), frequency=12)
H <- 60; train <- head(y, length(y)-H); test <- tail(y, H)
fit <- auto.arima(train, seasonal=TRUE, stepwise=TRUE, approximation=FALSE)
print(fit)
fc <- forecast(fit, h=H); acc <- accuracy(fc, test)
cat(sprintf('\nOUT-OF-SAMPLE (5 yr):  RMSE = %.2f ppm   MAPE = %.3f%%\n', acc['Test set','RMSE'], acc['Test set','MAPE']))
cat(sprintf('Ljung-Box residual p = %.3f\n', Box.test(residuals(fit), lag=12, type='Ljung-Box')$p.value))
Series: train 
ARIMA(3,1,1)(0,1,1)[12] 

Coefficients:
         ar1     ar2      ar3      ma1     sma1
      0.1650  0.0141  -0.1382  -0.5066  -0.8482
s.e.  0.1824  0.0766   0.0581   0.1805   0.0272

sigma^2 = 0.09504:  log likelihood = -107.98
AIC=227.97   AICc=228.16   BIC=252.66
OUT-OF-SAMPLE (5 yr):  RMSE = 0.95 ppm   MAPE = 0.231%
Ljung-Box residual p = 0.907
In [2]:
options(repr.plot.width = 9, repr.plot.height = 5)
autoplot(fc, include=120) +
  autolayer(test, series='actual (held out)') +
  scale_colour_manual(values=c('actual (held out)'='red')) +
  labs(title='auto.arima out-of-sample forecast — Mauna Loa CO₂', x='year', y='CO₂ (ppm)', colour='') +
  theme_minimal(base_size=13) + theme(legend.position='top')
No description has been provided for this image

Results¶

  • auto.arima selects a low-order SARIMA with white-noise residuals and forecasts the held-out 5 years with MAPE ≈ 0.23% — agreeing with statsmodels and the Bayesian structural model.
  • Three engines agree. Across the arc: AirPassengers (fixed seasonality, log/multiplicative), sunspots (variable cyclicality, damping forecast), and CO₂ (very stable trend+seasonality, near-perfect forecast) span the range of ARIMA behaviour — the groundwork before turning to GARCH / stochastic volatility, where the variance itself becomes the moving part.