Skip to contents

Thin wrapper over scoringRules that takes posterior samples from inlabru::generate() and returns four predictive scores per observation.

Usage

bru_score(fit, newdata, pred_formula, y_col, n_samples = 1000L, seed = NULL)

Arguments

fit

A fitted bru object. Must have been fit with control.compute = list(config = TRUE).

newdata

Data frame of covariate values for held-out observations.

pred_formula

Formula passed to inlabru::generate(). Must produce draws of Y on the outcome scale; see Details.

y_col

Name of the response column in newdata.

n_samples

Number of posterior samples (default 1000).

seed

Optional non-zero integer. If non-NULL, the scores are reproducible: the seed is used for R's RNG (the r*() draws in pred_formula) and for INLA's posterior sampler, which then runs single-threaded. The caller's RNG stream is restored afterwards.

Value

A tibble with one row per observation and columns crps, logs, se, ds.

Details

pred_formula must produce samples of Y — including observation-model stochasticity for discrete families. The caller writes the full distributional expression. Inside an inlabru generate() formula the predictor is evaluated once per posterior sample: latent-field symbols (Intercept, SPDE field values, ...) come in as scalars, and covariates come in as vectors over observations. So length(<covariate>) gives the observation count for the per-sample r*() call:

  • Poisson: ~ rpois(length(x), exp(Intercept + x))

  • Binomial: ~ rbinom(length(x), size = n_trials, prob = plogis(Intercept + x))

  • Gaussian: ~ rnorm(length(x), mean = Intercept + x, sd = 1 / sqrt(Precision_for_the_Gaussian_observations))

Hyperparameters are available in the formula under their standardised names (see inlabru::bru_standardise_names()), so the Gaussian observation noise is sampled jointly with the latent field.

This is the same contract inlabru::generate() already exposes — the package does not inject observation noise or dispatch on family. Users who want response-scale samples for a family not listed above write the appropriate random draw in the formula.

CRPS and the kernel log-score are strictly proper for continuous Y. For count / binomial Y the empirical CRPS on integer draws is still a reasonable proper score; scoringRules::logs_sample uses a kernel-density estimate which can be unstable on discrete supports — treat logs as approximate in that case.

Dawid-Sebastiani variance is floored at .Machine$double.eps to avoid division by zero when the sample variance collapses.