
Convergence and Approximation Diagnostics for INLAvaan Models
Source:R/method-diagnostics.R
diagnostics.RdExtract convergence and approximation-quality diagnostics from a fitted
INLAvaan model.
Usage
diagnostics(object, ...)
# S4 method for class 'INLAvaan'
diagnostics(object, type = c("global", "param"), ...)Arguments
- object
An object of class INLAvaan.
- ...
Currently unused.
- type
Character.
"global"(default) returns a named numeric vector of scalar diagnostics."param"returns a data frame with one row per free parameter containing per-parameter diagnostics.
Value
For type = "global", a named numeric vector (class
"diagnostics.INLAvaan"). For type = "param", a data frame
(class c("diagnostics.INLAvaan.param", "data.frame")).
Details
Global diagnostics (type = "global"):
nparNumber of free parameters.
nsampNumber of posterior samples drawn.
converged1 if the optimiser converged, 0 otherwise.
iterationsNumber of optimiser iterations.
grad_infL-infinity norm of the analytic gradient at the mode (max |grad|). Should be ~0 at convergence.
grad_inf_relRelative L-infinity norm of the analytic gradient (max |grad| / (|par| + 1e-6)).
grad_l2L2 (Euclidean) norm of the analytic gradient at the mode.
mode_shift_maxMaximum, across parameters, of the Newton step at the reported mode in posterior-SD units (max |\(\Sigma_\theta\) grad| / se). Unlike the raw gradient norms this is scale-free: it estimates how far the reported mode sits from the true posterior mode relative to the posterior uncertainty. Should be ~0 at convergence.
hess_condCondition number of the Hessian (precision matrix) computed from \(\Sigma_\theta\). Large values indicate near-singularity.
vb_kld_globalGlobal KL divergence from the VB mean correction (NA if VB correction was not applied).
vb_applied1 if VB correction was applied, 0 otherwise.
vb_shift_maxMaximum, across parameters, of the absolute VB correction in posterior-SD units (max |
vb_shift_sigma|). This is the quantity the fit-time check tests. NA if the VB correction was not applied.kld_maxMaximum per-parameter KL divergence from the VB correction.
kld_meanMean per-parameter KL divergence.
vb_mcse_maxMaximum, across parameters, of the estimated quadrature error of the VB shift, in posterior-SD units. See
vb_mcse_sigmabelow. NA undervb_method = "gauss_hermite".vb_mcse_meanMean estimated quadrature error of the VB shift, in posterior-SD units.
nmad_maxMaximum normalised max-absolute-deviation across marginals (skew-normal method only; NA otherwise).
nmad_meanMean NMAD across marginals.
scan_end_mass_maxMaximum, across parameters, of
scan_end_mass(see below). NA unless the skew-normal marginal method was used.
Per-parameter diagnostics (type = "param"):
A data frame with columns:
namesParameter name.
gradAnalytic gradient of the negative log-posterior at the mode. Should be ~0 at convergence.
grad_numNumerical (finite-difference) gradient at the mode. Should agree with
grad; large discrepancies indicate a bug in the analytic gradient.grad_diffDifference
grad_num - grad: should be ~0.grad_absAbsolute analytic gradient.
grad_relRelative analytic gradient |grad| / (|par| + 1e-6).
mode_shift_sigmaNewton step at the reported mode in posterior-SD units. Should be ~0 at convergence.
kldPer-parameter KL divergence from the VB correction.
vb_shiftVB correction shift (in original scale).
vb_shift_sigmaVB shift in units of posterior SD.
vb_mcse_sigmaEstimated quadrature error of the VB shift, in posterior-SD units. The shift is the solution of an integral evaluated by quasi-Monte Carlo over a finite node set, so it carries an integration error of its own. This estimates that error by splitting the node set in half and taking half the disagreement between the two half-set solutions. Read it as an error bar on
vb_shift_sigma: a value of 0.05 means the reported posterior mean of that parameter could move by roughly that much, in SD units, purely from the choice of node set. It runs conservative, because the two halves are negatively correlated and quasi-Monte Carlo error falls faster than root-n. It is exactly zero for parameters whose shift is pinned by the saturated-means fast path, since no quadrature is used there. It is NA for every parameter undervb_method = "gauss_hermite", whose rule is deterministic.nmadNormalised max-absolute-deviation of the skew-normal fit (NA when not using the skewnorm method).
alphaShape parameter of the fitted skew-normal marginal, on the unconstrained scale. Zero is a Gaussian marginal, and the sign gives the direction of the skew (NA when not using the skewnorm method).
scan_end_massMass the fitted marginal puts outside the window that was scanned to fit it, \(F(\hat\theta_j - 4 s_j) + 1 - F(\hat\theta_j + 4 s_j)\), where \(F\) is the fitted skew-normal distribution function, \(\hat\theta_j\) the posterior mode and \(s_j\) the Laplace posterior SD. The marginal is fitted inside that window only, so mass outside it is extrapolation, and when this is large the 2.5\ 97.5\ gives \(2\Phi(-4)\) = 6.3e-05, and healthy fits sit between 1e-03 and 1e-02 (NA when not using the skewnorm method).
Fit-time warnings: inlavaan() runs these checks once at the end
of every fit and emits a single consolidated warning (condition class
"inlavaan_diagnostics_warning") when any of them looks off:
the optimiser did not converge;
mode_shift_maxabove 0.1 posterior SDs;any marginal with
nmadabove 0.1;any marginal with
scan_end_massabove 0.05;vb_shift_maxabove 1 posterior SD;hess_condabove 1e8.
Three of these checks have calibration behind them. Over 1,046 simulated
fits with MCMC references, the Spearman correlation with the worst-case
posterior-mean discrepancy was 0.64 for the VB shift in SD units, 0.59 for
the scan-endpoint mass and 0.48 for the NMAD. The convergence, mode-shift
and condition-number checks are rules of thumb. Every number above is a
package default, chosen so that a healthy fit stays silent, and not a
calibrated cut-off: a tripped check is a prompt to look again, and silence
is not a certificate of accuracy. Silence the check with
suppressWarnings(), or selectively by handling the condition class.
Examples
# \donttest{
HS.model <- "
visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9
"
utils::data("HolzingerSwineford1939", package = "lavaan")
fit <- acfa(HS.model, HolzingerSwineford1939, std.lv = TRUE, nsamp = 100,
test = "none", verbose = FALSE)
# Global convergence summary
diagnostics(fit)
#> npar nsamp converged iterations
#> 21 100 1 66
#> grad_inf grad_inf_rel grad_l2 mode_shift_max
#> 2.02e-03 4.50e-03 3.01e-03 1.80e-04
#> hess_cond vb_applied vb_shift_max vb_kld_global
#> 4.51e+01 1 0.1926 0.0721
#> kld_max kld_mean vb_mcse_max vb_mcse_mean
#> 0.0186 0.0057 0.1330 0.0532
#> nmad_max nmad_mean scan_end_mass_max
#> 0.0229 0.0060 1.03e-03
# Per-parameter table
diagnostics(fit, type = "param")
#> names grad grad_num grad_diff grad_abs grad_rel mode_shift_sigma
#> 1 visual=~x1 1e-04 1e-04 0 1e-04 0.0001 1e-04
#> 2 visual=~x2 0e+00 0e+00 0 0e+00 0.0000 1e-04
#> 3 visual=~x3 3e-04 3e-04 0 3e-04 0.0004 1e-04
#> 4 textual=~x4 9e-04 9e-04 0 9e-04 0.0009 0e+00
#> 5 textual=~x5 -2e-03 -2e-03 0 2e-03 0.0018 1e-04
#> 6 textual=~x6 1e-03 1e-03 0 1e-03 0.0011 0e+00
#> 7 speed=~x7 1e-04 1e-04 0 1e-04 0.0001 0e+00
#> 8 speed=~x8 0e+00 0e+00 0 0e+00 0.0000 0e+00
#> 9 speed=~x9 1e-04 1e-04 0 1e-04 0.0001 0e+00
#> 10 x1~~x1 6e-04 6e-04 0 6e-04 0.0011 2e-04
#> 11 x2~~x2 1e-04 1e-04 0 1e-04 0.0010 0e+00
#> 12 x3~~x3 -7e-04 -7e-04 0 7e-04 0.0041 1e-04
#> 13 x4~~x4 4e-04 4e-04 0 4e-04 0.0004 0e+00
#> 14 x5~~x5 0e+00 0e+00 0 0e+00 0.0000 0e+00
#> 15 x6~~x6 5e-04 5e-04 0 5e-04 0.0005 0e+00
#> 16 x7~~x7 9e-04 9e-04 0 9e-04 0.0045 1e-04
#> 17 x8~~x8 -5e-04 -5e-04 0 5e-04 0.0007 0e+00
#> 18 x9~~x9 2e-04 2e-04 0 2e-04 0.0004 0e+00
#> 19 visual~~textual -2e-04 -2e-04 0 2e-04 0.0004 0e+00
#> 20 visual~~speed 7e-04 7e-04 0 7e-04 0.0014 1e-04
#> 21 textual~~speed 2e-04 2e-04 0 2e-04 0.0009 0e+00
#> kld vb_shift vb_shift_sigma vb_mcse_sigma nmad alpha scan_end_mass
#> 1 0.0045 0.0079 0.0947 0.0675 0.0094 0.5392 6.17e-05
#> 2 0.0010 0.0037 0.0454 0.0357 0.0004 0.5437 7.39e-05
#> 3 0.0040 0.0070 0.0900 0.0940 0.0024 0.6498 8.64e-05
#> 4 0.0141 0.0095 0.1681 0.0039 0.0032 0.9488 2.28e-04
#> 5 0.0161 0.0113 0.1797 0.0270 0.0033 0.9527 2.33e-04
#> 6 0.0147 0.0092 0.1714 0.0026 0.0032 0.9433 2.17e-04
#> 7 0.0022 -0.0049 -0.0669 0.0753 0.0027 -0.8595 1.26e-04
#> 8 0.0001 -0.0008 -0.0102 0.1330 0.0141 -0.7907 6.02e-05
#> 9 0.0186 0.0148 0.1926 0.0503 0.0160 0.8780 1.26e-04
#> 10 0.0011 -0.0103 -0.0477 0.1157 0.0112 -2.2918 6.26e-04
#> 11 0.0018 0.0056 0.0604 0.0516 0.0014 0.3314 7.18e-05
#> 12 0.0001 0.0017 0.0152 0.0135 0.0026 -1.1178 1.54e-04
#> 13 0.0005 0.0041 0.0320 0.0156 0.0033 -1.0977 1.49e-04
#> 14 0.0003 0.0030 0.0231 0.0290 0.0031 -1.0794 1.47e-04
#> 15 0.0016 0.0069 0.0568 0.0119 0.0023 -0.9738 1.14e-04
#> 16 0.0170 0.0201 0.1846 0.0759 0.0036 0.5696 1.05e-04
#> 17 0.0035 0.0156 0.0835 0.0460 0.0229 -1.3189 6.17e-05
#> 18 0.0101 -0.0223 -0.1421 0.0840 0.0067 -2.1898 1.03e-03
#> 19 0.0007 -0.0031 -0.0383 0.0534 0.0010 0.5158 6.55e-05
#> 20 0.0051 0.0110 0.1009 0.0644 0.0111 1.2491 2.34e-04
#> 21 0.0027 0.0057 0.0741 0.0669 0.0026 0.5496 7.32e-05
# }