waic: Widely Applicable Information Criterion for INLAvaan Models

View source: R/method-waic.R

waicR Documentation

Widely Applicable Information Criterion for INLAvaan Models

Description

Computes the WAIC of a fitted INLAvaan model in closed form from the fit's Laplace summary – the same per-unit Taylor quantities behind loo(), with no posterior draws and no Monte Carlo error. Single-level models are scored per subject; two-level models are scored per cluster by default, matching the units used by loo(). For a two-level model type = "loso" instead scores the conditional (leave-one-unit-out) WAIC; see Details.

Usage

waic(x, ...)

## S3 method for class 'INLAvaan'
waic(
  x,
  type = c("auto", "loso", "loco"),
  units = NULL,
  second_order = TRUE,
  cores = NULL,
  verbose = FALSE,
  ...
)

## S3 method for class 'inlavaan_internal'
waic(
  x,
  type = c("auto", "loso", "loco"),
  units = NULL,
  second_order = TRUE,
  cores = NULL,
  verbose = FALSE,
  ...
)

## S3 method for class 'inlavaan_waic'
print(x, ...)

## S3 method for class 'inlavaan_waic'
summary(object, ...)

Arguments

x

A fitted INLAvaan object (or its inlavaan_internal list).

...

Not used.

type

Unit type: "auto" (default) resolves to per-subject for single-level models and per-cluster (marginal WAIC) for two-level models. "loso" on a two-level model scores the conditional (leave-one-unit-out) WAIC instead (with a warning; see Details); "loco" cannot be forced on a model without clusters.

units

Optional integer vector of unit indices to score; defaults to all units.

second_order

Logical; include the second-order (Hessian) terms (default TRUE). FALSE gives the first-order WAIC, which equals the first-order LOO exactly – and inherits its bias: a first-order score overstates the elpd by \tfrac12 p_D in the limit, so candidates of different dimension cannot be compared on it (see loo()).

cores

Number of cores for differentiating the unit scores. The default NULL runs serially; parallelism must be requested explicitly.

verbose

Logical; print progress (default FALSE).

object

A fitted INLAvaan object, or an inlavaan_waic result.

Details

Writing \ell_u(\theta) = \log p(y_u \mid \theta) and expanding it to second order about the posterior mode, with the posterior taken as N(\theta^*, \Omega), both WAIC terms are available in closed form: the pointwise log predictive density \mathrm{lpd}_u is the same Gaussian integral loo() computes, and the penalty is the polynomial

p_{\mathrm{waic},u} = \mathrm{Var}[\ell_u(\theta)] = s_u^\top \Omega\, s_u + \tfrac12 \mathrm{tr}\!\left[(H_u \Omega)^2\right],

with s_u and H_u the unit's score and Hessian. Then \mathrm{elpd}_{\mathrm{waic}} = \sum_u (\mathrm{lpd}_u - p_{\mathrm{waic},u}) and \mathrm{WAIC} = -2\, \mathrm{elpd}_{\mathrm{waic}}.

Existence. p_{\mathrm{waic},u} is a polynomial in the posterior moments, so unlike the lpd and log CPO integrals of loo() it is finite for every unit and carries no condition of its own. The second-order WAIC therefore exists exactly where its lpd term does: where \Omega^{-1} - H_u is positive definite, equivalently k_{\min} > -1 for the spectrum k of -\Omega H_u. The log CPO condition k_{\max} < 1 is irrelevant here, since the WAIC reads no case-deletion term: a unit whose deleted posterior is improper can still carry an exact second-order WAIC. Where the lpd term fails, every estimate is reported at first order over all units and warns – \mathrm{elpd}_{\mathrm{waic}} is a headline predictive score, and mixing two Taylor orders within one reported number is exactly what loo() refuses for \mathrm{elpd}_{\mathrm{loo}} (the mixed alternative is reserved for p_loo, a secondary diagnostic). That fallback is exact rather than merely lower-order: the identity \mathrm{lpd}^{(1)}_u - p^{(1)}_{\mathrm{waic},u} = \log \mathrm{CPO}^{(1)}_u holds pointwise, so the first-order WAIC is the first-order LOO score. No other threshold is applied: as in loo(), existence is the only condition the package acts on.

The same model restrictions as loo() apply, and so does the flavour rule: fits with fixed.x = TRUE are scored conditionally on the exogenous covariates, fits with fixed.x = FALSE jointly (see loo()).

Marginal vs conditional WAIC (two-level models). The default per-cluster scoring is the marginal WAIC, which corresponds to leave-one-cluster-out cross-validation – prediction for a new cluster. Setting type = "loso" scores the conditional WAIC, corresponding to leave-one-unit-out – prediction for a new observation within an observed cluster. The two answer different questions and are easily conflated (Merkle, Furr & Rabe-Hesketh, 2019); the per-cluster marginal is the usual model-comparison target, so it is the default, and type = "loso" warns. This matches loo(type = "loso") – the two read the same estimand off the same expansion.

When inlavaan()'s test includes "loo" or "waic" (e.g. test = "full"), the WAIC is derived at fit time from the same Taylor pass as the LOO at no extra cost and stored with the fit: waic(fit) then returns the stored result when called with default arguments, and fitmeasures() reports waic, p_waic, se_waic as part of "all" for free. Under the default test = "standard" nothing is stored and waic(fit) computes it on demand. If the loo package is attached it masks this generic, but dispatch on INLAvaan objects continues to work.

Value

An object of class inlavaan_waic: a list with per_unit (pointwise lpd, p_waic, elpd_waic, with the same unit/group identification as loo()), estimates (matrix with rows elpd_waic, p_waic, waic and columns Estimate, SE), type, flavour, n_units, n_groups, n_lpd_ok (units whose second-order lpd exists), second_order (whether it was requested) and use_second (whether it was used). summary() is an alias for print(): it prints the same output and returns the result invisibly.

See Also

loo(), fitmeasures()

Examples


HS.model <- "
  visual  =~ x1 + x2 + x3
  textual =~ x4 + x5 + x6
  speed   =~ x7 + x8 + x9
"
utils::data("HolzingerSwineford1939", package = "lavaan")
fit <- acfa(HS.model, HolzingerSwineford1939, meanstructure = TRUE)
waic(fit)



INLAvaan documentation built on Oct. 2, 2026, 1:07 a.m.