In a horse race a set of competing models is estimated on the same data and ranked by how well they forecast. The comparison is more convincing, if it rests on forecasts that could actually have been made at the time. Therefore, each model is estimated repeatedly over an expanding window: the first window ends some periods before the end of the sample, each further window adds one period, and every estimate forecasts the periods, which follow the end of its window. The forecast errors of all windows are then summarised by out-of-sample statistics, which are complemented by the in-sample criteria of the vignette on model comparison.
This vignette lets three specifications of a VAR model compete: models with a weakly informative prior and lag orders from one to four, a model with stochastic search variable selection (SSVS) and a model with Bayesian variable selection (BVS). The last section shows how forecasts from other sources can join the race.
The models compete on the growth rate of Austrian real GDP
(dy), inflation (Dp) and the short-term
interest rate (r) from data set at_macrodata,
all in percent per quarter and up to 2019Q4, which leaves out the
quarters in which the pandemic moved output growth by ten percent. Each
model is estimated over an expanding window, whose first estimation
sample ends in 2017Q4.
data("at_macrodata")
at <- at_macrodata[["domestic"]]
data <- ts.intersect(dy = diff(at[, "y"]), Dp = at[, "Dp"], r = at[, "r"]) * 100
data <- window(data, end = c(2019, 4))
expanding_window_start <- 2018# Shared specifications
iterations <- 2000
burnin <- 1000
# Reset random number generator for reproducibility
set.seed(1234567)First, create a series of traditional VAR models:
var_default <- create_bvarmodel(data,
p = 1:4,
deterministic = "const",
iterations = iterations,
burnin = burnin)
var_default <- use_expanding_window(var_default, start = expanding_window_start)
var_default <- add_priors(var_default,
coef = list(v_i = 1 / 10, v_i_det = 1 / 100),
sigma = list(df = 3, scale = 1))
var_default <- add_initial_values(var_default)Second, create a series of VAR models with stochastic search variable selection (SSVS):
var_ssvs <- create_bvarmodel(data,
p = 4,
varsel = "ssvs",
deterministic = "const",
iterations = iterations,
burnin = burnin)
var_ssvs <- use_expanding_window(var_ssvs, start = expanding_window_start)
var_ssvs <- add_priors(var_ssvs,
coef = list(v_i = 1 / 10, v_i_det = 1 / 100),
sigma = list(df = 3, scale = 1),
varsel = list(inprior = 0.5, tau = c(0.05, 10), exclude_det = TRUE))
var_ssvs <- add_initial_values(var_ssvs)Third, create a series of VAR models with Bayesian variable selection à la Korobilis (2013):
var_bvs <- create_bvarmodel(data,
p = 4,
varsel = "bvs",
deterministic = "const",
iterations = iterations,
burnin = burnin)
var_bvs <- use_expanding_window(var_bvs, start = expanding_window_start)
var_bvs <- add_priors(var_bvs,
coef = list(v_i = 1 / 10, v_i_det = 1 / 100),
sigma = list(df = 3, scale = 1),
varsel = list(inprior = 0.5, exclude_det = TRUE))
var_bvs <- add_initial_values(var_bvs)Use combine_models to make one object:
Forecasts are obtained in two steps. First, function
add_forecast_input generates the data of the forecast
periods, where deterministic terms can be provided in the argument
deterministic and unmodelled variables in the argument
exogen. If they are not provided, the function tries to
obtain them from the model and gives a message, if it does not succeed.
Second, function add_posterior_forecasts then simulates the
forecasts.
Calculate forecast errors on which out-of-sample selection criteria will be based:
Use function add_posterior_loglik to add
log-likelihoods, on which in-sample selection criteria will be
based:
Calculate in-sample and out-of-sample selection criteria:
Compare the selection criteria. For out-of-sample criteria, the first model is used as a reference for comparison:
print(sc, relative = 1)
#>
#> ------------------------------------------
#> In-sample
#> ------------------------------------------
#>
#> Log-likelihood
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 -141.4 -141.0 -151.2 -133.3
#> Model 2 -131.4 -130.9 -143.0 -122.2
#> Model 3 -130.0 -129.7 -142.7 -119.4
#> Model 4 -128.8 -128.3 -143.2 -117.6
#> Model 5 -128.8 -128.4 -141.5 -118.2
#> Model 6 -140.4 -140.6 -152.5 -128.8
#>
#>
#> Akaike Information Criterion (AIC)
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 300.5 300.5
#> Model 2 289.7 289.7
#> Model 3 296.1 296.1
#> Model 4 302.5 302.5
#> Model 5 318.4 318.4
#> Model 6 342.8 342.8
#>
#>
#> Bayesian Information Criterion (BIC)
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 355.6 355.6
#> Model 2 372.4 372.4
#> Model 3 406.4 406.4
#> Model 4 440.3 440.3
#> Model 5 456.2 456.2
#> Model 6 480.6 480.6
#>
#>
#> Hannan-Quinn Criterion (HQ)
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 322.9 322.9
#> Model 2 323.3 323.3
#> Model 3 340.9 340.9
#> Model 4 358.4 358.4
#> Model 5 374.3 374.3
#> Model 6 398.8 398.8
#>
#>
#> Widely Applicable Information Criterion (WAIC)
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 304.4 304.4 218.9 389.9
#> Model 2 293.5 293.5 209.0 377.9
#> Model 3 301.9 301.9 211.4 392.5
#> Model 4 311.8 311.8 218.3 405.3
#> Model 5 290.2 290.2 199.5 380.8
#> Model 6 311.3 311.3 218.9 403.8
#>
#> Periods with a pointwise log-likelihood variance above 0.4, which makes the correction of WAIC unreliable, in models 1 (10), 2 (17), 3 (23), 4 (28), 5 (17), 6 (16).
#>
#>
#> Leave-One-Out Information Criterion (LOOIC)
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 304.9 304.9 219.1 390.8
#> Model 2 294.0 294.0 209.3 378.7
#> Model 3 302.9 302.9 212.2 393.6
#> Model 4 313.4 313.4 220.0 406.9
#> Model 5 290.8 290.8 199.9 381.8
#> Model 6 312.0 312.0 219.1 404.8
#>
#> Influential periods, whose importance sampling is unreliable, in models 1 (1), 3 (1), 4 (3), 5 (1), 6 (1), counted as a Pareto k above 0.7.
#>
#>
#> ------------------------------------------
#> Out-of-sample
#> ------------------------------------------
#>
#> Mean absolute forecast errors (MAFE)
#>
#> Variable h Model 1 Model 2 Model 3 Model 4 Model 5 Model 6
#> dy 1 1 0.9937 1.0185 1.0176 0.9812 0.9926
#> Dp 1 1 0.9398 0.9488 0.9424 0.9456 0.9757
#> r 1 1 0.9927 0.9902 0.9807 0.9793 0.9933
#> dy 2 1 1.0207 1.0264 1.0275 1.0018 1.0012
#> Dp 2 1 0.9437 0.9385 0.9285 0.9339 0.9842
#> r 2 1 1.0967 1.0648 1.0513 1.0238 1.0334
#> dy 3 1 1.0055 1.0165 1.0247 1.0175 0.9930
#> Dp 3 1 1.0051 1.0001 0.9838 0.9698 1.0013
#> r 3 1 1.1615 1.1503 1.1115 1.0678 1.0905
#> dy 4 1 0.9994 1.0101 1.0326 0.9989 0.9868
#> Dp 4 1 1.0297 1.0438 1.0320 0.9725 1.0359
#> r 4 1 1.2000 1.2151 1.1743 1.1063 1.0944
#>
#>
#> Root mean squared forecast errors (RMSFE)
#>
#> Variable h Model 1 Model 2 Model 3 Model 4 Model 5 Model 6
#> dy 1 1 0.9894 1.0137 1.0173 0.9826 0.9900
#> Dp 1 1 0.9399 0.9540 0.9475 0.9493 0.9848
#> r 1 1 0.9862 0.9848 0.9801 0.9761 0.9902
#> dy 2 1 1.0194 1.0298 1.0312 1.0053 1.0039
#> Dp 2 1 0.9502 0.9444 0.9346 0.9379 0.9917
#> r 2 1 1.0980 1.0686 1.0474 1.0192 1.0328
#> dy 3 1 1.0063 1.0177 1.0257 1.0141 0.9944
#> Dp 3 1 1.0022 1.0000 0.9874 0.9684 1.0026
#> r 3 1 1.1636 1.1544 1.1127 1.0641 1.0923
#> dy 4 1 0.9978 1.0097 1.0320 0.9990 0.9915
#> Dp 4 1 1.0344 1.0461 1.0311 0.9811 1.0398
#> r 4 1 1.1970 1.2152 1.1781 1.1056 1.1006AIC and BIC penalise a model by the number of parameters it nominally has, which is the same number for the three models with four lags: variable selection does not remove a coefficient from the model, it shrinks it towards zero, and how much of the nominal freedom that leaves is decided by the data rather than by the count. WAIC penalises by the flexibility the fit actually used and is the criterion to compare such models with.
No single specification forecasts best in every period, because the
errors of different models are not perfectly correlated. A pool of
forecasts exploits this: it is the mixture of the predictive
distributions of its members, and combining forecasts in this way is one
of the most reliable ways of improving them. Function
pool_forecasts forms the equal-weight pool from the draws
the models already hold, taking the same number of draws from each
member, and matches the windows of the members by the end of their
estimation samples, so that every pooled forecast combines forecasts
made with the same information. Here it pools all six models of the
race:
set.seed(1234567)
pool <- pool_forecasts(models)
pool
#> Pooled forecasts, equal weights
#>
#> Members: Model 1, Model 2, Model 3, Model 4, Model 5, Model 6
#> Variables: dy, Dp, r
#> Forecast horizon: 4
#> Draws per member: 2000
#> Forecasts: 9, from estimation samples ending in 2017Q4 to 2019Q4The pool is scored and ranked like the models. Function
combine_models adds it to the list of models, where the
functions that estimate a model leave it unchanged:
models_and_pool <- combine_models(models, pool)
models_and_pool <- add_forecast_errors(models_and_pool, test_sample = data)
sc_pool <- selection_criteria(models_and_pool)
print(sc_pool, relative = 1)
#>
#> ------------------------------------------
#> In-sample
#> ------------------------------------------
#>
#> Log-likelihood
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 -141.4 -141.0 -151.2 -133.3
#> Model 2 -131.4 -130.9 -143.0 -122.2
#> Model 3 -130.0 -129.7 -142.7 -119.4
#> Model 4 -128.8 -128.3 -143.2 -117.6
#> Model 5 -128.8 -128.4 -141.5 -118.2
#> Model 6 -140.4 -140.6 -152.5 -128.8
#> Model 7
#>
#>
#> Akaike Information Criterion (AIC)
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 300.5 300.5
#> Model 2 289.7 289.7
#> Model 3 296.1 296.1
#> Model 4 302.5 302.5
#> Model 5 318.4 318.4
#> Model 6 342.8 342.8
#> Model 7
#>
#>
#> Bayesian Information Criterion (BIC)
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 355.6 355.6
#> Model 2 372.4 372.4
#> Model 3 406.4 406.4
#> Model 4 440.3 440.3
#> Model 5 456.2 456.2
#> Model 6 480.6 480.6
#> Model 7
#>
#>
#> Hannan-Quinn Criterion (HQ)
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 322.9 322.9
#> Model 2 323.3 323.3
#> Model 3 340.9 340.9
#> Model 4 358.4 358.4
#> Model 5 374.3 374.3
#> Model 6 398.8 398.8
#> Model 7
#>
#>
#> Widely Applicable Information Criterion (WAIC)
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 304.4 304.4 218.9 389.9
#> Model 2 293.5 293.5 209.0 377.9
#> Model 3 301.9 301.9 211.4 392.5
#> Model 4 311.8 311.8 218.3 405.3
#> Model 5 290.2 290.2 199.5 380.8
#> Model 6 311.3 311.3 218.9 403.8
#> Model 7
#>
#> Periods with a pointwise log-likelihood variance above 0.4, which makes the correction of WAIC unreliable, in models 1 (10), 2 (17), 3 (23), 4 (28), 5 (17), 6 (16).
#>
#>
#> Leave-One-Out Information Criterion (LOOIC)
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 304.9 304.9 219.1 390.8
#> Model 2 294.0 294.0 209.3 378.7
#> Model 3 302.9 302.9 212.2 393.6
#> Model 4 313.4 313.4 220.0 406.9
#> Model 5 290.8 290.8 199.9 381.8
#> Model 6 312.0 312.0 219.1 404.8
#> Model 7
#>
#> Influential periods, whose importance sampling is unreliable, in models 1 (1), 3 (1), 4 (3), 5 (1), 6 (1), counted as a Pareto k above 0.7.
#>
#>
#> ------------------------------------------
#> Out-of-sample
#> ------------------------------------------
#>
#> Mean absolute forecast errors (MAFE)
#>
#> Variable h Model 1 Model 2 Model 3 Model 4 Model 5 Model 6 Model 7
#> dy 1 1 0.9937 1.0185 1.0176 0.9812 0.9926 1.0006
#> Dp 1 1 0.9398 0.9488 0.9424 0.9456 0.9757 0.9587
#> r 1 1 0.9927 0.9902 0.9807 0.9793 0.9933 0.9894
#> dy 2 1 1.0207 1.0264 1.0275 1.0018 1.0012 1.0129
#> Dp 2 1 0.9437 0.9385 0.9285 0.9339 0.9842 0.9548
#> r 2 1 1.0967 1.0648 1.0513 1.0238 1.0334 1.0450
#> dy 3 1 1.0055 1.0165 1.0247 1.0175 0.9930 1.0095
#> Dp 3 1 1.0051 1.0001 0.9838 0.9698 1.0013 0.9934
#> r 3 1 1.1615 1.1503 1.1115 1.0678 1.0905 1.0969
#> dy 4 1 0.9994 1.0101 1.0326 0.9989 0.9868 1.0047
#> Dp 4 1 1.0297 1.0438 1.0320 0.9725 1.0359 1.0190
#> r 4 1 1.2000 1.2151 1.1743 1.1063 1.0944 1.1317
#>
#>
#> Root mean squared forecast errors (RMSFE)
#>
#> Variable h Model 1 Model 2 Model 3 Model 4 Model 5 Model 6 Model 7
#> dy 1 1 0.9894 1.0137 1.0173 0.9826 0.9900 0.9989
#> Dp 1 1 0.9399 0.9540 0.9475 0.9493 0.9848 0.9628
#> r 1 1 0.9862 0.9848 0.9801 0.9761 0.9902 0.9863
#> dy 2 1 1.0194 1.0298 1.0312 1.0053 1.0039 1.0150
#> Dp 2 1 0.9502 0.9444 0.9346 0.9379 0.9917 0.9602
#> r 2 1 1.0980 1.0686 1.0474 1.0192 1.0328 1.0448
#> dy 3 1 1.0063 1.0177 1.0257 1.0141 0.9944 1.0098
#> Dp 3 1 1.0022 1.0000 0.9874 0.9684 1.0026 0.9935
#> r 3 1 1.1636 1.1544 1.1127 1.0641 1.0923 1.0992
#> dy 4 1 0.9978 1.0097 1.0320 0.9990 0.9915 1.0051
#> Dp 4 1 1.0344 1.0461 1.0311 0.9811 1.0398 1.0223
#> r 4 1 1.1970 1.2152 1.1781 1.1056 1.1006 1.1351The pool is the last model of the list. It was not estimated, so it has no in-sample criteria. Over these nine forecasts it lands in the middle of the field in most columns: it seldom beats the best model of a column, but neither does it share the largest errors, and over a longer race that robustness is what makes pools hard to beat. A pool is only as honest as the choice of its members: members chosen because they scored well over the same periods the pool is judged on flatter the pool with information it would not have had.
A horse race becomes more informative, if the models do not only
compete with each other, but also with the forecasts that institutions
actually published. Function create_external_forecast turns
such forecasts into an object, which can be added to the list of models
and which is then treated as one more competitor by all the functions
above.
Published forecasts can be taken from any source, as long as they are provided in long format with one point forecast per row. To keep this vignette self-contained, the following example uses two made-up forecasters instead. Each of them publishes a forecast for the current and the following three quarters at the beginning of every quarter from 2018Q1 to 2019Q4. Forecaster A is well informed: its forecasts are the realised values plus noise, which increases with the forecast horizon. Forecaster B always forecasts the mean of the series up to 2017Q4. Neither of them says anything about the performance of real forecasters.
fcst <- expand.grid(origin = seq(2018, 2019.75, by = 0.25),
h = 1:4,
variable = colnames(data),
forecaster = c("Forecaster A", "Forecaster B"),
stringsAsFactors = FALSE)
# Period, for which a forecast is made, as in time(data)
fcst[["period"]] <- fcst[["origin"]] + (fcst[["h"]] - 1) / 4
# Only periods with realised values can be evaluated
fcst <- fcst[fcst[["period"]] <= 2019.75, ]
# Realised values of each forecasted period
realised <- data[cbind(match(round(fcst[["period"]] * 4), round(time(data) * 4)),
match(fcst[["variable"]], colnames(data)))]
# Sample before the first publication
before <- window(data, end = c(2017, 4))
noise <- rnorm(nrow(fcst),
sd = 0.5 * sqrt(fcst[["h"]]) *
apply(diff(before), 2, sd)[fcst[["variable"]]])
fcst[["value"]] <- ifelse(fcst[["forecaster"]] == "Forecaster A",
realised + noise,
colMeans(before)[fcst[["variable"]]])
head(fcst)
#> origin h variable forecaster period value
#> 1 2018.00 1 dy Forecaster A 2018.00 1.6726137
#> 2 2018.25 1 dy Forecaster A 2018.25 1.3672011
#> 3 2018.50 1 dy Forecaster A 2018.50 1.3653565
#> 4 2018.75 1 dy Forecaster A 2018.75 0.3355216
#> 5 2019.00 1 dy Forecaster A 2019.00 1.2110604
#> 6 2019.25 1 dy Forecaster A 2019.25 0.4161256The columns of the data set do not have to follow a particular naming
convention. They are specified in the arguments period,
origin, variable and value, where
origin contains the date, at which a forecast was
published, and periods follow the convention of time,
i.e. 2018.25 for the second quarter of 2018. The names in column
variable must be those of the endogenous variables of the
models. Argument by produces one object per forecaster:
external <- create_external_forecast(fcst, models,
period = "period",
origin = "origin",
variable = "variable",
value = "value",
by = "forecaster",
data_lag = 1)A forecaster, which publishes a forecast in the first quarter of
2018, does not know the value of that quarter yet and, since data are
published with a delay, not even that of 2017Q4 in most cases. Argument
data_lag states this publication lag of the data in
periods, so that each forecast is matched to the estimation window,
which ends in 2017Q4. The forecast for 2018Q1 is then the one-step ahead
forecast of both the forecaster and the models. If a forecaster
published multiple forecasts between two data releases, only one of them
is used, the latest by default, so that no forecaster enters the
comparison twice.
From here on the external forecasts follow the workflow of the models. The functions, which add priors, initial values or posterior draws, are without effect for them:
all_models <- combine_models(models, external)
all_models <- add_forecast_errors(all_models, test_sample = data)
sc_all <- selection_criteria(all_models)
print(sc_all, relative = 1)
#>
#> ------------------------------------------
#> In-sample
#> ------------------------------------------
#>
#> Log-likelihood
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 -141.4 -141.0 -151.2 -133.3
#> Model 2 -131.4 -130.9 -143.0 -122.2
#> Model 3 -130.0 -129.7 -142.7 -119.4
#> Model 4 -128.8 -128.3 -143.2 -117.6
#> Model 5 -128.8 -128.4 -141.5 -118.2
#> Model 6 -140.4 -140.6 -152.5 -128.8
#> Model 7
#> Model 8
#>
#>
#> Akaike Information Criterion (AIC)
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 300.5 300.5
#> Model 2 289.7 289.7
#> Model 3 296.1 296.1
#> Model 4 302.5 302.5
#> Model 5 318.4 318.4
#> Model 6 342.8 342.8
#> Model 7
#> Model 8
#>
#>
#> Bayesian Information Criterion (BIC)
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 355.6 355.6
#> Model 2 372.4 372.4
#> Model 3 406.4 406.4
#> Model 4 440.3 440.3
#> Model 5 456.2 456.2
#> Model 6 480.6 480.6
#> Model 7
#> Model 8
#>
#>
#> Hannan-Quinn Criterion (HQ)
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 322.9 322.9
#> Model 2 323.3 323.3
#> Model 3 340.9 340.9
#> Model 4 358.4 358.4
#> Model 5 374.3 374.3
#> Model 6 398.8 398.8
#> Model 7
#> Model 8
#>
#>
#> Widely Applicable Information Criterion (WAIC)
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 304.4 304.4 218.9 389.9
#> Model 2 293.5 293.5 209.0 377.9
#> Model 3 301.9 301.9 211.4 392.5
#> Model 4 311.8 311.8 218.3 405.3
#> Model 5 290.2 290.2 199.5 380.8
#> Model 6 311.3 311.3 218.9 403.8
#> Model 7
#> Model 8
#>
#> Periods with a pointwise log-likelihood variance above 0.4, which makes the correction of WAIC unreliable, in models 1 (10), 2 (17), 3 (23), 4 (28), 5 (17), 6 (16).
#>
#>
#> Leave-One-Out Information Criterion (LOOIC)
#>
#> Mean Median Quantile (2.5%) Quantile (97.5%)
#> Model 1 304.9 304.9 219.1 390.8
#> Model 2 294.0 294.0 209.3 378.7
#> Model 3 302.9 302.9 212.2 393.6
#> Model 4 313.4 313.4 220.0 406.9
#> Model 5 290.8 290.8 199.9 381.8
#> Model 6 312.0 312.0 219.1 404.8
#> Model 7
#> Model 8
#>
#> Influential periods, whose importance sampling is unreliable, in models 1 (1), 3 (1), 4 (3), 5 (1), 6 (1), counted as a Pareto k above 0.7.
#>
#>
#> ------------------------------------------
#> Out-of-sample
#> ------------------------------------------
#>
#> Mean absolute forecast errors (MAFE)
#>
#> Variable h Model 1 Model 2 Model 3 Model 4 Model 5 Model 6 Model 7 Model 8
#> dy 1 1 0.9937 1.0185 1.0176 0.9812 0.9926 0.5870 0.6042
#> Dp 1 1 0.9398 0.9488 0.9424 0.9456 0.9757 0.5202 0.6144
#> r 1 1 0.9927 0.9902 0.9807 0.9793 0.9933 0.4397 10.1737
#> dy 2 1 1.0207 1.0264 1.0275 1.0018 1.0012 0.7027 0.5601
#> Dp 2 1 0.9437 0.9385 0.9285 0.9339 0.9842 0.5839 0.5857
#> r 2 1 1.0967 1.0648 1.0513 1.0238 1.0334 0.5862 6.7976
#> dy 3 1 1.0055 1.0165 1.0247 1.0175 0.9930 1.0504 0.5657
#> Dp 3 1 1.0051 1.0001 0.9838 0.9698 1.0013 0.8012 0.5798
#> r 3 1 1.1615 1.1503 1.1115 1.0678 1.0905 0.4087 5.4600
#> dy 4 1 0.9994 1.0101 1.0326 0.9989 0.9868 0.6789 0.5155
#> Dp 4 1 1.0297 1.0438 1.0320 0.9725 1.0359 0.9226 0.6909
#> r 4 1 1.2000 1.2151 1.1743 1.1063 1.0944 0.3536 4.6988
#>
#>
#> Root mean squared forecast errors (RMSFE)
#>
#> Variable h Model 1 Model 2 Model 3 Model 4 Model 5 Model 6 Model 7 Model 8
#> dy 1 1 0.9894 1.0137 1.0173 0.9826 0.9900 0.6228 0.6091
#> Dp 1 1 0.9399 0.9540 0.9475 0.9493 0.9848 0.4585 0.6407
#> r 1 1 0.9862 0.9848 0.9801 0.9761 0.9902 0.4371 8.0756
#> dy 2 1 1.0194 1.0298 1.0312 1.0053 1.0039 0.7018 0.5876
#> Dp 2 1 0.9502 0.9444 0.9346 0.9379 0.9917 0.5588 0.6256
#> r 2 1 1.0980 1.0686 1.0474 1.0192 1.0328 0.5364 5.4044
#> dy 3 1 1.0063 1.0177 1.0257 1.0141 0.9944 0.8490 0.6047
#> Dp 3 1 1.0022 1.0000 0.9874 0.9684 1.0026 0.8073 0.6288
#> r 3 1 1.1636 1.1544 1.1127 1.0641 1.0923 0.3733 4.3417
#> dy 4 1 0.9978 1.0097 1.0320 0.9990 0.9915 0.6128 0.5943
#> Dp 4 1 1.0344 1.0461 1.0311 0.9811 1.0398 0.8559 0.6988
#> r 4 1 1.1970 1.2152 1.1781 1.1056 1.1006 0.3197 3.7383The two forecasters are the last two models of the list. Since external forecasts are point forecasts, each publication contributes a single value to the out-of-sample statistics instead of a full posterior. Accordingly, their credible bands are degenerate and in-sample criteria are not available for them, which the printed comparison and the plots indicate by an empty entry.
vignette("macroprojections", package = "bvartools")
races models against projections that institutions actually published.
Those are annual, and it shows how the quarterly forecast draws of a
model are aggregated to annual figures before they are compared.
If you use bvartools in published work, please cite it.
citation("bvartools") prints the reference, and the package
has the DOI 10.5281/zenodo.22736604,
which always resolves to the latest archived version.
Korobilis, D. (2013). VAR forecasting using Bayesian variable selection. Journal of Applied Econometrics, 28(2), 204-230. https://doi.org/10.1002/jae.1271