SPB Git

spb/wp29_uqo

Public

# F3-dev-01 — Rolling-origin forecasts of the US unemployment rate: can a simple time-series model beat the naive forecast?

# Scientific question

Over the last three years, does a simple autoregressive-type model forecast the US civilian unemployment rate better than the naive (no-change) forecast at one- and three-month horizons? The estimands are the out-of-sample root-mean-squared error (RMSE) and mean absolute error (MAE) of (a) the naive forecast and (b) one model of your choice, computed over a fixed set of rolling (expanding-window) forecast origins, and the relative improvement of the model over the naive forecast, 1 − RMSE_model / RMSE_naive, at each horizon.

# Inputs

  • data/UNRATE.csv — observed data: US unemployment rate (percent, seasonally adjusted, monthly), FRED series UNRATE (source BLS), retrieved 2026-10-30 (UTC) from https://fred.stlouisfed.org/graph/fredgraph.csv?id=UNRATE, exactly as served (header observation_date,UNRATE, one row per month dated YYYY-MM-01, 1948-01 to 2026-09). Missing observations appear as an empty value field. This is the current (final) vintage; see data/README.md for provenance, SHA-256 and terms.

# Information-availability rules

  • Forecast origins: the 36 months t = 2023-07-01, 2023-08-01, …, 2026-06-01 (the observation_date of the origin month). Horizons h ∈ {1, 3} months; the target of origin t at horizon h is the month t + h.
  • A forecast made at origin t may use only observations dated ≤ t (expanding window: the training sample grows with t). Model selection, parameter estimation and any transformation (e.g. differencing, scaling) must use only observations dated ≤ t.
  • Naive baseline: the forecast for every horizon is the most recent available observation dated ≤ t (if the origin month itself is missing, use the latest earlier observation).
  • If the actual value at a target month is missing in the data, that (origin, horizon) pair still appears in the forecast ledger with an empty actual, but is excluded from all error statistics; report the number of evaluated pairs per horizon.
  • The evaluation errors are computed on the data as given (final vintage); do not claim real-time validity.

# Required outputs

  • out/forecasts.csv — the forecast ledger, one row per (origin, horizon, model), with columns origin_date (YYYY-MM-DD), target_date (YYYY-MM-DD), horizon (integer), forecast (number), actual (number, empty if missing), model (string: naive for the baseline, and the value of model_name for your model). Expected: 36 origins × 2 horizons × 2 models = 144 rows.
  • out/results.json with the keys:
key type unit meaning
task_id string — "F3-dev-01"
model_name string — short name of your model (e.g. "AR2_diff"), used in the model column
model_description string — one-sentence specification (lags, transformation, estimation sample start, estimation method)
n_origins integer — number of forecast origins (36)
first_origin, last_origin string date first and last origin dates
n_evaluated_h1, n_evaluated_h3 integer — (origin, horizon) pairs with a non-missing actual, per horizon
rmse_naive_h1, mae_naive_h1, rmse_naive_h3, mae_naive_h3 number percentage points naive-forecast errors per horizon
rmse_model_h1, mae_model_h1, rmse_model_h3, mae_model_h3 number percentage points your model's errors per horizon
rel_improvement_rmse_h1, rel_improvement_rmse_h3 number fraction 1 − rmse_model / rmse_naive (negative if the model is worse)
feasibility string — "complete", "partial" or "infeasible"
feasibility_reason string or null — explanation if not complete
data_issues array of {"issue","handling"} — data problems detected and how handled (empty list if none)
n_input_rows object — {"UNRATE.csv": number of data rows read, excluding the header}
n_analysed integer — observations used in the last training window
random_seed integer or null — seed used, if any
  • out/report.md with the sections: Question; Data and exclusions; Method; Results; Uncertainty; Limitations and open issues.
  • out/analysis.py — running ~/wp29/venv/bin/python out/analysis.py from the workspace root must regenerate out/results.json and out/forecasts.csv from data/ only, deterministically.
  • out/claims.json — a list of the central claims of the report: [{"id": "C1", "text": "...", "results_keys": ["..."], "status": "supported"|"unsupported"|"not_evaluated", "caveat": "..."}].

# Constraints

  • No network access. Python: ~/wp29/venv/bin/python (numpy, pandas, scipy, statsmodels available). Do not modify data/.
  • This task is designed to be completed in well under 20 minutes of work.
Files · main
Menu

Theme