causalig.attr
Attribution methods. Arguments reference explains the shared arguments in depth, and Attribution methods explains when to use which method.
Causal gradient methods
- class causalig.attr.CausalIntegratedGradients(forward_func)[source]
Causal Integrated Gradients (CIG).
CIG is the special case of
CausalExpectedGradientsMultiStepwith a single baseline: it integrates the causal gradient along the linear path frombaselinetoinput, conditioning on a surrogate at every step to separate direct and indirect effects.Direct effect of feature i: contribution along the residual path
h = x - surrogate(x), capturing the portion of the gradient that is not mediated through the surrogate.Indirect effect of feature i: contribution along the surrogate output path, capturing effects propagated through causally downstream features.
This class delegates entirely to
CausalExpectedGradientsMultiStepand exists as a convenience wrapper with the single-baseline API (baselineinstead ofbaselines).- Parameters:
forward_func – Model to attribute. Must accept
(batch, d)float tensors and return(batch, C)or(batch,)tensors.
- attribute(input, surrogate, ordering=None, baseline=None, n_steps=50, target=None, separate_effects=False, adjacency_matrix=None, step_chunk_size=None, dim_chunk_size=None, has_closed_form_jacobian=False, include_second_order_indirect=False, return_convergence_delta=False)[source]
Compute CIG attributions.
- Parameters:
input (Tensor) – Input tensor
(d,)or(batch, d).surrogate – Trained masked surrogate (autoencoder / regressor). Must accept
(batch, d)and return(batch, d).ordering (list[int] | None) – Topological ordering of feature indices, length
d. Only needed whenadjacency_matrixisNone; otherwise it is derived from the graph.baseline (Tensor | None) – Baseline tensor
(d,), shared by every input in the batch. The integration path runs frombaselinetoinput.n_steps (int) – Number of Riemann steps along the integration path. More steps give a more accurate approximation. Default 50.
target (int) – Output index to attribute for multi-class models. If
Noneall outputs are attributed simultaneously.separate_effects (bool) – If
Truereturn(direct, indirect)instead of their sum.adjacency_matrix (Tensor | None) – Boolean tensor
(d, d)where entry[i, j]means feature i causally influences feature j. Used to restrict which features the surrogate conditions on.step_chunk_size (int | None) – Process this many path steps at a time to reduce peak memory.
Noneprocesses all steps at once.dim_chunk_size (int | None) – Process this many feature dimensions at a time when computing surrogate Jacobians.
Noneprocesses all dimensions at once.has_closed_form_jacobian (bool) – Set
Truewhen the surrogate provides an exact input Jacobian in closed form (e.g.MaskedGlobalLinear), enabling a faster analytic Jacobian computation path instead of autograd.include_second_order_indirect (bool) – If
True, add a second-hop term that captures effects mediated through two surrogate applications. Defaults toFalse.return_convergence_delta (bool) – If
True, also return a completeness delta:sum(attributions) - (f(input) - f(baseline)). A delta near zero confirms the attributions satisfy the completeness axiom; it shrinks asn_stepsincreases.
- Returns:
Attribution tensor of shape matching
input, or tuple(direct, indirect)whenseparate_effects=True. Ifreturn_convergence_delta=True, the delta tensor is appended as the last element of the returned tuple (attributions are wrapped in a tuple if not already one).- Return type:
Tensor | tuple[Tensor, Tensor] | tuple[Tensor, Tensor, Tensor]
- class causalig.attr.CausalExpectedGradientsMultiStep(forward_func)[source]
Causal Expected Gradients — multi-step integration, averaged over baselines (CEG-MS).
For each baseline b in
baselines, the causal gradient is integrated along the full linear path from b toinputusingn_stepsRiemann steps, mirroringCausalIntegratedGradients. Attributions are then averaged over all baselines.CausalIntegratedGradientsis the special case with a single baseline.Attributions are decomposed into:
Direct effects: accumulated gradient along
h = x - surrogate(x).Indirect effects: accumulated gradient along the surrogate output, capturing effects mediated through causally downstream features.
- Parameters:
forward_func – Model to attribute. Must accept
(batch, d)float tensors and return(batch, C)or(batch,)tensors.
- attribute(input, surrogate, ordering=None, baselines=None, n_steps=50, target=None, separate_effects=False, adjacency_matrix=None, baselines_chunk_size=None, step_chunk_size=None, dim_chunk_size=None, has_closed_form_jacobian=False, include_second_order_indirect=False, return_convergence_delta=False)[source]
Compute CEG-MS attributions.
- Parameters:
input (Tensor) – Input tensor
(d,)or(batch, d).surrogate – Trained masked surrogate (autoencoder / regressor). Must accept
(batch, d)and return(batch, d).ordering (list[int] | None) – Topological ordering of feature indices, length
d. Only needed whenadjacency_matrixisNone; otherwise it is derived from the graph.baselines (Tensor | None) – Baseline distribution
(n_baselines, d)or(d,). Attributions are averaged over all baselines.n_steps (int) – Number of Riemann integration steps per baseline path. More steps give a more accurate approximation. Default 50.
target (int) – Output index to attribute for multi-class models.
Noneattributes all outputs simultaneously.separate_effects (bool) – If
Truereturn(direct, indirect)instead of their sum.adjacency_matrix (Tensor | None) – Boolean tensor
(d, d)where[i, j]means feature i causally influences feature j.baselines_chunk_size (int | None) – Number of baselines to process per pass.
Noneprocesses all baselines at once.step_chunk_size (int | None) – Number of integration steps to process per pass. Must be > 1 or
None.Noneprocesses all steps at once.dim_chunk_size (int | None) – Number of feature dimensions per surrogate Jacobian pass.
Noneuses all dimensions at once.has_closed_form_jacobian (bool) – Set
Truewhen the surrogate provides an exact input Jacobian in closed form (e.g.MaskedGlobalLinear) to use the faster analytic Jacobian path instead of autograd.include_second_order_indirect (bool) – If
True, add a second-hop indirect term that captures effects propagated through two successive surrogate applications. Defaults toFalse.return_convergence_delta (bool) – If
True, also return a completeness delta:sum(attributions) - (f(input) - mean_b f(baseline_b)). A delta near zero confirms the attributions satisfy the completeness axiom; it shrinks asn_stepsincreases.
- Returns:
Attribution tensor matching
inputshape, or tuple(direct, indirect)whenseparate_effects=True. Ifreturn_convergence_delta=True, the delta tensor is appended as the last element of the returned tuple (attributions are wrapped in a tuple if not already one).- Return type:
Tensor | tuple[Tensor, Tensor] | tuple[Tensor, Tensor, Tensor]
- class causalig.attr.CausalExpectedGradients(forward_func)[source]
Causal Expected Gradients (CEG) — single integration step per baseline.
For each baseline b sampled from
baselines, a single interpolated pointx_alpha = b + alpha * (input - b)(withalphadrawn uniformly) is used to estimate the gradient contribution. Attributions are averaged over all baselines.This is a cheaper alternative to
CausalExpectedGradientsMultiStepas described in the original paper introducing Expected Gradients. Use the multi-step variant when higher integration accuracy is required.Attributions are decomposed into:
Direct effects: gradient along the residual path
h = x - surrogate(x).Indirect effects: gradient along the surrogate output path, capturing effects mediated through downstream features.
- Parameters:
forward_func – Model to attribute. Must accept
(batch, d)float tensors and return(batch, C)or(batch,)tensors.
- attribute(input, surrogate, ordering=None, baselines=None, target=None, separate_effects=False, adjacency_matrix=None, baselines_chunk_size=None, dim_chunk_size=None, has_closed_form_jacobian=False, include_second_order_indirect=False, return_convergence_delta=False, seed=None)[source]
Compute CEG attributions (single-step per baseline).
- Parameters:
input (Tensor) – Input tensor
(d,)or(batch, d).surrogate – Trained masked surrogate (autoencoder / regressor). Must accept
(batch, d)and return(batch, d).ordering (list[int] | None) – Topological ordering of feature indices, length
d. Only needed whenadjacency_matrixisNone; otherwise it is derived from the graph.baselines (Tensor | None) – Tensor of baselines
(n_baselines, d)or(d,). Each row is one reference point; attributions are averaged over all rows.target (int) – Output index to attribute for multi-class models.
Noneattributes all outputs simultaneously.separate_effects (bool) – If
Truereturn(direct, indirect)instead of their sum.adjacency_matrix (Tensor | None) – Boolean tensor
(d, d)where[i, j]means feature i causally influences feature j.baselines_chunk_size (int | None) – Number of baselines to process at a time.
Noneprocesses all baselines in one pass.dim_chunk_size (int | None) – Number of feature dimensions to process at a time when computing surrogate Jacobians.
Noneuses all.has_closed_form_jacobian (bool) – Set
Truewhen the surrogate provides an exact input Jacobian in closed form (e.g.MaskedGlobalLinear) to use the faster analytic Jacobian path instead of autograd.include_second_order_indirect (bool) – If
True, add a second-hop indirect term that captures effects propagated through two successive surrogate applications. Defaults toFalse.return_convergence_delta (bool) – If
True, also return a completeness delta:sum(attributions) - (f(input) - mean_b f(baseline_b)). A delta near zero confirms the attributions satisfy the completeness axiom.seed (int | None) – Random seed for stochastic alpha sampling.
- Returns:
Attribution tensor matching
inputshape, or tuple(direct, indirect)whenseparate_effects=True. Ifreturn_convergence_delta=True, the delta tensor is appended as the last element of the returned tuple (attributions are wrapped in a tuple if not already one).- Return type:
Tensor | tuple[Tensor, Tensor] | tuple[Tensor, Tensor, Tensor]
Shapley-value baselines
These require the shap extra (pip install causalig[shap]). They are imported lazily: accessing
causalig.attr.CausalSHAP is what imports shap.
- class causalig.attr.CausalSHAP(forward_func, scm, background=None, n_samples=50, npermutations=10, noise_sigma=0.01, seed=None)[source]
SHAP attributions using causal interventional background samples.
Wraps SHAP’s
PermutationExplainerwith aCausalMaskerso that each coalition’s background distribution is generated viado-calculus on the provided SCM rather than by marginalising over observational data. This gives attributions that respect the causal graph and are not confounded by spurious correlations.- Parameters:
forward_func – Trained PyTorch model (must have
.parameters()).scm – Structural causal model used by
CausalMasker.background – Optional background dataset
(n, d)tensor. Subsampled ton_samplesrows at construction time.n_samples (int) – Number of interventional samples per coalition. Default 50.
npermutations (int) – Number of permutations for SHAP estimation. Default 10.
noise_sigma (float) – Standard deviation of exogenous SCM noise. Default 0.01.
seed (int | None) – Seed for the permutation sampling (and background subsampling). Pass one for reproducible attributions: shap reseeds NumPy’s global RNG when the explainer is created, from fresh entropy if
None. The SCM noise is drawn from torch’s global RNG, so also calltorch.manual_seed.
- attribute(input, npermutations=None)[source]
Compute CausalSHAP attributions.
- Parameters:
input – Input tensor
(batch, d); pass a single sample as(1, d). Converted to numpy internally for SHAP compatibility.npermutations (int | None) – Override the default number of permutations set at construction.
Noneuses the constructor value.
- Returns:
Numpy array of SHAP values,
(batch, d)for a single-output model.
- class causalig.attr.ConditionalSHAP(forward_func, background, type='gaussian', n_samples=50, npermutations=10, seed=None)[source]
SHAP attributions using conditional imputation of masked features.
Wraps SHAP’s
PermutationExplainerwith aConditionalMaskerso that each coalition’s unobserved features are filled from a conditional distribution rather than marginalised independently. This removes the assumption of feature independence made by standard (marginal) SHAP while not requiring a full causal model.- Parameters:
forward_func – Trained PyTorch model (must have
.parameters()).background – Training data
(n, d)used to fit the conditional distribution.type – Conditional sampler type. Currently only
'gaussian'is supported, which fits a multivariate Gaussian tobackground.n_samples (int) – Conditional samples per coalition. Default 50.
npermutations (int) – Permutations for SHAP estimation. Default 10.
seed (int | None) – Seed for the permutation sampling and conditional sampling. Pass one for reproducible attributions: shap reseeds NumPy’s global RNG when the explainer is created, from fresh entropy if
None.
- attribute(input, npermutations=None)[source]
Compute ConditionalSHAP attributions.
- Parameters:
input – Input tensor
(batch, d); pass a single sample as(1, d). Converted to numpy internally for SHAP compatibility.npermutations (int | None) – Override the default number of permutations set at construction.
Noneuses the constructor value.
- Returns:
Numpy array of SHAP values,
(batch, d)for a single-output model.
Maskers and samplers
The building blocks the SHAP baselines use. They are not exported from causalig.attr; import them from
their modules if you need them.
- class causalig.attr._core.causal_shap.CausalMasker(scm, noise_dist, n_samples=50, device=None, background=None, seed=None)[source]
SHAP masker that uses a structural causal model (SCM) to generate interventional background samples.
For each SHAP coalition (defined by a boolean feature mask), the masker performs a
do-intervention on the observed features and samples the remaining features from the SCM, marginalising over noise. This respects the causal structure of the data rather than breaking feature correlations arbitrarily.- Parameters:
scm – Structural causal model with a
forward_do(X_input, noise, do_nodes, do_values)method.noise_dist (Callable[[int, int], Tensor]) – Callable
(batch, p, device) -> Tensorthat samples exogenous noise for the SCM.n_samples (int) – Number of interventional samples to draw per coalition. Higher values reduce variance at the cost of compute. Default 50.
device (device | None) – Device to run computations on. Defaults to CPU.
background (Tensor | None) – Optional background dataset
(n, d)used as the observational starting distribution before intervening. IfNone, a zero background is used.
- __call__(mask, x)[source]
Generate interventional samples for a SHAP coalition.
Called by SHAP’s
PermutationExplainerfor each coalition subset.- Parameters:
mask – Boolean array of length
d;Truemeans the feature is present in the coalition (i.e. intervened on).x – Numpy array of length
d; the instance being explained.
- Returns:
Numpy array of shape
(n_samples, d)containing samples from the interventional distributionP(X | do(X_mask = x_mask)).
- causalig.attr._core.causal_shap.gaussian_noise(batch, p, sigma=1e-06, device=None)[source]
Sample isotropic Gaussian noise for SCM exogenous variables.
- Parameters:
- Returns:
Tensor of shape
(batch, p).- Return type:
- class causalig.attr._core.conditional_shap.ConditionalMasker(conditional_sampler, n_samples=50)[source]
SHAP masker that fills masked features using a conditional sampler.
For each SHAP coalition (boolean mask), the masker calls
conditional_samplerto draw samples of the unobserved features from their conditional distribution given the observed features. This respects marginal feature correlations without requiring a full causal model.- Parameters:
- __call__(mask, x)[source]
Generate conditionally-imputed samples for a SHAP coalition.
Called by SHAP’s
PermutationExplainerfor each coalition subset.- Parameters:
mask – Boolean array of length
d;True= feature is in the coalition (observed),False= feature is masked out.x – Numpy array of length
d; the instance being explained.
- Returns:
Array of shape
(n_samples, d)where unobserved features are filled with conditional samples and observed features are fixed to their values inx.
- class causalig.attr._core.conditional_shap.GaussianConditionalSampler(X_train, ridge=1e-08, max_cache_size=512)[source]
Conditional sampler based on a multivariate Gaussian approximation.
Fits a joint Gaussian to training data and samples from the conditional distribution
p(X_missing | X_observed = x_obs)using the standard Gaussian conditioning formula. Inverse covariance computations are cached per observed-feature coalition to avoid redundant work across SHAP calls.- Parameters:
X_train (ndarray) – Training data array
(n, d)used to estimate the mean and covariance of the joint distribution.ridge (float) – Ridge regularisation added to covariance matrices before inversion for numerical stability. Default
1e-8.max_cache_size (int) – Maximum number of coalition patterns to keep in the LRU cache. Oldest entries are evicted when full. Default 512.
- __call__(x, mask, n_samples=50)[source]
Sample from the Gaussian conditional distribution.
- Parameters:
x – Instance array of length
d.mask – Boolean array of length
d;True= observed.n_samples – Number of samples to draw.
- Returns:
Float32 array of shape
(n_samples, n_missing)containing samples of the unobserved features.
- causalig.attr._core.conditional_shap.gaussian_conditional_sampler(x, mask, n_samples=50, X_train=None)[source]
Convenience wrapper: construct a
GaussianConditionalSamplerand sample once.Prefer constructing
GaussianConditionalSamplerdirectly when the same instance will be called repeatedly (avoids re-fitting the covariance on every call).- Parameters:
x – Instance array of length
d.mask – Boolean array of length
d;True= observed.n_samples – Number of conditional samples to draw.
X_train (ndarray | None) – Training data
(n, d)used to estimate the distribution.
- Returns:
Float32 array of shape
(n_samples, n_missing).