| Title: | Synthesised Fourth Opinion for Bayesian Triangulation |
|---|---|
| Description: | Synthesises one coherent, independent predictive opinion for a Bayesian model from a curated battery of known and underutilised inference methods, or abstains when no diversity gain exists. Built to serve as a fourth, synthesised witness alongside an independent panel of inference engines: it stacks over model-structure and method diversity in predictive space (leave-one-out stacking, PSIS-gated) on an axis orthogonal to the engine axis, never averaging the engines. Predictive opinions are exchanged through an ArviZ-style 'DataTree' 'NetCDF' interchange so no live 'Python' is required at read time. Abstention is a first-class outcome. |
| Authors: | Max Moldovan [aut, cre] (ORCID: <https://orcid.org/0000-0001-9680-8474>) |
| Maintainer: | Max Moldovan <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.3.1.9000 |
| Built: | 2026-10-16 01:36:21 UTC |
| Source: | https://github.com/max578/koine |
An abstention records why koine declined to issue a fourth opinion, at what scope, and which lenses (if any) were dropped on the way. It is returned as a normal value and surfaces as "abstained" in the downstream triangulation.
abstention( reason, scope = c("synthesis", "lens"), detail, lenses_dropped = NULL )abstention( reason, scope = c("synthesis", "lens"), detail, lenses_dropped = NULL )
reason |
Single string from the closed taxonomy (Stage-0 SS8). |
scope |
Either |
detail |
Human-readable explanation. Required — an abstention with no detail is itself misleading (I1). |
lenses_dropped |
Optional list of |
An object of class koine_abstention.
abstention("no_diverse_battery", detail = "only 1 opinion lens resolved")abstention("no_diverse_battery", detail = "only 1 opinion lens resolved")
family_spec
Wraps a base-R / brms family object (which exposes linkinv but no
pointwise log-likelihood) with the loglik_pointwise and rng functions
koine needs. Supported families in this build are gaussian, binomial
(and bernoulli, a binomial with one trial), and poisson. An unsupported
family raises error.family_not_evaluable, never a silent approximation.
as_family_spec(family, trials = NULL)as_family_spec(family, trials = NULL)
family |
A base-R |
trials |
Optional length- |
A koine_family_spec.
fs <- as_family_spec(gaussian()) fs$loglik_pointwise(y = c(0, 1), eta = c(0, 1), aux = list(sigma = 1))fs <- as_family_spec(gaussian()) fs$loglik_pointwise(y = c(0, 1), eta = c(0, 1), aux = list(sigma = 1))
For each contributed opinion fit, takes the native pointwise log-likelihood
if present, else reconstructs the S x N matrix by evaluating the family's
loglik_pointwise at each draw's linear predictor. Columns are reindexed to
the pass's canonical obs_id order (A3).
assemble_loglik(fb_fits, pass)assemble_loglik(fb_fits, pass)
fb_fits |
A list of |
pass |
The originating |
A named list (by lens method) of list(ll =, chain_id =), where ll
is an S x N matrix over the canonical observation axis.
set.seed(1) d <- data.frame(y = rnorm(40), x = rnorm(40)) pass <- koine_pass(y ~ x, d, gaussian()) fit <- fit_dram(pass, n_iter = 600L, n_burn = 300L, n_chains = 2L) ll <- assemble_loglik(list(fit), pass) dim(ll[[1]]$ll)set.seed(1) d <- data.frame(y = rnorm(40), x = rnorm(40)) pass <- koine_pass(y ~ x, d, gaussian()) fit <- fit_dram(pass, n_iter = 600L, n_burn = 300L, n_chains = 2L) ll <- assemble_loglik(list(fit), pass) dim(ll[[1]]$ll)
Per-lens log marginal likelihood (model evidence) via bridge sampling
(Meng & Wong 1996; Gronau et al. 2017), as a Bayes-factor cross-check on the
battery. This axis has role = "diagnostic": it is a scalar per lens and
never enters stacking (the synthesis assembly excludes diagnostic-role
output). The estimate is prior-conditional — it is computed under
koine's canonical reference prior (coefficients N(0, beta_prior_sd);
Gaussian dispersion via a log-sigma N(0, log_sigma_prior_sd) prior), and
Bayes factors are sensitive to that prior, so the result is flagged
accordingly. Lenses that fit an alternative model structure (a different
likelihood, e.g. robust-t) are excluded from the cross-check: their evidence
is not comparable on the shared prior.
evidence_axis( fb_fits, pass, beta_prior_sd = 5, log_sigma_prior_sd = 2, log_tau_prior_sd = 2 )evidence_axis( fb_fits, pass, beta_prior_sd = 5, log_sigma_prior_sd = 2, log_tau_prior_sd = 2 )
fb_fits |
A list of contributed |
pass |
The originating |
beta_prior_sd |
Prior SD on the coefficients (default 5, matching the lenses' weakly-informative default). |
log_sigma_prior_sd |
Prior SD on log-sigma for Gaussian families (default 2). |
log_tau_prior_sd |
Prior SD on log-tau for mixed-model passes (default 2, matching the RE lenses' weakly-informative default). |
Requires the suggested bridgesampling package; absent it, returns a structured unavailable record rather than failing (I1).
A list with available (logical), prior_conditional (always TRUE),
and, when available, evidence (a data frame of lens_id, log_ml,
log_ml_se) plus note. role is documented as "diagnostic".
set.seed(1) d <- data.frame(y = rnorm(40), x = rnorm(40)) pass <- koine_pass(y ~ x, d, gaussian()) fit <- fit_dram(pass, n_iter = 800L, n_burn = 400L, n_chains = 2L) evidence_axis(list(fit), pass)$evidenceset.seed(1) d <- data.frame(y = rnorm(40), x = rnorm(40)) pass <- koine_pass(y ~ x, d, gaussian()) fit <- fit_dram(pass, n_iter = 800L, n_burn = 400L, n_chains = 2L) evidence_axis(list(fit), pass)$evidence
A family_spec exposes, as pure functions, the pieces koine needs to compute
a pointwise log-likelihood and a posterior-predictive draw for any lens that
does not emit them natively. This low-level constructor is normally reached
through as_family_spec(), which adapts a base-R family object.
family_spec( name, link, linkinv, loglik_pointwise, rng, support_check, aux_params = character(0), dlp_deta = NULL, d2lp_deta2 = NULL )family_spec( name, link, linkinv, loglik_pointwise, rng, support_check, aux_params = character(0), dlp_deta = NULL, d2lp_deta2 = NULL )
name |
Family name, e.g. |
link |
Link name, e.g. |
linkinv |
Function mapping the linear predictor |
loglik_pointwise |
Function |
rng |
Function |
support_check |
Function |
aux_params |
Character vector naming the auxiliary parameters (e.g.
|
dlp_deta |
Optional function |
d2lp_deta2 |
Optional function |
An object of class koine_family_spec.
# normally reached through as_family_spec(); the low-level constructor: fs <- family_spec( name = "gaussian", link = "identity", linkinv = function(eta) eta, loglik_pointwise = function(y, eta, aux) { stats::dnorm(y, eta, aux$sigma, log = TRUE) }, rng = function(eta, aux) stats::rnorm(length(eta), eta, aux$sigma), support_check = function(y) all(is.finite(y)), aux_params = "sigma") fs$loglik_pointwise(c(0, 1), c(0, 1), list(sigma = 1))# normally reached through as_family_spec(); the low-level constructor: fs <- family_spec( name = "gaussian", link = "identity", linkinv = function(eta) eta, loglik_pointwise = function(y, eta, aux) { stats::dnorm(y, eta, aux$sigma, log = TRUE) }, rng = function(eta, aux) stats::rnorm(length(eta), eta, aux$sigma), support_check = function(y) all(is.finite(y)), aux_params = "sigma") fs$loglik_pointwise(c(0, 1), c(0, 1), list(sigma = 1))
fb_fit
Construct an fb_fit
fb_fit( draws, provenance, exactness = c("exact", "approximate", "resampled"), sample_stats = NULL, log_likelihood = NULL, posterior_predictive = NULL, diagnostics = NULL, status = c("contributed", "abstained"), abstention = NULL )fb_fit( draws, provenance, exactness = c("exact", "approximate", "resampled"), sample_stats = NULL, log_likelihood = NULL, posterior_predictive = NULL, diagnostics = NULL, status = c("contributed", "abstained"), abstention = NULL )
draws |
A |
provenance |
A |
exactness |
|
sample_stats |
Optional |
log_likelihood |
Optional |
posterior_predictive |
Optional predictive draws array. |
diagnostics |
Optional named list of convergence diagnostics; if |
status |
|
abstention |
An |
A validated object of class koine_fb_fit.
set.seed(1) draws <- posterior::as_draws_array( array(rnorm(8L), dim = c(2L, 2L, 2L), dimnames = list(NULL, NULL, c("b_(Intercept)", "b_x")))) prov <- provenance_record( method = "demo", method_version = "0", impl_language = "R", seed = 1L, derived_seed = 1L, ir_hash = "h", maturity_tier = "reference-validated", independence_key = list(family = "random_walk", kernel = "demo"), role = "opinion", exactness = "exact") fb_fit(draws = draws, provenance = prov, exactness = "exact", status = "contributed")set.seed(1) draws <- posterior::as_draws_array( array(rnorm(8L), dim = c(2L, 2L, 2L), dimnames = list(NULL, NULL, c("b_(Intercept)", "b_x")))) prov <- provenance_record( method = "demo", method_version = "0", impl_language = "R", seed = 1L, derived_seed = 1L, ir_hash = "h", maturity_tier = "reference-validated", independence_key = list(family = "random_walk", kernel = "demo"), role = "opinion", exactness = "exact") fb_fit(draws = draws, provenance = prov, exactness = "exact", status = "contributed")
fb_fit's drawsComputes split-Rhat and bulk/tail ESS from the posterior draws via
posterior::, engine-agnostically. Never fabricates an HMC-only statistic
(I1, F2): for non-HMC lenses sample_stats stays NULL and only the
draws-derived diagnostics are returned.
fb_fit_diagnostics(x)fb_fit_diagnostics(x)
x |
A contributed |
A named list with rhat, ess_bulk, ess_tail (per variable).
set.seed(1) draws <- posterior::as_draws_array( array(rnorm(80L), dim = c(20L, 2L, 2L), dimnames = list(NULL, NULL, c("b_(Intercept)", "b_x")))) prov <- provenance_record( method = "demo", method_version = "0", impl_language = "R", seed = 1L, derived_seed = 1L, ir_hash = "h", maturity_tier = "reference-validated", independence_key = list(family = "random_walk", kernel = "demo"), role = "opinion", exactness = "exact") fit <- fb_fit(draws = draws, provenance = prov, exactness = "exact", status = "contributed") fb_fit_diagnostics(fit)set.seed(1) draws <- posterior::as_draws_array( array(rnorm(80L), dim = c(20L, 2L, 2L), dimnames = list(NULL, NULL, c("b_(Intercept)", "b_x")))) prov <- provenance_record( method = "demo", method_version = "0", impl_language = "R", seed = 1L, derived_seed = 1L, ir_hash = "h", maturity_tier = "reference-validated", independence_key = list(family = "random_walk", kernel = "demo"), role = "opinion", exactness = "exact") fit <- fb_fit(draws = draws, provenance = prov, exactness = "exact", status = "contributed") fb_fit_diagnostics(fit)
Runs delayed-rejection adaptive Metropolis on the pass's GLM and returns an
fb_fit(). The fit carries equal-weight posterior draws and a complete
provenance record; the pointwise log-likelihood is left NULL for
assemble_loglik() to compute via the family spec (F3).
fit_dram(pass, lens_spec = NULL, n_iter = 4000L, n_burn = 2000L, n_chains = 4L)fit_dram(pass, lens_spec = NULL, n_iter = 4000L, n_burn = 2000L, n_chains = 4L)
pass |
A |
lens_spec |
The lens's registry record (for provenance + the derived
seed); defaults to the registry's |
n_iter |
Iterations per chain. |
n_burn |
Burn-in iterations discarded per chain. |
n_chains |
Number of chains. |
A koine_fb_fit.
set.seed(1) d <- data.frame(x = rnorm(40)) d$y <- 1 + 0.8 * d$x + rnorm(40) pass <- koine_pass(y ~ x, d, gaussian()) fit_dram(pass, n_iter = 800L, n_burn = 400L, n_chains = 2L)set.seed(1) d <- data.frame(x = rnorm(40)) d$y <- 1 + 0.8 * d$x + rnorm(40) pass <- koine_pass(y ~ x, d, gaussian()) fit_dram(pass, n_iter = 800L, n_burn = 400L, n_chains = 2L)
Runs BayesianTools' DREAMzs sampler on the pass's GLM and returns an
fb_fit(). Supports the Gaussian, Binomial (logit), and Poisson (log)
families; for any other family/link it returns a lens-scope abstention().
fit_dream(pass, lens_spec = NULL, n_iter = 15000L, burn_frac = 0.5)fit_dream(pass, lens_spec = NULL, n_iter = 15000L, burn_frac = 0.5)
pass |
A |
lens_spec |
The lens's registry record; defaults to the |
n_iter |
Total DREAM iterations (model evaluations across the ensemble). |
burn_frac |
Fraction of each recorded chain discarded as burn-in. |
A koine_fb_fit, or a koine_abstention.
ter Braak & Vrugt (2008). Differential Evolution Markov Chain with snooker updater and fewer chains. Stat. Comput. 18:435-446.
set.seed(1) d <- data.frame(x = rnorm(40)) d$y <- 1 + 0.8 * d$x + rnorm(40) pass <- koine_pass(y ~ x, d, gaussian()) fit_dream(pass, n_iter = 6000L)set.seed(1) d <- data.frame(x = rnorm(40)) d$y <- 1 + 0.8 * d$x + rnorm(40) pass <- koine_pass(y ~ x, d, gaussian()) fit_dream(pass, n_iter = 6000L)
Runs the koine-authored No-U-Turn Sampler on the random-effects marginal
model — the random intercepts integrated out, exactly for the Gaussian LMM
and by adaptive Gauss-Hermite quadrature for a GLMM — and returns an
fb_fit() of (beta, sigma, tau) draws. For the Poisson marginal — whose
variance-component funnel a single static-metric kernel cannot traverse — a
funnel-safe blocked sampler is used: log tau is slice-sampled, and the
coefficients are slice-sampled along their tau-resolved principal axes (a
Gibbs block that needs no step size and cannot stall); the Gaussian and
binomial marginals keep the joint NUTS kernel.
fit_glmm_marginal( pass, lens_spec = NULL, n_iter = 1500L, n_burn = 750L, n_chains = 4L, n_nodes = 20L, max_treedepth = 9L )fit_glmm_marginal( pass, lens_spec = NULL, n_iter = 1500L, n_burn = 750L, n_chains = 4L, n_nodes = 20L, max_treedepth = 9L )
pass |
A |
lens_spec |
The lens's registry record; defaults to the registry's
|
n_iter |
Iterations per chain (including warm-up). The Hamiltonian kernel needs far fewer than a random walk for the same effective sample size, so the default is modest. |
n_burn |
Warm-up iterations per chain (step-size + mass-matrix adaptation), discarded from the returned draws. |
n_chains |
Number of chains. |
n_nodes |
Gauss-Hermite nodes for the GLMM marginal (ignored for the exact Gaussian LMM path). |
max_treedepth |
Maximum NUTS tree depth (the joint-NUTS Gaussian / binomial
path only), capping the leapfrog budget per iteration at |
For the breeder-standard multi-environment-trial (MET) structure — two
crossed or nested random intercepts (1 | variety) + (1 | trial) — the
Gaussian marginal stays exact (a dense Cholesky of V = sigma^2 I + sum_r tau_r^2 Z_r Z_r') and is sampled by a coordinate-wise slice kernel over
(beta, sigma, tau_variety, tau_trial); the draws then carry one
tau_<grouping> per random factor. A non-Gaussian MET (a dense crossed-GLMM
marginal, which has no exact quadrature) returns a lens-scope abstention().
The pointwise log-likelihood is left NULL for assemble_loglik() to compute
as the per-observation integrated predictive (F3). If the pass carries no
supported random intercept, returns a lens-scope abstention() rather than a
wrong fit (I1).
A koine_fb_fit, or a koine_abstention for an unsupported pass.
set.seed(1) g <- factor(rep(1:8, each = 5)) d <- data.frame(x = rnorm(40), g = g) d$y <- 1 + 0.5 * d$x + rnorm(8)[g] + rnorm(40, 0, 0.7) pass <- koine_pass(y ~ x + (1 | g), d, gaussian()) fit_glmm_marginal(pass, n_iter = 800L, n_burn = 400L, n_chains = 2L)set.seed(1) g <- factor(rep(1:8, each = 5)) d <- data.frame(x = rnorm(40), g = g) d$y <- 1 + 0.5 * d$x + rnorm(8)[g] + rnorm(40, 0, 0.7) pass <- koine_pass(y ~ x + (1 | g), d, gaussian()) fit_glmm_marginal(pass, n_iter = 800L, n_burn = 400L, n_chains = 2L)
Fits a Gaussian linear mixed model whose random intercepts are Student-t
(b_g ~ t_nu(0, tau)) by delayed-rejection adaptive Metropolis on the t-RE
marginal, and returns an fb_fit() carrying its own t-RE integrated
predictive. Resolves only for a Gaussian (identity) response with a supported
single random intercept; otherwise returns a lens-scope abstention().
fit_glmm_robust_re( pass, lens_spec = NULL, nu = 4, n_iter = 4000L, n_burn = 2000L, n_chains = 4L, n_nodes = 32L )fit_glmm_robust_re( pass, lens_spec = NULL, nu = 4, n_iter = 4000L, n_burn = 2000L, n_chains = 4L, n_nodes = 32L )
pass |
A |
lens_spec |
The lens's registry record; defaults to the |
nu |
Degrees of freedom of the Student-t random effect (fixed; lower = heavier-tailed group effects). Default 4. |
n_iter, n_burn, n_chains
|
Sampler controls. |
n_nodes |
Gauss-Laguerre nodes for the scale-mixture integral. |
A koine_fb_fit, or a koine_abstention.
set.seed(1) g <- factor(rep(1:12, each = 8)) bt <- stats::rt(12, df = 4) * 1.2 d <- data.frame(x = rnorm(96), g = g) d$y <- 1 + 0.5 * d$x + bt[g] + rnorm(96, 0, 0.7) pass <- koine_pass(y ~ x + (1 | g), d, gaussian()) fit_glmm_robust_re(pass, n_iter = 800L, n_burn = 400L, n_chains = 2L)set.seed(1) g <- factor(rep(1:12, each = 8)) bt <- stats::rt(12, df = 4) * 1.2 d <- data.frame(x = rnorm(96), g = g) d$y <- 1 + 0.5 * d$x + bt[g] + rnorm(96, 0, 0.7) pass <- koine_pass(y ~ x + (1 | g), d, gaussian()) fit_glmm_robust_re(pass, n_iter = 800L, n_burn = 400L, n_chains = 2L)
Gaussian linear model with a horseshoe prior (Carvalho, Polson & Scott 2010)
via bayesreg. Resolves only for a continuous (Gaussian, identity) response
with at least one predictor; otherwise a lens-scope abstention().
fit_horseshoe( pass, lens_spec = NULL, n_iter = 2000L, n_burn = 1000L, n_chains = 4L )fit_horseshoe( pass, lens_spec = NULL, n_iter = 2000L, n_burn = 1000L, n_chains = 4L )
pass |
A |
lens_spec |
The lens's registry record; defaults to the |
n_iter, n_burn, n_chains
|
Sampler controls. |
A koine_fb_fit, or a koine_abstention.
Carvalho, Polson & Scott (2010). The horseshoe estimator for sparse signals. Biometrika 97(2):465-480.
set.seed(1) d <- data.frame(x1 = rnorm(60), x2 = rnorm(60)) d$y <- 1 + 0.8 * d$x1 + rnorm(60) pass <- koine_pass(y ~ x1 + x2, d, gaussian()) fit_horseshoe(pass, n_iter = 1000L, n_burn = 500L, n_chains = 2L)set.seed(1) d <- data.frame(x1 = rnorm(60), x2 = rnorm(60)) d$y <- 1 + 0.8 * d$x1 + rnorm(60) pass <- koine_pass(y ~ x1 + x2, d, gaussian()) fit_horseshoe(pass, n_iter = 1000L, n_burn = 500L, n_chains = 2L)
Gaussian linear model with a Laplace (Bayesian lasso) prior (Park & Casella
2008) via bayesreg — a moderate, soft-thresholding shrinkage between
ridge and horseshoe. Same resolution rules as fit_horseshoe().
fit_lasso( pass, lens_spec = NULL, n_iter = 2000L, n_burn = 1000L, n_chains = 4L )fit_lasso( pass, lens_spec = NULL, n_iter = 2000L, n_burn = 1000L, n_chains = 4L )
pass |
A |
lens_spec |
The lens's registry record; defaults to the |
n_iter, n_burn, n_chains
|
Sampler controls. |
A koine_fb_fit, or a koine_abstention.
Park & Casella (2008). The Bayesian lasso. JASA 103(482):681-686.
set.seed(1) d <- data.frame(x1 = rnorm(60), x2 = rnorm(60)) d$y <- 1 + 0.8 * d$x1 + rnorm(60) pass <- koine_pass(y ~ x1 + x2, d, gaussian()) fit_lasso(pass, n_iter = 1000L, n_burn = 500L, n_chains = 2L)set.seed(1) d <- data.frame(x1 = rnorm(60), x2 = rnorm(60)) d$y <- 1 + 0.8 * d$x1 + rnorm(60) pass <- koine_pass(y ~ x1 + x2, d, gaussian()) fit_lasso(pass, n_iter = 1000L, n_burn = 500L, n_chains = 2L)
Runs NIMBLE's conjugate / Metropolis-within-Gibbs sampler on the pass's GLM
and returns an fb_fit() of equal-weight posterior draws with a complete
provenance record. If the family/link pair is unsupported, returns a
lens-scope abstention() rather than a wrong fit (I1).
fit_nimble( pass, lens_spec = NULL, n_iter = 4000L, n_burn = 2000L, n_chains = 4L )fit_nimble( pass, lens_spec = NULL, n_iter = 4000L, n_burn = 2000L, n_chains = 4L )
pass |
A |
lens_spec |
The lens's registry record; defaults to the registry's
|
n_iter |
Iterations per chain (including burn-in). |
n_burn |
Burn-in iterations discarded per chain. |
n_chains |
Number of chains. |
A koine_fb_fit, or a koine_abstention for an unsupported link.
set.seed(1) d <- data.frame(x = rnorm(40)) d$y <- 1 + 0.8 * d$x + rnorm(40) pass <- koine_pass(y ~ x, d, gaussian()) fit_nimble(pass, n_iter = 1000L, n_burn = 500L, n_chains = 2L)set.seed(1) d <- data.frame(x = rnorm(40)) d$y <- 1 + 0.8 * d$x + rnorm(40) pass <- koine_pass(y ~ x, d, gaussian()) fit_nimble(pass, n_iter = 1000L, n_burn = 500L, n_chains = 2L)
Runs NIMBLE's conjugate / Metropolis-within-Gibbs sampler on a mixed model
with a single random intercept and returns an fb_fit() of (beta, sigma, tau) draws — the random effects are sampled but not retained, since the
opinion is stacked on the integrated predictive. If the family/link pair is
unsupported, or the pass carries no supported random intercept, returns a
lens-scope abstention() rather than a wrong fit (I1).
fit_nimble_glmm( pass, lens_spec = NULL, n_iter = 4000L, n_burn = 2000L, n_chains = 4L )fit_nimble_glmm( pass, lens_spec = NULL, n_iter = 4000L, n_burn = 2000L, n_chains = 4L )
pass |
A |
lens_spec |
The lens's registry record; defaults to the registry's
|
n_iter |
Iterations per chain (including burn-in). |
n_burn |
Burn-in iterations discarded per chain. |
n_chains |
Number of chains. |
A koine_fb_fit, or a koine_abstention for an unsupported pass.
set.seed(1) g <- factor(rep(1:8, each = 5)) d <- data.frame(x = rnorm(40), g = g) d$y <- 1 + 0.5 * d$x + rnorm(8)[g] + rnorm(40, 0, 0.7) pass <- koine_pass(y ~ x + (1 | g), d, gaussian()) fit_nimble_glmm(pass, n_iter = 1000L, n_burn = 500L, n_chains = 2L)set.seed(1) g <- factor(rep(1:8, each = 5)) d <- data.frame(x = rnorm(40), g = g) d$y <- 1 + 0.5 * d$x + rnorm(8)[g] + rnorm(40, 0, 0.7) pass <- koine_pass(y ~ x + (1 | g), d, gaussian()) fit_nimble_glmm(pass, n_iter = 1000L, n_burn = 500L, n_chains = 2L)
Runs the exact Polya-Gamma Gibbs sampler for a Bernoulli-logit model and
returns an fb_fit(). Resolves only for the binomial (logit) family; for any
other family it returns a lens-scope abstention() rather than a wrong fit.
fit_pg_gibbs( pass, lens_spec = NULL, n_iter = 3000L, n_burn = 1500L, n_chains = 4L )fit_pg_gibbs( pass, lens_spec = NULL, n_iter = 3000L, n_burn = 1500L, n_chains = 4L )
pass |
A |
lens_spec |
The lens's registry record; defaults to the |
n_iter |
Iterations per chain. |
n_burn |
Burn-in iterations discarded per chain. |
n_chains |
Number of chains. |
A koine_fb_fit, or a koine_abstention.
Polson, Scott & Windle (2013). Bayesian inference for logistic models using Polya-Gamma latent variables. JASA 108(504):1339-1349.
set.seed(1) d <- data.frame(x = rnorm(80)) d$y <- rbinom(80, 1, plogis(0.5 * d$x)) pass <- koine_pass(y ~ x, d, binomial()) fit_pg_gibbs(pass, n_iter = 1000L, n_burn = 500L, n_chains = 2L)set.seed(1) d <- data.frame(x = rnorm(80)) d$y <- rbinom(80, 1, plogis(0.5 * d$x)) pass <- koine_pass(y ~ x, d, binomial()) fit_pg_gibbs(pass, n_iter = 1000L, n_burn = 500L, n_chains = 2L)
Gaussian linear model with a Gaussian (ridge) prior of estimated global
scale via bayesreg — mild, near-flat shrinkage anchoring the low-sparsity
end of the shrinkage spectrum. Same resolution rules as fit_horseshoe().
fit_ridge( pass, lens_spec = NULL, n_iter = 2000L, n_burn = 1000L, n_chains = 4L )fit_ridge( pass, lens_spec = NULL, n_iter = 2000L, n_burn = 1000L, n_chains = 4L )
pass |
A |
lens_spec |
The lens's registry record; defaults to the |
n_iter, n_burn, n_chains
|
Sampler controls. |
A koine_fb_fit, or a koine_abstention.
set.seed(1) d <- data.frame(x1 = rnorm(60), x2 = rnorm(60)) d$y <- 1 + 0.8 * d$x1 + rnorm(60) pass <- koine_pass(y ~ x1 + x2, d, gaussian()) fit_ridge(pass, n_iter = 1000L, n_burn = 500L, n_chains = 2L)set.seed(1) d <- data.frame(x1 = rnorm(60), x2 = rnorm(60)) d$y <- 1 + 0.8 * d$x1 + rnorm(60) pass <- koine_pass(y ~ x1 + x2, d, gaussian()) fit_ridge(pass, n_iter = 1000L, n_burn = 500L, n_chains = 2L)
Fits y ~ Student-t(nu, X beta, sigma) by delayed-rejection adaptive
Metropolis (the DRAM kernel) and returns an fb_fit() carrying its own
Student-t pointwise log-likelihood. Resolves only for a continuous
(Gaussian-declared) response; otherwise returns a lens-scope abstention().
fit_robust_t( pass, lens_spec = NULL, nu = 4, n_iter = 4000L, n_burn = 2000L, n_chains = 4L )fit_robust_t( pass, lens_spec = NULL, nu = 4, n_iter = 4000L, n_burn = 2000L, n_chains = 4L )
pass |
A |
lens_spec |
The lens's registry record; defaults to the |
nu |
Degrees of freedom of the Student-t likelihood (fixed; lower = of heavier tails). Default 4. |
n_iter, n_burn, n_chains
|
Sampler controls. |
A koine_fb_fit, or a koine_abstention.
set.seed(1) d <- data.frame(x = rnorm(50)) d$y <- 1 + 0.8 * d$x + stats::rt(50, df = 4) * 0.6 pass <- koine_pass(y ~ x, d, gaussian()) fit_robust_t(pass, nu = 4, n_iter = 800L, n_burn = 400L, n_chains = 2L)set.seed(1) d <- data.frame(x = rnorm(50)) d$y <- 1 + 0.8 * d$x + stats::rt(50, df = 4) * 0.6 pass <- koine_pass(y ~ x, d, gaussian()) fit_robust_t(pass, nu = 4, n_iter = 800L, n_burn = 400L, n_chains = 2L)
Decides whether a lens of a given maturity tier may corroborate the fourth
opinion, and at what weight discount. A koine-first lens
(koine-implemented-validated) may corroborate only when validation evidence
is on record (validation_ref); without it the lens is treated as
experimental and may not corroborate — an unvalidated first-mover is
never silently trusted (open-arms correctness, SS6/SS11).
gate_corroboration(maturity_tier, validation_ref = NULL)gate_corroboration(maturity_tier, validation_ref = NULL)
maturity_tier |
One of |
validation_ref |
Optional identifier of the validation evidence (e.g. a
ledger cairn id). Required to back the |
A list with effective_tier, may_corroborate (logical), and
discount (1 reference-validated, 0.5 koine-validated, 0 experimental).
gate_corroboration("reference-validated") gate_corroboration("koine-implemented-validated", validation_ref = "cairn-1") gate_corroboration("koine-implemented-validated") # unbacked -> experimentalgate_corroboration("reference-validated") gate_corroboration("koine-implemented-validated", validation_ref = "cairn-1") gate_corroboration("koine-implemented-validated") # unbacked -> experimental
Computes per-lens PSIS-LOO with a sample-size-dependent Pareto-k threshold
min(1 - 1 / log10(S), 0.7). Lenses whose worst k exceeds the threshold are
dropped with a recorded reason (never silently). This build implements the
drop action; K-fold refit is a later stage.
gate_psis(loglik_list)gate_psis(loglik_list)
loglik_list |
Output of |
A list with loo (named list of loo objects for retained lenses),
kept (ids), dropped (list(id =, reason =, k =)), and threshold.
Vehtari, A., Simpson, D., Gelman, A., Yao, Y., & Gabry, J. (2024). Pareto smoothed importance sampling. Journal of Machine Learning Research, 25(72), 1-58.
set.seed(1) d <- data.frame(y = rnorm(40), x = rnorm(40)) pass <- koine_pass(y ~ x, d, gaussian()) fit <- fit_dram(pass, n_iter = 600L, n_burn = 300L, n_chains = 2L) gate_psis(assemble_loglik(list(fit), pass))set.seed(1) d <- data.frame(y = rnorm(40), x = rnorm(40)) pass <- koine_pass(y ~ x, d, gaussian()) fit <- fit_dram(pass, n_iter = 600L, n_burn = 300L, n_chains = 2L) gate_psis(assemble_loglik(list(fit), pass))
One row per contributing opinion lens, carrying its two-level key, maturity tier, and a corroboration discount. The discount reflects: koine-first maturity (SS11), within-family kernel redundancy, and membership of a collapse grouping. This feeds the downstream fourth-vs-three grading.
independence_report(fb_fits)independence_report(fb_fits)
fb_fits |
A list of contributed |
A data frame with columns lens_id, family, kernel,
maturity_tier, discount, and collapsed_witness.
set.seed(1) d <- data.frame(y = rnorm(40), x = rnorm(40)) pass <- koine_pass(y ~ x, d, gaussian()) fit <- fit_dram(pass, n_iter = 600L, n_burn = 300L, n_chains = 2L) independence_report(list(fit))set.seed(1) d <- data.frame(y = rnorm(40), x = rnorm(40)) pass <- koine_pass(y ~ x, d, gaussian()) fit <- fit_dram(pass, n_iter = 600L, n_burn = 300L, n_chains = 2L) independence_report(list(fit))
Is this object an abstention?
is_abstention(x)is_abstention(x)
x |
Any object. |
TRUE if x is a koine_abstention.
out <- abstention("no_diverse_battery", scope = "synthesis", detail = "only one opinion lens resolved.") is_abstention(out) is_abstention(42)out <- abstention("no_diverse_battery", scope = "synthesis", detail = "only one opinion lens resolved.") is_abstention(out) is_abstention(42)
A cheap capability predicate — it resolves the battery but fits nothing —
for a parent panel's backend-availability gate. Returns TRUE when at least
two independent opinion lenses would enrol, or a single reason string from
the abstention taxonomy otherwise ("feature_unsupported",
"no_diverse_battery", or "pass_invalid" for a malformed model). Because
the PSIS reliability gate and weight-degeneracy check can only be evaluated
after fitting, a TRUE here is necessarily optimistic: koine may still abstain
at synthesise() time. The predicate is a floor, not a guarantee.
koine_can_contribute( formula, data, family, resources = list(allowed_tiers = 1L), registry = koine_stage1_registry() )koine_can_contribute( formula, data, family, resources = list(allowed_tiers = 1L), registry = koine_stage1_registry() )
formula, data, family
|
As for |
resources |
A resources list (see |
registry |
A registry list; defaults to |
TRUE, or a single reason-code string.
koine_opinion_draws(), synthesise()
d <- data.frame(y = rnorm(40), x = rnorm(40)) koine_can_contribute(y ~ x, d, gaussian())d <- data.frame(y = rnorm(40), x = rnorm(40)) koine_can_contribute(y ~ x, d, gaussian())
Returns the prior draw, the model simulator, the sampler call, the parameters
to rank, and a grid-exact reference-posterior builder for one of koine's
koine-authored lenses ("dram", "pg_gibbs", "robust_t"). This is the
shared harness behind sbc_check() and reference_posterior_check() for the
recorded validation study; SBC simulates from the model returned here, so the
calibration test sees the lens's own {prior, model, sampler} triple.
koine_lens_validation_setup( lens_id, n_obs = 40L, n_pred = 1L, nu = 4, fit_control = list(n_iter = 1500L, n_burn = 750L, n_chains = 2L), family = c("gaussian", "binomial", "poisson"), n_groups = 12L, n_per_group = 6L )koine_lens_validation_setup( lens_id, n_obs = 40L, n_pred = 1L, nu = 4, fit_control = list(n_iter = 1500L, n_burn = 750L, n_chains = 2L), family = c("gaussian", "binomial", "poisson"), n_groups = 12L, n_per_group = 6L )
lens_id |
One of |
n_obs |
Observations per simulated dataset (population lenses). |
n_pred |
Number of predictors beyond the intercept. |
nu |
Student-t degrees of freedom for |
fit_control |
A list of sampler controls passed to the lens fit. |
family |
For the mixed-model lenses, the response family
( |
n_groups |
Number of random-effect groups (mixed-model lenses). |
n_per_group |
Observations per group (mixed-model lenses). |
A list with generate, fit_fn, param_names, and reference.
setup <- koine_lens_validation_setup("dram") setup$param_namessetup <- koine_lens_validation_setup("dram") setup$param_names
Materialises koine's single synthesised opinion as an equal-weight
posterior::draws_array over the parameters its contributing lenses share, by
drawing from each retained lens in proportion to its LOO-stacking weight. This
is the parameter-space representation a parent panel's parameter-marginal
triangulation consumes. The stacking weights, the stacked predictive elpd, any
per-lens parameters dropped from the shared set, and any scale parameters whose
lens set was restricted ride along as attributes (koine_weights,
koine_elpd_stacked, koine_dropped_vars, koine_scale_restricted).
koine_opinion_draws(result, n_draws = 4000L, seed = NULL)koine_opinion_draws(result, n_draws = 4000L, seed = NULL)
result |
A |
n_draws |
Total draws in the returned mixture. Default 4000. |
seed |
Optional integer seed for the mixture sampling; defaults to a seed derived from the pass's content hash, so the representation is reproducible. |
The mixture is over koine's own battery (a legitimate single opinion), never a
pool across the parent's independent engines (charter SS4). Each parameter is
mixed only over the lenses for which it is comparable: the linear-predictor
coefficients (b_<col>) over every contributing lens, but a scale parameter
(sigma, tau) only over the family-likelihood lenses — a likelihood-variant
lens (the robust-t lens, which carries its own Student-t likelihood) reports its
scale on a different metric, so it would bias the synthesised value if averaged
in. The returned draws are therefore a per-parameter marginal representation
(each column is its comparable-lens stacking mixture); the joint is approximate,
which is exactly what a parameter-marginal triangulation needs.
A one-chain posterior::draws_array, or the input abstention.
synthesise(), koine_can_contribute()
set.seed(1) d <- data.frame(y = 1 + rnorm(80), x = rnorm(80)) pass <- koine_pass(y ~ x, d, gaussian()) res <- synthesise(pass, keep_fits = TRUE) if (!is_abstention(res)) { dr <- koine_opinion_draws(res) posterior::summarise_draws(dr, "mean", "sd") }set.seed(1) d <- data.frame(y = 1 + rnorm(80), x = rnorm(80)) pass <- koine_pass(y ~ x, d, gaussian()) res <- synthesise(pass, keep_fits = TRUE) if (!is_abstention(res)) { dr <- koine_opinion_draws(res) posterior::summarise_draws(dr, "mean", "sd") }
pass
Construct a koine pass
koine_pass( formula, data, family, required_outputs = c("posterior", "log_likelihood"), seed = 1L, obs_id = NULL, resources = list(allowed_tiers = 1L), prior = NULL )koine_pass( formula, data, family, required_outputs = c("posterior", "log_likelihood"), seed = 1L, obs_id = NULL, resources = list(allowed_tiers = 1L), prior = NULL )
formula |
A model formula. Population-level terms, optionally with
|
data |
A data frame holding every column referenced in |
family |
A base-R |
required_outputs |
Character subset of |
seed |
Integer master seed; per-lens seeds are derived from it. |
obs_id |
Optional character vector of observation ids (defaults to
|
resources |
A list with |
prior |
Optional structured prior table (unused by the DRAM lens, which uses its own weakly-informative default; reserved for later lenses). |
A validated object of class koine_pass.
d <- data.frame(y = rnorm(20), x = rnorm(20)) koine_pass(y ~ x, d, gaussian())d <- data.frame(y = rnorm(20), x = rnorm(20)) koine_pass(y ~ x, d, gaussian())
pass from design arrays (the IR-targetable builder)The programmatic, re-entrant, deparse-free entry point a parent triangulation
panel drives (flexyBayes backend-contract clause 1): build a pass directly
from a named design matrix, a response, a family, and an optional grouping
vector — no model formula, no match.call() capture, no session-global
state. Two passes can be built and synthesised in the same process without
interference. The stored design is used verbatim downstream, so non-syntactic
canonical column names (e.g. (Intercept)) pass through untouched.
koine_pass_from_design( x, y, family, group = NULL, groups = NULL, coef_names = colnames(x), response_name = "y", grouping_name = "g", required_outputs = c("posterior", "log_likelihood"), seed = 1L, obs_id = NULL, resources = list(allowed_tiers = 1L), prior = NULL )koine_pass_from_design( x, y, family, group = NULL, groups = NULL, coef_names = colnames(x), response_name = "y", grouping_name = "g", required_outputs = c("posterior", "log_likelihood"), seed = 1L, obs_id = NULL, resources = list(allowed_tiers = 1L), prior = NULL )
x |
A numeric design matrix with named columns (the fixed-effects design;
include an |
y |
The response vector (length |
family |
A base-R |
group |
Optional grouping vector (length |
groups |
Optional named list of two grouping vectors (each length
|
coef_names |
Optional column names for |
response_name |
Name recorded for the response (default |
grouping_name |
Name recorded for the (single) grouping factor when
|
required_outputs |
Character subset of |
seed |
Integer master seed; per-lens seeds are derived from it. |
obs_id |
Optional character vector of observation ids (defaults to
|
resources |
A list with |
prior |
Optional structured prior table (unused by the DRAM lens, which uses its own weakly-informative default; reserved for later lenses). |
A validated object of class koine_pass.
koine_pass(), koine_opinion_draws()
set.seed(1) x <- cbind(`(Intercept)` = 1, z = rnorm(40)) y <- 1 + 0.5 * x[, "z"] + rnorm(40) pass <- koine_pass_from_design(x, y, gaussian()) pass$has_re # FALSE -- a population model, built without a formulaset.seed(1) x <- cbind(`(Intercept)` = 1, z = rnorm(40)) y <- 1 + 0.5 * x[, "z"] + rnorm(40) pass <- koine_pass_from_design(x, y, gaussian()) pass$has_re # FALSE -- a population model, built without a formula
The Stage-1 enrolment registry (leanest cut)
koine_stage1_registry()koine_stage1_registry()
A list of koine_lens_spec records.
reg <- koine_stage1_registry() vapply(reg, function(L) L$id, character(1))reg <- koine_stage1_registry() vapply(reg, function(L) L$id, character(1))
Resolves a lens spec's declared maturity against its validation_ref: a
koine-first lens without recorded validation evidence is demoted to
experimental (it may not corroborate). Reference-validated lenses and
validation-backed koine lenses keep their declared tier.
lens_effective_maturity(lens_spec)lens_effective_maturity(lens_spec)
lens_spec |
A |
The effective maturity tier (a string).
lens_effective_maturity(koine_stage1_registry()[[1]])lens_effective_maturity(koine_stage1_registry()[[1]])
Construct a lens specification (a registry record)
lens_spec( id, label, tier, independence_key, role, exactness, maturity_tier, family_support, feature_support, emits_loglik, fit_fn = NULL, implemented = FALSE, emits_evidence = FALSE, structure_variant = FALSE, validation_ref = NULL )lens_spec( id, label, tier, independence_key, role, exactness, maturity_tier, family_support, feature_support, emits_loglik, fit_fn = NULL, implemented = FALSE, emits_evidence = FALSE, structure_variant = FALSE, validation_ref = NULL )
id |
Stable key, e.g. |
label |
Human-readable label. |
tier |
1 (R/C++ native), 2 (opt-in C++), or 3 (opt-in Python). |
independence_key |
|
role |
|
exactness |
|
maturity_tier |
One of the maturity tiers (Stage-0 SS11). |
family_support |
Predicate |
feature_support |
A |
emits_loglik |
|
fit_fn |
The adapter |
implemented |
|
emits_evidence |
|
structure_variant |
|
validation_ref |
Optional identifier (e.g. a ledger cairn id) recording
the SBC / reference-posterior evidence behind a
|
A koine_lens_spec.
lens_spec( id = "demo", label = "Demonstration lens", tier = 1L, independence_key = list(family = "random_walk", kernel = "demo"), role = "opinion", exactness = "exact", maturity_tier = "reference-validated", family_support = function(fs) fs$name == "gaussian", feature_support = list(random_effects = FALSE, distributional = FALSE, nonlinear = FALSE, met = FALSE), emits_loglik = FALSE)lens_spec( id = "demo", label = "Demonstration lens", tier = 1L, independence_key = list(family = "random_walk", kernel = "demo"), role = "opinion", exactness = "exact", maturity_tier = "reference-validated", family_support = function(fs) fs$name == "gaussian", feature_support = list(random_effects = FALSE, distributional = FALSE, nonlinear = FALSE, met = FALSE), emits_loglik = FALSE)
An equal-weight mixture of the contributing lenses' conditional-mean
predictives, deliberately over-dispersed to serve as a reference
bracket rather than a confident prediction. For each observation the envelope
half-width combines the average within-lens posterior uncertainty with the
between-lens disagreement, the latter inflated by inflate (default 2). The
reported envelope is the full equal-weight pool; flagging is leave-one-out
— a lens is flagged at an observation when its posterior-mean response
falls outside the over-dispersed bracket formed by the other lenses, so a
disagreement carrier is caught against the consensus rather than inflating
its own bracket. The envelope is a diagnostic surface only and is never
shipped as the opinion (I2).
linear_pool_envelope(fb_fits, pass, inflate = 2, level = 0.95)linear_pool_envelope(fb_fits, pass, inflate = 2, level = 0.95)
fb_fits |
A list of contributed |
pass |
The originating |
inflate |
Over-dispersion multiplier on the between-lens disagreement variance (default 2, per SS9.2's "inflated approximately 2x disagreement"). |
level |
Central interval width for the bracket (default 0.95). |
Operates on the conditional-mean scale mu_i = linkinv(eta_i), which is
comparable across every lens regardless of likelihood-tail differences, so a
robust-t lens and a Gaussian lens are bracketed on the same footing.
A list with obs_id, pool_mean, lower, upper (length-N
vectors), flags (a data frame of lens_id x out-of-envelope counts),
n_components, and inflate; or NULL when fewer than two lenses
expose a comparable mean-response (no envelope is meaningful).
set.seed(1) d <- data.frame(y = 1 + rnorm(50), x = rnorm(50)) pass <- koine_pass(y ~ x, d, gaussian()) fits <- list( fit_dram(pass, n_iter = 800L, n_burn = 400L, n_chains = 2L), fit_robust_t(pass, n_iter = 800L, n_burn = 400L, n_chains = 2L)) env <- linear_pool_envelope(fits, pass) env$flagsset.seed(1) d <- data.frame(y = 1 + rnorm(50), x = rnorm(50)) pass <- koine_pass(y ~ x, d, gaussian()) fits <- list( fit_dram(pass, n_iter = 800L, n_burn = 400L, n_chains = 2L), fit_robust_t(pass, n_iter = 800L, n_burn = 400L, n_chains = 2L)) env <- linear_pool_envelope(fits, pass) env$flags
Build a provenance record
provenance_record( method, method_version, impl_language, seed, derived_seed, ir_hash, maturity_tier, independence_key, role, exactness, timestamp_iso8601 = NULL, lib_versions = NULL, device = NULL, py_pins = NULL, trace = NULL, structure_variant = FALSE )provenance_record( method, method_version, impl_language, seed, derived_seed, ir_hash, maturity_tier, independence_key, role, exactness, timestamp_iso8601 = NULL, lib_versions = NULL, device = NULL, py_pins = NULL, trace = NULL, structure_variant = FALSE )
method |
Lens method id (e.g. |
method_version |
Version string of the method implementation. |
impl_language |
|
seed |
Master seed from the pass. |
derived_seed |
Per-lens derived seed. |
ir_hash |
Content hash of the originating pass. |
maturity_tier |
One of the maturity tiers (Stage-0 SS11). |
independence_key |
|
role |
|
exactness |
|
timestamp_iso8601 |
ISO-8601 timestamp; defaults to now (UTC). |
lib_versions |
Optional named list of library versions. |
device |
Optional device string. |
py_pins |
Optional named list of Python pins (Tier-3 only). |
trace |
Optional list of per-stage outcomes. |
structure_variant |
|
A koine_provenance object.
provenance_record( method = "dram", method_version = "0.1.0", impl_language = "R", seed = 1L, derived_seed = 42L, ir_hash = "abc123", maturity_tier = "reference-validated", independence_key = list(family = "random_walk", kernel = "dram"), role = "opinion", exactness = "exact")provenance_record( method = "dram", method_version = "0.1.0", impl_language = "R", seed = 1L, derived_seed = 42L, ir_hash = "abc123", maturity_tier = "reference-validated", independence_key = list(family = "random_walk", kernel = "dram"), role = "opinion", exactness = "exact")
fb_fit
Read an ArviZ DataTree NetCDF-4 file into an fb_fit
read_idata_nc(path, pass = NULL, reader = c("auto", "rnetcdf", "ncdf4"))read_idata_nc(path, pass = NULL, reader = c("auto", "rnetcdf", "ncdf4"))
path |
Path to the |
pass |
Optional |
reader |
One of |
A koine_fb_fit.
# read_idata_nc() resolves an ArviZ DataTree NetCDF written by a Tier-3 # (Python) lens into the uniform fb_fit contract; supply the .nc path and # the originating pass: ## Not run: fit <- read_idata_nc("inference.nc", pass) ## End(Not run)# read_idata_nc() resolves an ArviZ DataTree NetCDF written by a Tier-3 # (Python) lens into the uniform fb_fit contract; supply the .nc path and # the originating pass: ## Not run: fit <- read_idata_nc("inference.nc", pass) ## End(Not run)
Compares a lens's posterior to an exact reference computed by dense grid integration of the same unnormalised log-posterior — a reference that is independent of any sampler and needs no external engine, so it is runnable in this standalone package. Feasible only for low-dimensional models (the grid is the product over parameters); for larger models it returns a structured "not applicable" record rather than a misleading number (I1).
reference_posterior_check( fit, log_post_unnorm, grid, tol = 0.15, max_cells = 2e+05 )reference_posterior_check( fit, log_post_unnorm, grid, tol = 0.15, max_cells = 2e+05 )
fit |
A contributed |
log_post_unnorm |
A function |
grid |
A named list of numeric grid vectors, one per parameter, naming the parameters in draw-scale order. |
tol |
Maximum tolerated absolute standardised discrepancy between the lens and reference posterior mean (in reference SDs) for a pass. |
max_cells |
Refuse (return not-applicable) above this many grid cells. |
A list with applicable (logical), and when applicable reference
and lens summaries (per-parameter mean and SD), discrepancy (per
parameter, in reference SDs), and passed.
setup <- koine_lens_validation_setup( "dram", n_obs = 30L, fit_control = list(n_iter = 1500L, n_burn = 750L, n_chains = 2L)) g <- setup$generate(1L) fit <- setup$fit_fn(g$pass) ref <- setup$reference(g, n_pts = 21L) reference_posterior_check(fit, ref$log_post_unnorm, ref$grid)$passedsetup <- koine_lens_validation_setup( "dram", n_obs = 30L, fit_control = list(n_iter = 1500L, n_burn = 750L, n_chains = 2L)) g <- setup$generate(1L) fit <- setup$fit_fn(g$pass) ref <- setup$reference(g, n_pts = 21L) reference_posterior_check(fit, ref$log_post_unnorm, ref$grid)$passed
Enrols a lens iff: its tier is allowed; its family predicate passes; its feature support covers the formula; the log-likelihood is producible (native or via the family spec); the adapter is implemented in this build; and, for a koine-authored lens, its validation evidence is on record (the open-arms correctness gate, SS11 — an unvalidated first-mover abstains). A lens that fails any test is excluded with a recorded reason — a logged absence, not an error (I1).
resolve_battery(pass, registry = koine_stage1_registry())resolve_battery(pass, registry = koine_stage1_registry())
pass |
A |
registry |
A registry list; defaults to |
A list with enrolled (lens specs) and excluded
(list(id =, reason =) records).
set.seed(1) d <- data.frame(y = rnorm(30), x = rnorm(30)) pass <- koine_pass(y ~ x, d, gaussian()) resolved <- resolve_battery(pass) vapply(resolved$enrolled, function(L) L$id, character(1))set.seed(1) d <- data.frame(y = rnorm(30), x = rnorm(30)) pass <- koine_pass(y ~ x, d, gaussian()) resolved <- resolve_battery(pass) vapply(resolved$enrolled, function(L) L$id, character(1))
Repeatedly draws true parameters from the prior, simulates a dataset from the
lens's own generative model, fits the lens, and records the rank of each true
parameter among the (thinned) posterior draws. If the lens samples its
posterior correctly, the ranks are uniform on 0:n_keep; systematic
departures (a chi-squared test per parameter) reveal a miscalibrated sampler.
sbc_check( generate, fit_fn, param_names, n_sims = 128L, n_keep = 64L, n_bins = 8L, alpha = 0.05, seed = 1L )sbc_check( generate, fit_fn, param_names, n_sims = 128L, n_keep = 64L, n_bins = 8L, alpha = 0.05, seed = 1L )
generate |
A function |
fit_fn |
A function |
param_names |
Character vector of parameters to rank (a subset of the
names of |
n_sims |
Number of SBC replications. |
n_keep |
Posterior draws retained per fit (the ranks lie in |
n_bins |
Number of histogram bins for the chi-squared uniformity test. |
alpha |
Family-wise significance level (Bonferroni-adjusted across parameters) below which calibration is judged to have failed. |
seed |
Master seed; per-replication seeds are derived from it. |
SBC validates the {prior, model, sampler} triple as a whole, so the
generate callback must simulate data from exactly the model the lens
assumes (e.g. a Student-t likelihood for the robust-t lens), using the
exact prior the lens places.
A list with ranks (an n_sims x length(param_names) matrix),
n_keep, uniformity (a data frame of param, chisq, df, p_value),
alpha_adj, and passed (logical: every parameter's p-value exceeds the
adjusted alpha).
setup <- koine_lens_validation_setup( "dram", n_obs = 30L, fit_control = list(n_iter = 800L, n_burn = 400L, n_chains = 2L)) res <- sbc_check(setup$generate, setup$fit_fn, setup$param_names, n_sims = 16L, n_keep = 16L, n_bins = 4L) res$passedsetup <- koine_lens_validation_setup( "dram", n_obs = 30L, fit_control = list(n_iter = 800L, n_burn = 400L, n_chains = 2L)) res <- sbc_check(setup$generate, setup$fit_fn, setup$param_names, n_sims = 16L, n_keep = 16L, n_bins = 4L) res$passed
Computes stacking weights over the retained lenses and the stacked leave-one-out predictive density (the stacking objective evaluated at the optimum). Weights are retained for the diagnostic surface; they are never shipped as a pooled posterior (I2).
stack_opinion(loo_list)stack_opinion(loo_list)
loo_list |
A named list of loo objects (the gate's |
A list with weights (named simplex), elpd_stacked, and
n_components.
Yao, Y., Vehtari, A., Simpson, D., & Gelman, A. (2018). Using stacking to average Bayesian predictive distributions. Bayesian Analysis, 13(3), 917-1007.
set.seed(1) d <- data.frame(y = 1 + rnorm(60), x = rnorm(60)) pass <- koine_pass(y ~ x, d, gaussian()) fits <- list( fit_dram(pass, n_iter = 800L, n_burn = 400L, n_chains = 2L), fit_robust_t(pass, n_iter = 800L, n_burn = 400L, n_chains = 2L)) gate <- gate_psis(assemble_loglik(fits, pass)) if (length(gate$kept) >= 2L) stack_opinion(gate$loo)set.seed(1) d <- data.frame(y = 1 + rnorm(60), x = rnorm(60)) pass <- koine_pass(y ~ x, d, gaussian()) fits <- list( fit_dram(pass, n_iter = 800L, n_burn = 400L, n_chains = 2L), fit_robust_t(pass, n_iter = 800L, n_burn = 400L, n_chains = 2L)) gate <- gate_psis(assemble_loglik(fits, pass)) if (length(gate$kept) >= 2L) stack_opinion(gate$loo)
Resolves the battery, fits each opinion lens, assembles pointwise
log-likelihoods, applies the PSIS gate, stacks the survivors, and reports a
weight-concentration diagnostic — or returns a first-class abstention()
when fewer than two independent opinion lenses survive. The result is either
a koine_result or a koine_abstention, never a silent partial.
synthesise( pass, registry = koine_stage1_registry(), on_degenerate = c("flag", "abstain"), keep_fits = FALSE )synthesise( pass, registry = koine_stage1_registry(), on_degenerate = c("flag", "abstain"), keep_fits = FALSE )
pass |
A |
registry |
A registry list; defaults to |
on_degenerate |
What to do when the stacking weights are degenerate
(the battery corroborated rather than diversified): |
keep_fits |
If |
A koine_result or a koine_abstention.
d <- data.frame(y = rnorm(30), x = rnorm(30)) pass <- koine_pass(y ~ x, d, gaussian()) # with a single-lens battery, koine abstains rather than guessing res <- synthesise(pass, registry = list(koine_stage1_registry()[[1]])) is_abstention(res)d <- data.frame(y = rnorm(30), x = rnorm(30)) pass <- koine_pass(y ~ x, d, gaussian()) # with a single-lens battery, koine abstains rather than guessing res <- synthesise(pass, registry = list(koine_stage1_registry()[[1]])) is_abstention(res)
fb_fit against the field rulesEnforces: a contributed fit carries draws + a complete provenance tuple (F4);
exactness agrees between the fit and its provenance; an abstained fit
carries an koine_abstention and no draws; sample_stats/log_likelihood
are either NULL or arrays (no fabricated values, I1).
validate_fb_fit(x)validate_fb_fit(x)
x |
A |
x, invisibly, if valid; otherwise stops.
set.seed(1) draws <- posterior::as_draws_array( array(rnorm(8L), dim = c(2L, 2L, 2L), dimnames = list(NULL, NULL, c("b_(Intercept)", "b_x")))) prov <- provenance_record( method = "demo", method_version = "0", impl_language = "R", seed = 1L, derived_seed = 1L, ir_hash = "h", maturity_tier = "reference-validated", independence_key = list(family = "random_walk", kernel = "demo"), role = "opinion", exactness = "exact") validate_fb_fit(fb_fit(draws, prov, "exact", status = "contributed"))set.seed(1) draws <- posterior::as_draws_array( array(rnorm(8L), dim = c(2L, 2L, 2L), dimnames = list(NULL, NULL, c("b_(Intercept)", "b_x")))) prov <- provenance_record( method = "demo", method_version = "0", impl_language = "R", seed = 1L, derived_seed = 1L, ir_hash = "h", maturity_tier = "reference-validated", independence_key = list(family = "random_walk", kernel = "demo"), role = "opinion", exactness = "exact") validate_fb_fit(fb_fit(draws, prov, "exact", status = "contributed"))
Validate a provenance record's mandatory tuple
validate_provenance(x)validate_provenance(x)
x |
A |
x, invisibly, if every mandatory field is present and non-NULL;
otherwise raises error.provenance_incomplete.
prov <- provenance_record( method = "dram", method_version = "0.1.0", impl_language = "R", seed = 1L, derived_seed = 42L, ir_hash = "abc123", maturity_tier = "reference-validated", independence_key = list(family = "random_walk", kernel = "dram"), role = "opinion", exactness = "exact") validate_provenance(prov)prov <- provenance_record( method = "dram", method_version = "0.1.0", impl_language = "R", seed = 1L, derived_seed = 42L, ir_hash = "abc123", maturity_tier = "reference-validated", independence_key = list(family = "random_walk", kernel = "dram"), role = "opinion", exactness = "exact") validate_provenance(prov)
Summarises how concentrated the stacking weights are. Concentration on one
component means the battery added no predictive diversity (the lenses
corroborate rather than diversify); spread weights mean genuine
model-structure diversity was realised. Reports the effective number of
components n_eff = 1 / sum(w^2), the maximum weight, the entropy, and a
degenerate flag.
weight_concentration(weights, n_eff_threshold = 1.5)weight_concentration(weights, n_eff_threshold = 1.5)
weights |
A named numeric vector of stacking weights. |
n_eff_threshold |
Below this effective component count the weights are flagged degenerate. Default 1.5. |
A list with weights, max_weight, n_eff, entropy, and
degenerate.
# spread weights: genuine diversity; concentrated weights: corroboration weight_concentration(c(dram = 0.55, robust_t = 0.45)) weight_concentration(c(dram = 0.97, robust_t = 0.03))# spread weights: genuine diversity; concentrated weights: corroboration weight_concentration(c(dram = 0.55, robust_t = 0.45)) weight_concentration(c(dram = 0.97, robust_t = 0.03))