The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
gdpar_eb()
end-to-end, four path regimes, EB-vs-FB comparison and troubleshooting
(Sub-phase 8.6.E)gdpar_eb() call (K = 1 + p = 1)gdpar_compare_eb_fb()This is an operational recipe. It walks you through
gdpar_eb() end to end across the four path regimes
canonized in Sub-phase 8.6 of gdpar:
| Regime | \(K\) | \(p\) | Stan template pair |
|---|---|---|---|
| Base | 1 | 1 | amm_eb_marginal.stan +
amm_eb_conditional.stan |
| Path A | 1 | >1 | amm_eb_marginal_multi.stan +
amm_eb_conditional_multi.stan |
| Path B | >1 | 1 | amm_eb_marginal_K.stan +
amm_eb_conditional_K.stan |
| Path C | >1 | >1 | amm_eb_marginal_KxP.stan +
amm_eb_conditional_KxP.stan |
It then shows how to compare an EB fit against a Fully-Bayes (FB) fit
on the same data via gdpar_compare_eb_fb(), how to read the
numerical diagnostics that surface when the marginal Hessian is poorly
conditioned, and when to give up on EB and fall back to FB.
The theoretical canonization of EB-vs-FB — the asymptotic equivalence
(Theorem 7A and its multivariate extension Theorem 7A*), the
higher-order coverage discrepancy (Proposition 7B scalar / 7B* matricial
/ 7B* tensorial), the finite-sample compound decision bound (Theorem 7C
/ 7C* compound multi-slot), and the four discrepancy conditions of
Proposition 7D — lives in the canonical vignettes
vignette("v07_eb_vs_fb") (scalar) and
vignette("v07b_eb_multivariate") (multivariate extension).
Read those if you want to know why a given choice was made;
read this one if you want to do it.
The chunks below default to eval = FALSE because they
compile Stan models and take several minutes per fit; re-enable
evaluation on a per-chunk basis or globally via
knitr::opts_chunk$set(eval = TRUE) if you want to reproduce
the runs locally.
library(gdpar)
# These two are Suggests; gdpar_eb() and gdpar_compare_eb_fb() require
# them at runtime.
library(cmdstanr)
library(posterior)We will work with a synthetic dataset of size n = 150 on
a single continuous outcome with one covariate, then enrich it to
multivariate and multi-slot variants as we walk through the four
regimes.
set.seed(20260526L)
n <- 150L
df <- data.frame(x = stats::rnorm(n))
df$y_scalar <- 1.0 + 0.4 * df$x + stats::rnorm(n, sd = 0.3)
# Multivariate (p = 2) outcome for Path A.
df$y_p2 <- cbind(
1.0 + 0.4 * df$x + stats::rnorm(n, sd = 0.3),
-0.5 + 0.2 * df$x + stats::rnorm(n, sd = 0.4)
)
# Same dataset is fine for Path B (K > 1, p = 1) and Path C (K > 1,
# p > 1) by reusing y_scalar / y_p2 with a multi-slot family below.gdpar_eb() call (K = 1 + p =
1)The base regime mirrors the canonical gdpar() signature;
the only new arguments are eb_correction = TRUE (default;
applies the Proposition 7B scalar inflation to the conditional credible
intervals) and laplace_control = list(...) (controls the
multi-start Laplace maximizer of v07 Section 11.1 step (i)).
fit_eb <- gdpar_eb(
formula = y_scalar ~ x,
family = gdpar_family("gaussian"),
amm = amm_spec(a = ~ x),
data = df,
iter_warmup = 500L,
iter_sampling = 500L,
chains = 2L,
refresh = 0L,
seed = 1L,
laplace_control = list(multi_start_M = 5L)
)
print(fit_eb)The output reports the EB plug-in point estimate \(\widehat\theta_{\text{ref}}^{\text{EB}}\)
(from the marginal Laplace), its marginal standard error from the
Laplace covariance, the marginal Hessian condition number \(\kappa(H)\), the multi-start dispersion
across the multi_start_M = 5 independent inits, and the
conditional HMC convergence diagnostics (\(\widehat R\), ESS, divergences).
summary(fit_eb) returns a tidy table of EB credible
intervals with the Proposition 7B scalar inflation applied:
For a \(p\)-dimensional outcome, the
amm spec uses dimwise() (or a plain list of
length \(p\)) to declare the
per-coordinate components, and the family is promoted to a
gdpar_family_multi of dimension \(p\). The Stan template pair
amm_eb_marginal_multi.stan +
amm_eb_conditional_multi.stan (canonized in Sub-phase 8.6.C
under decision D34) is dispatched automatically:
fit_eb_A <- gdpar_eb(
formula = y_p2 ~ x,
family = gdpar_family_multi("gaussian", p = 2L),
amm = amm_spec(p = 2L, dims = dimwise(a = ~ x)),
data = df,
iter_warmup = 500L,
iter_sampling = 500L,
chains = 2L,
refresh = 0L,
seed = 2L
)
print(fit_eb_A)The corresponding correction is matricial, \(C^*_{g,\alpha} \in \mathbb{R}^{p\times p}\) (Proposition 7B* of v07b Section 5.1). It reduces algebraically to the scalar Proposition 7B at \(p = 1\), so the upgrade from base to Path A is transparent.
For a multi-slot distributional regression (e.g. modelling both
mu and sigma of a Gaussian K=2, or
mu and phi of a Negative Binomial K=2), the
amm input is either a named list of amm_spec (one per slot)
or a gdpar_formula_set via gdpar_bf(...). The
Stan template pair amm_eb_marginal_K.stan +
amm_eb_conditional_K.stan is dispatched automatically:
fs <- gdpar_bf(y_scalar ~ a(x), sigma ~ a(x))
fit_eb_B <- gdpar_eb(
formula = fs,
family = gdpar_family("gaussian"),
data = df,
iter_warmup = 500L,
iter_sampling = 500L,
chains = 2L,
refresh = 0L,
seed = 3L,
skip_id_check = TRUE
)
print(fit_eb_B)Coverage of stan_ids per Sub-phase 8.6.C decision D33 (relaxed):
{1, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13} — Gaussian, Negative
Binomial, Beta, Gamma, Lognormal-loc-scale, Student-t, Tweedie, ZIP,
ZINB, Hurdle-Poisson, Hurdle-NB.
Path C, canonized in Sub-phase 8.6.D under decision D36 = (alpha) +
D37 = (i) + D38’’ = (h), composes Path A coordinate-wise factorization
with Path B multi-parametric K-slot semantics: a single outcome
matrix-column y[n, p] is shared across the K distributional
slots, each carrying its own per-coordinate linear predictor.
The initial 8.6.D iteration restricts Path C to
family$stan_id %in% c(1, 3) (Gaussian K=2, NB K=2) under
decision D40’ to avoid the numerical caveat of Section 6.1 of the
opening handoff (HMC condicional bajo plug-in EB cerca del borde de
soporte logit/log links + warmup corto). Beta / Gamma / Lognormal /
Student-t / Tweedie / mixtures are deferred to a later iteration.
y_p2_int <- matrix(
rnbinom(n * 2L, size = 5, mu = exp(0.5 + 0.2 * df$x)),
n, 2L
)
df$y_p2_int <- y_p2_int
fit_eb_C <- gdpar_eb(
formula = y_p2_int ~ x,
family = gdpar_family("neg_binomial_2"),
amm = list(
mu = amm_spec(p = 2L, dims = dimwise(a = ~ x)),
phi = amm_spec(p = 2L, dims = dimwise(a = ~ x))
),
data = df,
iter_warmup = 500L,
iter_sampling = 500L,
chains = 2L,
refresh = 0L,
seed = 4L,
skip_id_check = TRUE
)
print(fit_eb_C)The fit object carries new Path C-specific slots:
theta_ref_kp_hat: 3D numeric array of shape
[J_groups, K, p].theta_ref_kp_se: same shape; per-coordinate marginal
standard errors derived from each slot’s Laplace covariance block.theta_ref_kp_cov_per_slot: named list of K
matrices each p × p; the per-slot blocks of the joint
Laplace covariance after the block-diagonal extraction of decision D43 =
(a).correction_tensor_constant: 3D array of shape
[K, p, p] with the Proposition 7B* tensor correction of
decision D37 = (i).correction_tensor_dispositions: named character vector
reporting whether each slot’s correction was applied
("ok"), "non_finite", "non_psd",
"missing", or "disabled".Every gdpar_eb_fit carries a
diagnostics_numerical slot with four entries derived from
the multi-start Laplace strategy of Charter Section 2.8:
kappa (base regime / Path A / Path B) or
kappa_per_slot (Path C): the condition number of the
marginal Hessian at the chosen MAP. The guard
laplace_control$kappa_threshold (default 1e10)
aborts the fit with gdpar_eb_numerical_error when exceeded.
A kappa between 1e6 and 1e9 is a
warning sign; consider tightening the prior on theta_ref or
moving the anchor closer to the data via
anchor = "empirical_y".
lm_perturbation: the Levenberg-Marquardt ridge
actually added to the marginal covariance when the bare Hessian was
singular or non-PSD. A non-zero value means the Laplace approximation
needed numerical stabilization; the result is still valid but the
effective sample size for the EB anchor is smaller than the nominal
Laplace draws would suggest.
multi_start_dispersion: standard deviation of the
log marginal across the multi_start_M independent inits,
normalized by the absolute mean. A value above 0.05
triggers a diagnostic warning because it suggests multi-modality of the
marginal likelihood (open question O5*-EBFB of v07b Section 9.5).
Consider raising multi_start_M from the default 5 to 10–20
to stress-test the optimum.
marginal_log_lik_history: the per-init log marginal
achieved by each optimize() call. Useful for forensics when
the dispersion is large.
gdpar_compare_eb_fb()The companion function gdpar_compare_eb_fb() (canonized
in Sub-phase 8.6.E) takes a gdpar_eb_fit and a
gdpar_fit fitted on the same dataset and reports three
operational diagnostics of the EB-vs-FB theory of v07:
fit_fb <- gdpar(
formula = y_scalar ~ x,
family = gdpar_family("gaussian"),
amm = amm_spec(a = ~ x),
data = df,
iter_warmup = 500L,
iter_sampling = 500L,
chains = 2L,
refresh = 0L,
seed = 1L
)
cmp <- gdpar_compare_eb_fb(fit_eb, fit_fb, level = 0.95,
tv_bins = 30L)
print(cmp)
summary(cmp)The output carries three tables:
theta_diff_table: per-anchor cell comparison of
\(\widehat\theta_{\text{ref}}^{\text{EB}}\)
and the FB posterior mean \(E_{\text{FB}}[\theta_{\text{ref}}]\), with
the difference and the difference normalized by the FB standard error.
Under the standing hypotheses of v07 Section 4 (EB-MARG-ID +
PRIOR-FB-WEAK + HIER-COMPLEX), Theorem 7A predicts diff_rel
close to zero up to \(O(n^{-1/2})\).
tv_table: marginal empirical total variation
distance per common \(\xi\) parameter,
computed via histogram plug-in over the shared support. Under Theorem
7A, marginal TV \(\to 0\) in
probability as \(n \to \infty\). A
persistent large TV across many parameters suggests one of the
discrepancy conditions of Proposition 7D (multi-modality of the marginal
likelihood, near-singular Fisher information, informative prior, deep
hierarchy).
coverage_table: per anchor cell, the EB credible
interval width (with inflation applied when
eb_correction = TRUE), the FB credible interval width, and
the ratio width_eb / width_fb. This operationally verifies
the \(O(n^{-1})\) under-cover
prediction of Proposition 7B (and its matricial / tensorial extensions).
A ratio systematically below 1 confirms the EB under-cover; a ratio
above 1 after correction suggests the inflation is over-correcting,
which is acceptable in finite samples and consistent with the asymptotic
guarantee.
gdpar_eb_numerical_error: kappa = ...The marginal Hessian is too ill-conditioned for Laplace to be reliable. Options:
theta_ref via a stronger
gdpar_prior(theta_ref = "normal(0, 0.5)").anchor = "empirical_y".laplace_control$multi_start_M and rerun (the
per-init seed offset will sample different unconstrained-space
inits).gdpar() (the most reliable option
when the marginal likelihood is genuinely flat).gdpar_unsupported_feature_error on Path CThe initial 8.6.D iteration restricts Path C to
family$stan_id %in% c(1, 3) (Gaussian K=2, NB K=2) per
decision D40’. For other distributional families under \(K > 1 \wedge p > 1\), fall back to FB
via gdpar() or split the multivariate outcome into \(p\) separate Path B fits as a
workaround.
A multi_start_dispersion above 0.05 suggests
multi-modality of the marginal likelihood (open question O5*-EBFB of
v07b Section 9.5). The result returned by gdpar_eb() is the
mode with the highest log marginal across the multi_start_M
inits, which may differ from the mode picked by a single run.
Options:
multi_start_M from the default 5 to 10–20.theta_ref to break the
multi-modality.logit-strict linksPath B with strict \((0, 1)\)
inverse-link families (Beta, Bernoulli) can exhibit conditional HMC
instability when the EB plug-in anchor falls near the support boundary
and the HMC warmup is short. The caveat is documented in the closure of
Sub-phase 8.6.C (HANDOFF_SUBFASE_8_6_C_CIERRE.md Section
3.3). Workarounds:
iter_warmup to 1000 or more.sigma_a_k (the HMC has fewer
chances to sample large a_coef_k values that saturate the
logit).anchor = "prior_median" or an explicit numeric
anchor that keeps the EB plug-in in the interior of the support.A representative end-to-end Path C smoke (Gaussian K=2 + p=2, \(n = 80\),
iter_warmup = iter_sampling = 200L,
chains = 2L) takes approximately 50 seconds on contemporary
hardware (amm_eb_marginal_KxP.stan and
amm_eb_conditional_KxP.stan each compile once and are
cached by cmdstanr). If the smoke takes significantly longer or aborts
with gdpar_eb_numerical_error, the geometry of the K × p
marginal is likely the culprit; check kappa_per_slot and
the slot dispositions returned by the correction tensor.
vignette("v07_eb_vs_fb").vignette("v07b_eb_multivariate").vignette("v08_amm_for_cate_ite_positioning") and the
implementation vignettes
v08b_cate_ite_bridge_implementation and
v08c_meta_learner_comparison.gdpar_dependence_diagnostic()
(lag-1 autocorrelation, Durbin-Watson, Ljung-Box) or its spatial sibling
gdpar_spatial_dependence_diagnostic() (Moran’s I), and
obtain dependence-robust standard errors and percentile intervals with
gdpar_dependence_robust() (temporal block bootstrap) or
gdpar_spatial_dependence_robust() (spatial block
bootstrap), Block 9, Axis 2. This makes the uncertainty robust
to dependence; gdpar does not model the dependence. The full
recipe is in vignette("vop09_dependence_robust").The canonical theoretical references for EB-vs-FB in the AMM are
Petrone, Rousseau, and Scricciolo (2014) and Rousseau and Szabo (2017)
for the asymptotic equivalence and merging results; Carlin and Gelfand
(1990) for the higher-order coverage discrepancy and the inflation
correction; and Robbins (1956) / Efron (2010) for the compound decision
framework. Full bibliographic details are in
vignette("v07_eb_vs_fb") Section “References Cited in This
Block”.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.