WVIM and LOCO now default to
n_repeats = 1, and the argument may be removed for these
refit-based methods in the future (#84).
FeatureSampler$sample() and
$sample_newdata() gain a samples_per_row
argument (default 1L).
samples_per_row > 1 the sampler returns
samples_per_row * length(row_ids) rows in draw-major order
(one block of all input rows per draw), default behaviour is
unchanged.samples_per_row
natively.WVIM and LOCO gain a
batch_size constructor argument (default NULL)
to parallelize refits.
design_points) are
dispatched per internal mlr3::benchmark() call via the
mlr3fselect::fs("design_points") fselector.NULL keeps the prior sequential single-refit behaviour
(bbotk default of one design point per call). Set a positive integer
(e.g. the number of future/mirai workers) so
mlr3 can spread refits across workers. Previously they were dispatched
one at a time and backends sat idle during LOCO/WVIM computation.uhash, so scores/obs-losses are attributed
correctly for any batch_size.PerturbationImportance
(PFI/CFI/RFI) and
ConditionalSAGE now pass
samples_per_row = n_repeats / n_samples to the
sampler on unique test rows instead of externally replicating row IDs.
ConditionalARFSampler this calls
arf::forge(n_synth = ...) on n_test unique
evidence rows rather than n_synth = 1 on replicated rows:
much faster at scale, and it dodges an int32 overflow inside
arf::forge for large n_test * n_repeats.MarginalSAGE) does not use a
FeatureSampler and is unaffected.PerturbationImportance now forges sequentially inside
each mirai daemon, since the outer mirai layer already parallelizes
across features; a ConditionalARFSampler with
parallel = TRUE no longer nests arf::forge()
parallelism inside workers (which would oversubscribe cores). The
sampler’s parallel flag still drives fit-time parallelism
(adversarial_rf/forde) as before.$importance() with a test-based ci_method
("lei", "cpi") now warns and returns
NA inference fields for a feature whose hypothesis test
errors, instead of aborting the whole call; this guards against an
R-devel (2026-05) change to stats::wilcox.test that errors
on many-ties or many-zeros inputs.relation = "ratio" importances now return
NA (with a warning) instead of
Inf/NaN for features whose baseline score is
0.PerturbationImportance no longer calls
$obs_loss() without measure, which errored
when measures was not the task default.ConditionalARFSampler$sample() now errors when
parallel = TRUE but no parallel backend is registered,
e.g. after deserializing a sampler in a new session.ConditionalARFSampler no longer returns under-sampled
(and, with samples_per_row > 1, partially
NA-filled) output when conditioning_set is
empty.
arf::forge(evidence = NULL, n_synth = k) returns only
k unconditional draws, not nrow(data) * k; the
previous code path silently recycled a single sample across all output
rows when samples_per_row = 1L. The marginal case now
requests nrow(data) * samples_per_row independent draws so
every (instance, draw) pair gets its own sample.ConditionalSAGE (empty
conditioning set on every empty coalition); CFI/RFI/PFI condition on the
complement of the perturbed feature and never trigger the
empty-conditioning path. As a side effect, ConditionalSAGE
importance estimates for noise features are now substantially less
inflated under the same n_permutations /
n_samples budget.KnockoffSampler n_repeats > iters
cap-and-warn behaviour moved from
PerturbationImportance$initialize() into
KnockoffSampler$sample() itself; behaviour is
unchanged.mlr3 learner is now supported in
PerturbationImportance (PFI, CFI,
RFI) and SAGE methods.
Resampling to be instantiated and
consist of a single iteration, e.g. there must be only 1 test set.rsmp_all_test(task) utility can be used to
construct a single-iteration Resampling object from a given
Task where all observations are aligned to the test set and
the train set is empty. We will likely refine the API around this in the
future.ResampleResult will be constructed from
the given learner, task, and
resampling arguments, which is then consistent with the
previous default of performing resample() to get trained
learners for each resampling iteration.ci_method = "lei" for
WVIM/LOCO: distribution-free inference based
on Lei et al. (2018), testing observation-wise loss differences.
Defaults to Wilcoxon signed-rank test with median aggregation. Supports
t-test, Fisher permutation, and binomial (sign) tests. Requires a
decomposable measure (with $obs_loss()).p_adjust parameter in $importance()
for multiplicity correction across all ci_methods that
produce p-values ("raw", "nadeau_bengio",
"cpi", "lei"). Accepts any method from
stats::p.adjust.methods (e.g. "holm",
"bonferroni", "BH"). Default is
"none". When "bonferroni", confidence
intervals are also adjusted (alpha/k). For other methods, only p-values
are adjusted because sequential/adaptive procedures lack a clean
per-comparison alpha for CI construction.ci_methods ("raw",
"nadeau_bengio") return se,
statistic, p.value, conf_lower,
and conf_upper columns. The "quantile" method
returns only conf_lower and conf_upper (no
se, statistic, or p.value).ci_methods support
alternative = "greater" (one-sided) or
alternative = "two.sided" (the default) to test H0:
importance <= 0 vs H1: importance > 0, or H0: importance = 0 vs
H1: importance != 0, respectively. For "quantile",
alternative controls whether the interval is one-sided
("greater": finite lower bound,
conf_upper = Inf) or two-sided (both bounds finite).FeatureImportanceMethod, explaining how p-values and
confidence intervals are calculated for each method.n_repeats in favor of stability
PerturbationImportance methods (PFI,
CFI, RFI): n_repeats is now
30LOCO and WVIM: n_repeats is
now 30 as well.n_repeats = 1, which is obviously too small.ranger with rpart in most tests
where a flexible learner was unnecessary.expect_method_output() expectation that
validates all three main outputs ($importance(),
$scores(), $obs_loss()) of a computed
method.test_basic_workflow, test_with_resampling,
test_custom_sampler) and inlined their logic at call sites
for better readability.ConditionalGaussianSampler instead of
ConditionalARFSampler in tests that don’t specifically test
ARF functionality.n_repeats values in all tests (1L for
functional, 5L for plausibility).The major version bump is largely to mark the occasion that the package is now considered “released”.
fippy comparison article since a more
comprehensive comparison is now available in xplainfi-benchmark.min_permutations default in
SAGE methods to 10 rather than 3, since the previous value
was found to lead to spurious early stopping.sim_dgp_ewald lading to erroneous variances when
compared to their settings.KnockoffSequentialSampler as the
seqknockoff package is not available on CRAN or R-universe.
KnockoffSampler with the corresponding
knockoff_fun = seqknockoff::knockoffs_seq still works.sim_dgp_confounded, removing x2
which doesn’t add anything interesting over x1.obs_loss() is computed (see
https://github.com/mlr-org/mlr3/pull/1411).measure to be unspecified and
falling back to a task_type-specific default measure$importance() gains ci_method parameter
for variance estimation (#40):
"none" (default): Simple aggregation without confidence
intervals"raw": Uncorrected variance estimates (informative
only, CIs too narrow)"nadeau_bengio": Variance correction by Nadeau &
Bengio (2003) as recommended by Molnar et al. (2023)"quantile": Empirical quantile-based confidence
intervals"cpi": Conditional Predictive Impact for perturbation
methods (PFI/CFI/RFI), supporting t-, Wilcoxon-, Fisher-, and binomial
testsPerturbationImportance
methods only (not available for WVIM/LOCO or SAGE)$importance() gains standardize parameter
to normalize scores to [-1, 1] range$importance() and $scores() gain
relation parameter (default: "difference") to
compute importances as difference or ratio of baseline and
post-modification loss
$compute() to avoid recomputing
predictions/refits when changing aggregation methodsim_dgp_independent(): Baseline with additive
independent effectssim_dgp_correlated(): Highly correlated features (PFI
fails, CFI succeeds)sim_dgp_mediated(): Mediation structure (total vs
direct effects)sim_dgp_confounded(): Confounding structuresim_dgp_interactions(): Interaction effects between
features$obs_loss() computes observation-wise importance scores
when measure has a Measure$obs_loss()
method$predictions field stores prediction objects for
further analysisPerturbationImportance and WVIM methods
support groups parameter for grouped feature importance:
groups = list(effects = c("x1", "x2", "x3"), noise = c("noise1", "noise2"))feature column contains group names instead
of individual featuresmlr3fselect for cleaner
internalsiters_refit → n_repeats
for consistencylearner$predict_newdata_fast() for faster
predictions (requires mlr3 >= 1.1.0)sampler$sample() callsbatch_size parameter to control memory usage with
large datasetsmirai or future
backendsmirai::daemons() or
future::plan()iters_perm → n_repeats
for consistency$sample(feature, row_ids): Samples from stored task
using row IDs$sample_newdata(feature, newdata): Samples from
external dataPermutationSampler →
MarginalPermutationSamplerARFSampler → ConditionalARFSamplerGaussianConditionalSampler →
ConditionalGaussianSamplerKNNConditionalSampler →
ConditionalKNNSamplerCtreeConditionalSampler →
ConditionalCtreeSamplerconditioning_set for
features to condition onMarginalSampler: Base class for marginal sampling
methodsMarginalReferenceSampler: Samples complete rows from
reference data (for SAGE)KnockoffSampler: Knockoff-based sampling (#16 via @mnwright)
KnockoffGaussianSampler,
KnockoffSequentialSamplerrow_ids-based samplingiters parameter for multiple knockoff iterationsBug fix: ConditionalSAGE now
properly uses conditional sampling (was accidentally using marginal
sampling)
Performance improvements:
learner$predict_newdata_fast() for faster
predictionsbatch_size parameter controls memory usage for large
coalitionsConvergence tracking (#29, #33):
early_stopping = TRUEse_threshold (default: 0.01)min_permutations (default: 3)check_interval permutations
(default: 1)$converged: Boolean indicating if convergence was
reached$n_permutations_used: Actual permutations used (may be
less than requested)$convergence_history: Per-feature importance and SE
over permutations$plot_convergence(): Visualize convergence curvesarf-powered conditional sampling)arf)fippy