SPB Git

spb/wp29_uqo

Public

# F3-conf-03 — Rolling-origin ridge forecasts of US IP growth (h = 1)

# Question

Does a fixed-penalty (λ = 50) ridge regression on eight standardised monthly predictors forecast next month's US industrial production growth (100·Δln INDPRO) better than (i) the naive last-value forecast and (ii) the expanding historical mean, over 60 rolling origins 2021-09 … 2026-08? Estimands: out-of-sample RMSE and MAE of each forecast, and 1 − RMSE_ridge/RMSE_baseline.

# Data and exclusions

  • data/ip_predictors.csv, 417 rows (1992-01 … 2026-09), current FRED vintage retrieved 2026-10-30. Monthly index is complete, unique and sorted.
  • Missing values: only neworder_chg for 1992-01 and 1992-02. These never enter: the earliest ridge training row is s = 1992-03 (its lags reach ip_growth of 1992-01, which is present).
  • Discrepancy with README: README says the 1992-01 value of every change series is empty, but ip_growth, oil_chg and permit_chg have values for 1992-01. They were used as given (ip_growth 1992-01 only appears as the second lag of the first training row).
  • The COVID-19 swings (ip_growth −14.14 % in 2020-04, +6.35 % in 2020-06) are in every training window. I kept them because the task fixes the estimator exactly.
  • No observations were excluded. At the last origin (2026-08) the ridge model has 413 training rows (s = 1992-03 … 2026-07).

# Method

  • Origins t = 2021-09-01 … 2026-08-01 (60). The target is ip_growth at t+1. Only data dated ≤ t are used at each origin.
  • Naive: ip_growth_t. Expanding mean: the mean of ip_growth over 1992-04 … t.
  • Ridge: training pairs (z_s, y_{s+1}) for 1992-03 ≤ s ≤ t−1, with z_s = (ip_s, ip_{s−1}, ip_{s−2}, oil_chg_s, fedfunds_s, permit_chg_s, neworder_chg_s, tcu_s). At every origin, features are standardised with the training-window mean and the sample SD (ddof = 1), and the target is centred on its training mean ȳ. b = (Z′Z + 50·I)⁻¹Z′(y − ȳ), with an unpenalised intercept ȳ. Forecast = ȳ + ((z_t − μ)/σ)·b. Standardisation is therefore "expanding" (recomputed from each origin's own training window). λ is fixed and was not tuned.
  • Errors = forecast − actual, computed on current-vintage data. Everything is in out/analysis.py, which is deterministic.
  • Supplementary uncertainty (out/uncertainty.json): a Diebold–Mariano test on squared-error loss differences, with the Harvey–Leybourne–Newbold correction, Newey–West lag 0 and 3, and t(59) reference. Also a moving-block bootstrap (block 6, B = 5000, seed 20261030) of 1 − RMSE ratio, reported as a 90 % percentile interval.

# Results

model RMSE (pp/month) MAE (pp/month)
naive 0.8831 0.6990
expanding mean 0.5439 0.4293
ridge (λ = 50) 0.5608 0.4514
  • Relative improvement of ridge vs naive: 1 − 0.5608/0.8831 = +0.365 (ridge has 36.5 % lower RMSE).
  • Relative improvement of ridge vs expanding mean: −0.031, meaning ridge RMSE is 3.1 % higher than the mean's. MAE ranks the models the same way.
  • Answer: ridge clearly beats the naive forecast, but it does not beat the expanding historical mean over 2021-09 … 2026-08. It is slightly worse, and the difference is not statistically distinguishable from zero (see below).

# Uncertainty

  • Ridge vs naive: DM statistic −3.36 (NW lag 0, p = 0.001) and −3.45 (lag 3, p = 0.001). The bootstrap 90 % interval for the relative improvement is [0.27, 0.42]. The advantage over naive is robust.
  • Ridge vs mean: DM statistic +0.54 (lag 0, p = 0.59) and +0.58 (lag 3, p = 0.56). The bootstrap 90 % interval for the relative improvement is [−0.14, 0.04]. With 60 origins we cannot tell ridge and the mean apart.
  • 60 monthly origins is a short evaluation sample. The bootstrap and DM tests treat the parameter-estimation error as part of the loss differential and are only approximate. They are not part of the specified estimands.

# Limitations and open issues

  • Current-vintage data, and publication lags are ignored (e.g., INDPRO/TCU/NEWORDER for month t are not actually known at the end of month t). Results describe how predictable the revised series is under stylised timing. They are not real-time forecast performance.
  • λ = 50 was fixed by the task and not tuned. Other penalties, or robust handling of the 2020 outliers (which strongly affect μ, σ and b), could change the ranking. I did not explore these, because that would depart from the specified estimator.
  • The evaluation window (post-COVID recovery, 2021–2026) is a single regime, so these conclusions may not generalise.
  • README/data discrepancy on 1992-01 change values (documented above); it does not affect the forecasts materially.
Files · main
Menu

Theme