DensityScore#
- class cultivars.forecast.scoring.DensityScore(paths, realized, *, names=None)[source]#
Score one origin’s density forecast against what happened.
Constructs from raw arrays – the
forecast_pathsoutput of any Bayesian result in the package, or any rival forecaster’s simulated paths – so the grading is model-agnostic by design. The predictive sample \(\{x^{(s)}_{h}\}_{s=1}^{S}\) at each horizon \(h\) stands in for the predictive distribution, and every score inDensityScoreResultis a functional of that sample and the outcome \(y_h\): the CRPS and the energy score exactly, the log score through a kernel density estimate, the point losses through the sample mean and median.- Parameters:
- Variables:
_paths – The validated
(n_draws, h, k)predictive sample._realized – The validated
(h, k)outcomes._names – The resolved series labels.
- Raises:
DimensionError – If the arrays cannot be scored together.
NumericalError – If any input is not finite.
Note
One origin at a time. The class scores a single predictive sample against a single outcome path; a ranking of forecasters needs many origins, which is
Backtest’s job, and its record computes the same CRPS and log score per origin throughlosses(). A single series must arrive as a column,(n_draws, 1)or(n_draws, h, 1); a one-dimensional(n_draws,)sample is not promoted, because it cannot be told from a single-horizon(n_draws,)sample ofkseries with the draws axis missing.See also
DensityScoreResult– the recordcompute()returns.Calibration– the calibration side of the same question, across many origins.fan_chart()– the bands of the same paths.
References
Gneiting, T., & Raftery, A. E. (2007). Strictly proper scoring rules, prediction, and estimation. Journal of the American Statistical Association, 102(477), 359-378.
Example
Synthetic draws, then a BVAR’s posterior predictive scored against the four observations it held out:
>>> import numpy as np >>> rng = np.random.default_rng(0) >>> paths = rng.standard_normal((2000, 4, 2)) >>> outcome = rng.standard_normal((4, 2)) >>> scores = DensityScore(paths, outcome).compute() >>> scores.crps.shape (4, 2) >>> bool(np.all(scores.crps > 0.0)) True >>> from cultivars.multivariate.large_dim.bayesian import BVAR >>> y = np.random.default_rng(0).standard_normal((124, 2)) >>> fit = BVAR(y[:120], order=1, names=("gdp", "cpi")).fit(n_draws=200, seed=0) >>> held_out = DensityScore(fit.forecast_paths(4, seed=0), y[120:], names=fit.names) >>> record = held_out.compute() >>> record.names, record.n_horizons, record.n_draws (('gdp', 'cpi'), 4, 200)
Methods#
|
Evaluate every score. |