Full Bayesian BTL inference via CmdStanR (adaptive-compatible)
Source:R/bayes_btl_mcmc.R
fit_bayes_btl_mcmc.RdRuns full Bayesian posterior inference for a Bradley–Terry–Luce (BTL) style
model using the package’s CmdStan machinery, but in a standalone
(non-adaptive) context. The function is designed so downstream diagnostics
and reporting can reuse the existing adaptive summary tools (notably
summarize_items() and summarize_refits()) without requiring new summary
functions.
Arguments
- results
Canonical
results_tblwithA_id,B_id, andbetter_id(plus the standard adaptive results columns). Seevalidate_results_tbl()for required structure. For legacyID1/ID2/better_iddata, first usebuild_btl_results_data().- ids
Character vector of all sample ids (length
N).- model_variant
Model variant label:
"btl","btl_e","btl_b", or"btl_e_b". Defaults to"btl_e_b".- cmdstan
List of CmdStan settings. Common fields:
- chains
Number of chains (defaults to
min(8, physical_cores)via internal resolution).- parallel_chains
Maximum concurrent chains. Automatic scheduling uses at most two CPU slots within the available allocation and
core_fraction. An explicit value bypasses that fraction and is capped atchains; its product withthreads_per_chainmust fit the available allocation.- threads_per_chain
Threads per chain (default
1). The bundled models do not use within-chain parallel likelihoods, so higher values do not accelerate their likelihood evaluation.- iter_warmup
Warmup iterations (default
1000).- iter_sampling
Sampling iterations (default
1000).- seed
Optional integer seed forwarded to CmdStan (default
NULL).- core_fraction
Fraction of available CPU slots for automatic parallelization (default
0.8); at least one slot is retained.- output_dir
Optional directory for CmdStan output.
Sampling requires the suggested parallelly package for allocation-aware detection. Scheduler, container, and check constraints limit concurrency, without changing the number of chains. Explicit requests above two CPU slots are reported and permitted within the allocation, except under an active
_R_CHECK_LIMIT_CORES_constraint. Excessive requests fail with guidance. If detection fails, a warning reports the one-slot fallback. When launching multiple fits independently, divide the allocation among them yourself.- pair_counts
Optional integer vector of subset sizes (e.g.,
c(200, 500, 1000)). When provided, the model is fit once per subset size and the round log contains one row per fit. IfNULL, a single fit is run using all rows inresults.- subset_method
Subset strategy when
pair_countsis provided:"first"(default) uses the firstnrows ofresultsfor each refit;"sample"draws a random permutation once and then takes the firstnrows of that permutation for each refit.- seed
Optional integer seed for deterministic subset selection when
subset_method = "sample". WhenNULL, falls back tocmdstan$seedif provided.- inference_contract
Optional list of inference-routing semantics to attach to each fit contract. When omitted, values are inferred from
results$phaseand optionalresults$judge_scope.- warm_start_prior
Optional
make_warm_start_prior()object. Defaults to no predictive prior (raw theta prior mean 0, SD 1). IDs must matchids.
Value
A list with:
- item_log_list
List of item-log tables, one per refit, matching the canonical adaptive item log schema. This is the preferred structure for reuse with
summarize_items().- item_summary
A single tibble formed by row-binding
item_log_list(kept for backward compatibility). Each row corresponds to an item within a refit;refit_ididentifies the refit.- round_log
Tibble matching the canonical adaptive round log schema (one row per refit).
- fits
List of BTL fit contracts (one per refit). Each records the actual per-item raw theta prior in
theta_prior; predictive fits also include compact provenance inpredictive_prior.- fit
Single fit contract (only when one refit is run).
Details
Internally, the function can optionally refit the model on increasing subsets
of the observed comparisons (via pair_counts). Each refit is treated
as a "refit" in the adaptive logging sense, producing:
one round-log row per refit (compatible with
round_log_schema()),one item-log table per refit (compatible with
.adaptive_item_log_schema()).
See also
build_btl_results_data(), make_warm_start_prior(), adaptive_rank()
Other Bayesian models:
build_btl_results_data()
Examples
if (FALSE) { # \dontrun{
results <- tibble::tibble(
pair_uid = "A:B#1",
unordered_key = "A:B",
ordered_key = "A:B",
A_id = "A",
B_id = "B",
better_id = "A",
winner_pos = 1L,
phase = "phase2",
iter = 1L,
received_at = as.POSIXct("2026-01-01 00:00:00", tz = "UTC"),
backend = "openai",
model = "gpt-test"
)
fit <- fit_bayes_btl_mcmc(
results,
ids = c("A", "B"),
model_variant = "btl_e_b"
)
# Generate summaries
summarize_refits(fit)
summarize_items(fit)
} # }