SPB Git

spb/wp29_uqo

Public
4.4 KB · 50 lines markdown
1# F3-conf-03 — Rolling-origin ridge forecasts of US industrial production growth23## Question4Does a fixed-penalty ridge regression (λ = 50; `lambda`) on eight standardised predictors forecast next-month US industrial production growth (100 × Δln INDPRO) better than the naive (last value) forecast and the expanding historical mean? I evaluated this over 60 rolling origins (`n_origins`), from `first_origin` = 2021-09-01 to `last_origin` = 2026-08-01, at horizon h = 1. The estimands are each model's out-of-sample RMSE and MAE, and the ridge model's relative RMSE improvement over each baseline.56## Data and exclusions7The input is `data/ip_predictors.csv`: 417 rows (`n_input_rows`), monthly from 1992-01 to 2026-09. It is current-vintage FRED data, and its SHA-256 matches the README. There are no duplicate or missing months. The only empty cells are `neworder_chg` for 1992-01 and 1992-02. All data problems and how I handled them are listed in `data_issues`:8- The README says the 1992-01 cells of every change series are empty. In the file, three of them (`ip_growth`, `oil_chg`, `permit_chg`) have values. I used the values as given.9- The extreme COVID-19 months (2020-03 to 2020-06) are kept in every training window.10- The data are revised (current vintage), and publication lags are ignored.1112Exclusion ledger (`out/exclusions.csv`), counted at the last origin: start with 417 rows. Dropping months before 1992-03-01 (the training start set in the specification) leaves 415. Dropping months whose target would fall after the origin leaves 413 training rows (`n_analysed`).1314## Method15- **Naive forecast:** `ip_growth` at the origin t.16- **Mean forecast:** the arithmetic mean of `ip_growth` from 1992-04 to t.17- **Ridge model:** trained on rows s from 1992-03 to t−1, with target `ip_growth` at s+1.18  - Features (`n_features` = 8): `ip_growth` at s, s−1 and s−2, plus `oil_chg`, `fedfunds`, `permit_chg`, `neworder_chg` and `tcu`.19  - Each feature is standardised with the mean and the sample standard deviation (ddof = 1) of that origin's training rows. These statistics are recomputed at every origin (`normalisation_window` = "expanding").20  - The target is centred on its training mean ȳ, and b = (Z′Z + 50 I)⁻¹ Z′(y − ȳ). The intercept is not penalised.21  - Forecast = ȳ + z̃_t·b, where z̃_t is the origin's feature vector standardised with the same statistics.22- **Evaluation:** errors are forecast − actual over the 60 target months, 2021-10 to 2026-09.23- No randomness is involved (`random_seed` = null).2425## Results26| model | RMSE (pp/month) | MAE (pp/month) |27|---|---|---|28| naive | 0.883 (`rmse_naive`) | 0.699 (`mae_naive`) |29| expanding mean | 0.544 (`rmse_mean`) | 0.429 (`mae_mean`) |30| ridge λ=50 | 0.561 (`rmse_ridge`) | 0.451 (`mae_ridge`) |3132- **Ridge vs naive:** ridge reduces RMSE by 36.5% (`rel_improvement_vs_naive` = 0.365).33- **Ridge vs expanding mean:** ridge does *not* beat the mean. Its RMSE is 3.1% higher (`rel_improvement_vs_mean` = −0.031), and its MAE is also higher (`mae_ridge` vs `mae_mean`).3435The individual forecasts are in `out/forecasts.csv`: 180 rows, 60 per model.3637## Uncertainty38I ran Diebold–Mariano tests on squared-error loss for h = 1, with the Harvey–Leybourne–Newbold correction and a t(59) reference distribution:39- **Ridge vs naive:** DM = 3.36, p = 0.0014 (`dm_stat_vs_naive`, `dm_pvalue_vs_naive`). The ridge model's advantage over the naive forecast is statistically significant.40- **Ridge vs mean:** DM = −0.54, p = 0.59 (`dm_stat_vs_mean`, `dm_pvalue_vs_mean`). The two forecasts' accuracy cannot be told apart statistically.4142With only 60 forecast errors, the RMSE estimates are imprecise. I did not compute confidence intervals for the RMSEs themselves.4344## Limitations and open issues45- **Not real-time:** the data are current-vintage (revised) INDPRO, TCU and NEWORDER, and publication lags are ignored. These are pseudo-out-of-sample results, not real-time forecast performance.46- **Fixed specification:** λ is fixed at 50 and not tuned, and the model is linear. Every training window includes the COVID-19 extremes, which may distort the coefficients. The specification defines the windows without exclusions, so I kept them.47- **Narrow evaluation:** the window is short (60 months) and covers a single period, 2021–2026.48- **README discrepancy:** the README's statement about empty 1992-01 cells does not match the file (see `data_issues`).49- **Feasibility:** the task was completed in full (`feasibility` = "complete").50
Files · 142b688c28c78ba61ec1f5788e17a176c2bbac2a
Menu

Theme