Fits a brms model for every candidate predictor combination and compares
them with loo::loo_compare(), returning the selected combination as an
fs_result.
Arguments
- data
A data.frame or data.table. It is copied, never modified. Only
target,predictorsanddate_colare carried forward, and rows with a missing value in any of them are dropped before any model is fitted.- target
Character. Name of the target (response) column, which must exist in
dataand suitbrm_family(numeric forstats::gaussian(), 0/1 or logical forbrms::bernoulli()).- predictors
Character vector. Names of the candidate predictor columns; at least one, all present in
data.- date_col
Character or NULL. Name of a date column. When provided, an
iso_week_idfeature (ISO year * 100 + ISO week) is added to the predictors. Note:iso_week_identers the models as a continuous covariate, which is a rough encoding of seasonality; a categorical or cyclic encoding is deferred to a future version. Default NULL (no date feature; the date column itself is never used as a predictor).- brm_family
A model family accepted by brms::brm(), for example stats::gaussian() (default) or brms::bernoulli().
- prior
A brms prior specification (default NULL).
- brm_args
List. Extra arguments for brms::brm() (for example iter, warmup, seed), overriding featR's defaults of iter = 2000, adapt_delta = 0.99, max_treedepth = 15 and refresh = 0.
chainsandcoresare respected when evaluating combinations sequentially (coresis capped at the detected core count; the defaults are 4 chains on 1 core), but both are forced to 1 whenparallel_combinations = TRUE. Defaultlist().- rule
Selection rule:
"1se"(default) keeps the most parsimonious model within one standard error of the best elpd;"best"keeps the raw elpd maximum.- max_comb_size
Whole number >= 1, or NULL. Largest number of predictors allowed in a combination; values above the number of candidate predictors are capped rather than rejected. Default NULL (all sizes).
- sample_combinations
Whole number >= 1, or NULL. Randomly sample this many combinations instead of evaluating all of them; ignored when fewer combinations exist. Pass
seedto make the draw reproducible. Default NULL (evaluate every combination).- parallel_combinations
Logical. Evaluate predictor combinations in parallel via parallel::mclapply(). Not available on Windows (falls back to sequential evaluation with a message), and falls back to sequential evaluation when
n_coresresolves to 1. Because each model is then held to a single MCMC chain, cross-chain convergence diagnostics such as R-hat become unavailable; a warning says so. Default FALSE.- seed
Optional whole number (within the R integer range; fractional values are an error rather than being truncated). When supplied, seeds the random sampling of combinations (see
sample_combinations) locally; the previous RNG state is restored on exit. Default NULL: fs_bayes() never seeds the RNG unless asked. Note this does not seed the samplers; passseedinsidebrm_argsto control brms itself.- verbose
Logical. Print progress information, and show a progress bar for sequential evaluation when the suggested pbapply package is installed. Default FALSE.
- n_cores
Whole number >= 1. Worker count used when
parallel_combinations = TRUE, and ignored otherwise. Default 1 (sequential); requests are capped at the detected core count.
Value
An object of class fs_result with:
- selected
Character vector of the predictors in the chosen model.
- scores
NULL: no per-feature score is comparable across combination models.details$n_featuresrecords how many candidate predictors were offered.- method
"bayes".
- task
"regression", or "classification" when
brm_familyis one of the categorical brms families.- model
The selected
brmsfit.- details
A list with
data(the complete-case modeling data.table:target,predictors,date_colandiso_week_idwhere applicable, plus appendedfitted_values,residuals,abs_residualsandsquared_residualscolumns),maeandrmse(in-sample, post-selection errors computed on the same rows used to fit and select, so they are optimistic),formula(the selected model's formula string),best_elpd(the selected model's elpd_loo, possiblyNA),loo_comparison(theloo::loo_compare()table – a matrix or data.frame depending on the loo version – orNULLwhen fewer than two models could be compared or the comparison failed),n_failed_fits(how many combinations failed to fit) andn_features(the number of candidate predictors, includingiso_week_idwhendate_colis supplied).- call
The matched call.
Details
Use this when you want the predictor subset itself chosen by out-of-sample
predictive fit under a fully Bayesian model, and you can afford to fit one
model per subset. The search is exhaustive by default: with p candidate
predictors it fits every non-empty subset, 2^p - 1 models, and each one
compiles and samples its own Stan program. Use max_comb_size or
sample_combinations to bound the search.
Model selection uses loo::loo_compare() rather than the raw elpd
maximum. With rule = "1se" (the default) the chosen model is the most
parsimonious one – fewest predictors, ties broken by the higher elpd –
among those whose elpd difference from the best model is no larger in
absolute value than one standard error of that difference (the se_diff
column of the comparison table). With rule = "best" the raw elpd maximum
wins, which is the older behavior and is more prone to over-fitting the
comparison. When no usable comparison table is available, both rules fall
back to the raw elpd maximum, ties broken by fewer predictors.
Combinations whose model fails to fit are excluded from selection and
counted in details$n_failed_fits, with a warning. If no fit yields a
finite elpd_loo at all, the first successfully fitted model is returned
with a warning; that is an arbitrary fallback, not a selection.
Per-model sampler warnings (divergent transitions, R-hat, effective sample
size) and loo's Pareto-k warnings are muffled while the models are fitted,
so a search over many subsets does not flood the console, but they are not
discarded: after the search one warning summarizes how many fits raised
sampler warnings and another how many have observations with Pareto
k > 0.7 (unreliable PSIS-LOO estimates), each stating whether the selected
model is among them. verbose = TRUE shows every individual warning.
Two caveats are worth stating plainly. details$mae and details$rmse are
in-sample errors computed on the same rows used to fit and to select, so
they are optimistic. And anything read off the returned brmsfit
(posterior intervals, effect sizes) is post-selection inference: the model
was chosen by looking at the same data it is reported on.
Examples
# Fitting needs more than the brms package: brms compiles and samples a
# Stan program for each candidate model, which requires a working C++
# toolchain. The call is therefore guarded on brms being installed, limited
# to two single-predictor fits via max_comb_size = 1, and wrapped in try()
# so that a machine without a usable Stan toolchain skips the example
# instead of failing it.
# \donttest{
if (requireNamespace("brms", quietly = TRUE)) {
x1 <- seq(-2, 2, length.out = 40)
x2 <- rep(c(-1, 1), 20)
d <- data.frame(
y = 1 + 2 * x1 + sin(seq_len(40)),
x1 = x1,
x2 = x2
)
res <- try(
fs_bayes(
d, target = "y", predictors = c("x1", "x2"),
max_comb_size = 1,
brm_args = list(chains = 1, iter = 500, refresh = 0),
rule = "1se", verbose = FALSE
),
silent = TRUE
)
if (!inherits(res, "try-error")) {
print(res$selected)
print(res$details$loo_comparison)
}
}
#> Compiling Stan program...
#> Compiling Stan program...
#> Warning: 2 of 2 model fits failed and were excluded from selection.
# }