# F3-conf-03 — Rolling-origin ridge forecasts of US industrial production growth ## Question Does a fixed-penalty ridge regression (λ = 50, key `lambda`) on 8 standardised monthly predictors (`n_features`) forecast next-month US industrial production growth (100 × Δln INDPRO, percent per month) better than the naive (last value) and expanding-mean forecasts? The test uses `n_origins` = 60 rolling origins from `first_origin` = 2021-09-01 to `last_origin` = 2026-08-01, at horizon h = 1. Estimands: out-of-sample RMSE and MAE of each forecast, and 1 − RMSE_ridge/RMSE_baseline. ## Data and exclusions - Input: `data/ip_predictors.csv`, with 417 data rows (`n_input_rows`) covering 1992-01 to 2026-09. Its SHA-256 matches the README. The full audit is in `out/state/data_audit.md`. - Missing values: only `neworder_chg` for 1992-01 and 1992-02. Neither month is used. - Data issues (`data_issues`): - The README says the first month of every change series is empty, but three of these columns are filled for 1992-01. These values were used as given. - Extreme COVID-era observations (ip_growth −14.1 in 2020-04) fall inside every training window. They were kept, because the specification fixes the training rows. - The data are the current vintage, not real-time. - Exclusion ledger (`out/exclusions.csv`), for the ridge training set at the last origin: 417 rows → minus 2 months before 1992-03 → minus 2 months whose target lies after the origin → 413 training rows (`n_analysed`). ## Method - **Naive forecast:** ip_growth_t. - **Expanding-mean forecast:** the mean of ip_growth over 1992-04..t. - **Ridge forecast:** - Training rows are s = 1992-03 … t−1, with target ip_growth_{s+1}. - The features are ip_growth_s, ip_growth_{s−1}, ip_growth_{s−2}, oil_chg_s, fedfunds_s, permit_chg_s, neworder_chg_s and tcu_s. - Each feature is z-scored with the mean and the ddof=1 standard deviation of that origin's training rows. These statistics are recomputed at every origin (`normalisation_window` = "expanding"). - The target is centred on its training mean ȳ, which serves as the unpenalised intercept. - The coefficients are b = (Z′Z + 50 I)⁻¹ Z′(y − ȳ), and the forecast is ȳ + z̃_t·b. - The method has no randomness (`random_seed` = null). - Code: `out/analysis.py`. It writes `out/results.json`, `out/forecasts.csv` (180 rows) and `out/exclusions.csv`. ## Results | model | RMSE | MAE | |---|---|---| | naive | 0.8831 (`rmse_naive`) | 0.6990 (`mae_naive`) | | expanding mean | 0.5439 (`rmse_mean`) | 0.4293 (`mae_mean`) | | ridge | 0.5608 (`rmse_ridge`) | 0.4514 (`mae_ridge`) | - Compared with the naive forecast, ridge improves RMSE by 0.365 (`rel_improvement_vs_naive`), i.e. ~36% (C1). - Compared with the expanding mean, ridge is slightly worse: the relative improvement is −0.031 (`rel_improvement_vs_mean`), and its MAE is also higher (C3). - So ridge beats the naive forecast but not the expanding mean over this window. ## Uncertainty I ran Diebold–Mariano tests on the squared-error loss differential (ridge minus baseline), with the Harvey–Leybourne–Newbold small-sample correction and t(59) reference. - **Ridge vs naive:** DM = −3.36 (`dm_stat_ridge_vs_naive`), p = 0.0014 (`dm_pvalue_ridge_vs_naive`). Ridge is significantly better (C2). - **Ridge vs mean:** DM = 0.54 (`dm_stat_ridge_vs_mean`), p = 0.59 (`dm_pvalue_ridge_vs_mean`). There is no significant difference (C4). Only 60 errors are evaluated, so the relative-improvement figures carry sizeable sampling error. The ~3% gap to the mean is well within noise. ## Limitations and open issues - The data are the current vintage and publication lags are ignored. The results describe how predictable the revised series is under stylised timing, not real-time forecast accuracy. - λ is fixed at 50 by the specification and was not tuned. Other penalties or feature sets could rank differently; this was not evaluated. - COVID outliers stay in every training window and can distort the scaling statistics and the coefficients. - The evaluation window (2021-10 to 2026-09 targets) is a single, fairly calm post-pandemic period. - The DM test is applied to forecasts from estimated models (with the mean nested in ridge as λ→∞), so its p-values are approximate. - Feasibility: complete.