pkgdown/extra.css

Skip to contents

Takes a tbl_now and chooses a model for you: it builds a grid of candidate models (epidemic process x reporting-delay family) sized to how much data you have, backtest()s them over several historical dates, score()s them, keeps the best one, and refits it on the full data. The returned object is an ordinary nowcast() result (so autoplot(), predict(), etc. work), with the ranked scoreboard attached in its comparison slot.

Usage

auto_nowcast(
  data,
  metric = c("wis", "ape", "mse", "coverage", "coverage_50", "coverage_90"),
  type = c("auto", "two_stage", "one_stage"),
  sir = NULL,
  ar = NULL,
  hsgp = NULL,
  delays = NULL,
  likelihood = nb_likelihood(),
  models = NULL,
  n_dates = 6L,
  n_draws_select = 500L,
  n_draws = 2000L,
  K = 25L,
  K_select = 10L,
  min_ar = 15L,
  min_hsgp = 30L,
  now = NULL,
  seed = sample.int(.Machine$integer.max, 1),
  verbose = TRUE,
  ...
)

Arguments

data

A tbl_now object (tbl.now::tbl_now()).

metric

Selection criterion. "wis" (default, lowest Weighted Interval Score), "ape" (lowest absolute percentage error of the median), "mse" (lowest mean squared error), or one of the calibration criteria, which pick the model whose empirical interval coverage is closest to nominal: "coverage_50" (smallest |0.50 - coverage_50|), "coverage_90" (smallest |0.90 - coverage_90|), or "coverage" (smallest |0.50 - coverage_50| + |0.90 - coverage_90|, i.e. both intervals jointly).

type

Stage strategy used for both the backtest and the final fit: "auto" (default), "two_stage", or "one_stage" (see nowcast()).

sir, ar, hsgp

Optional epidemic-process components (e.g. sir_epidemic(R0 = ...)) carrying your priors. If supplied, that process is forced into the candidate grid; otherwise the plain constructor is used when the series length calls for it.

delays

A list of delay components to compare. Default: list(lognormal_delay(), generalized_gamma_delay(), dirichlet_delay()).

likelihood

Either a single likelihood used for every candidate (default nb_likelihood()), or a list of likelihoods to compare too, e.g. list(nb_likelihood(), poisson_likelihood()).

models

Optional model() object or list of them (e.g. carrying a custom_delay() / custom_epidemic()) appended to the candidate grid so they compete in the same backtest.

n_dates

Number of historical dates to backtest over (default 6).

n_draws_select

Posterior draws during the selection backtest (default 500 – kept small for speed).

n_draws

Posterior draws for the final fit of the winning model (default 2000).

K

Delay imputations for the final two-stage fit of the winning model (default 25).

K_select

Delay imputations during the selection backtest (default 10 – kept small for speed, like n_draws_select). The selection backtest fits the whole grid over many dates, so its cost scales with K_select; ranking the candidates is robust to a coarser imputation than the final fit. Lower it (e.g. 5) for a long series where selection dominates the runtime.

min_ar, min_hsgp

Series-length thresholds (in event-times) at which AR(1) and HSGP become candidates (defaults 15 and 30).

now

As-of date for the final fit (default: the tbl_now's now).

seed

RNG seed.

verbose

Print progress and the chosen model (default TRUE).

...

Passed through to backtest() and nowcast() (e.g. temporal_effects).

Value

A nowcast_class (as from nowcast()) for the selected model, with the model-selection scoreboard in its comparison slot: list(scores, chosen, metric, max_time).

Details

Candidate epidemic processes are chosen by series length (max_time, the number of event-times): a process becomes a candidate as soon as the series is long enough to support it (SIR needs the least data, the HSGP the most) and is never dropped for being too long, so the comparison always spans every process the data can support. With the default thresholds:

  • max_time < min_ar -> compares {SIR};

  • min_ar <= max_time < min_hsgp -> compares {SIR, AR(1)};

  • max_time >= min_hsgp -> compares {SIR, AR(1), HSGP}.

Any process you pass explicitly via sir / ar / hsgp is always included (regardless of length), which is how you make a prior compete: e.g. pass sir = sir_epidemic(R0 = lognormal_prior(log(3), 0.2)) and the SIR candidate will use that R0 prior throughout the comparison.

Robustness. A candidate that fails to converge on a backtest date simply drops out of the comparison there (it never aborts the search), and candidates are scored on the common set of dates where they all produced a forecast so a model cannot "win" on a lucky subset. The winner is then refit on the full data; if that refit fails, auto_nowcast() falls through to the next-best candidate (and so on), so it converges whenever any candidate would.

Candidate delays default to LogNormal, Generalized-Gamma and Dirichlet; override with delays.

Speed. The grid is backtested with a fast configuration (n_draws_select posterior draws over n_dates dates spread across the history); only the winning model is refit with the full n_draws. Backtesting is the expensive step – set a future::plan() (e.g. future::plan(multisession)) for parallel speed-up.

Examples

# \donttest{
library(tbl.now)
data(denguedat)
# A short window keeps this example quick (auto_nowcast fits a whole grid):
dn <- subset(denguedat,
             onset_week >= as.Date("1990-06-01") & onset_week <= as.Date("1990-12-01"))
tn <- tbl_now(dn, event_date = onset_week, report_date = report_week,
              data_type = "linelist", verbose = FALSE)
# Backtesting the grid is the expensive step -- uncomment to run candidates
# in parallel (then restore sequential afterwards):
# future::plan(future::multisession, workers = 4)
# Compare a couple of delays; make the SIR candidate use a custom R0 prior:
nc <- auto_nowcast(tn,
                   sir    = sir_epidemic(R0 = lognormal_prior(log(2), 0.3)),
                   delays = list(lognormal_delay(), dirichlet_delay()),
                   n_dates = 2, n_draws_select = 150, n_draws = 300,
                   temporal_effects = "none")
#>  auto_nowcast: comparing 6 candidate models (1 likelihood x 3 epidemic
#>   processes x 2 delays) over 2 backtest dates; max_time = 35.
#>  Running 12 backtest cells sequentially.
#>  For a large grid, set a parallel plan first:
#>   `future::plan(future::multisession, workers = N)`.
#>  auto_nowcast: selected HSGP/nb/LogNormal (best wis).
# future::plan(future::sequential)
best_model_name(nc)    # the winning model's label
#> [1] "HSGP/nb/LogNormal"
comparison_scores(nc)  # the ranked scoreboard
#>               model      wis overprediction underprediction dispersion
#> 1 HSGP/nb/LogNormal 18.60444              0        6.000000  12.604444
#> 2  SIR/nb/Dirichlet 21.49708              0        9.388889  12.108194
#> 3 HSGP/nb/Dirichlet 22.08194              0       13.333333   8.748611
#> 4  SIR/nb/LogNormal 22.12306              0       12.000000  10.123056
#> 5  AR1/nb/Dirichlet 25.44486              0       16.388889   9.055972
#> 6  AR1/nb/LogNormal 28.04625              0       20.500000   7.546250
#>   coverage_50 coverage_90       ape     mse n
#> 1           1           1 0.5346535 2916.00 1
#> 2           0           1 0.6386139 4160.25 1
#> 3           0           1 0.6138614 3844.00 1
#> 4           0           1 0.5643564 3249.00 1
#> 5           0           1 0.7772277 6162.25 1
#> 6           0           1 0.7970297 6480.25 1
best_score(nc)         # just the winner's row
#>               model      wis overprediction underprediction dispersion
#> 1 HSGP/nb/LogNormal 18.60444              0               6   12.60444
#>   coverage_50 coverage_90       ape  mse n
#> 1           1           1 0.5346535 2916 1
selection_metric(nc)   # which metric chose it
#> [1] "wis"
winner <- best_model(nc)  # the model() object, to reuse elsewhere
# }