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 CausalExpectedGradientsMultiStep with a single baseline: it integrates the causal gradient along the linear path from baseline to input, 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 CausalExpectedGradientsMultiStep and exists as a convenience wrapper with the single-baseline API (baseline instead of baselines).

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 when adjacency_matrix is None; otherwise it is derived from the graph.

  • baseline (Tensor | None) – Baseline tensor (d,), shared by every input in the batch. The integration path runs from baseline to input.

  • 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 None all outputs are attributed simultaneously.

  • separate_effects (bool) – If True return (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. None processes all steps at once.

  • dim_chunk_size (int | None) – Process this many feature dimensions at a time when computing surrogate Jacobians. None processes all dimensions at once.

  • has_closed_form_jacobian (bool) – Set True when 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 to False.

  • 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 as n_steps increases.

Returns:

Attribution tensor of shape matching input, or tuple (direct, indirect) when separate_effects=True. If return_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 to input using n_steps Riemann steps, mirroring CausalIntegratedGradients. Attributions are then averaged over all baselines.

CausalIntegratedGradients is 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 when adjacency_matrix is None; 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. None attributes all outputs simultaneously.

  • separate_effects (bool) – If True return (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. None processes all baselines at once.

  • step_chunk_size (int | None) – Number of integration steps to process per pass. Must be > 1 or None. None processes all steps at once.

  • dim_chunk_size (int | None) – Number of feature dimensions per surrogate Jacobian pass. None uses all dimensions at once.

  • has_closed_form_jacobian (bool) – Set True when 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 to False.

  • 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 as n_steps increases.

Returns:

Attribution tensor matching input shape, or tuple (direct, indirect) when separate_effects=True. If return_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 point x_alpha = b + alpha * (input - b) (with alpha drawn uniformly) is used to estimate the gradient contribution. Attributions are averaged over all baselines.

This is a cheaper alternative to CausalExpectedGradientsMultiStep as 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 when adjacency_matrix is None; 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. None attributes all outputs simultaneously.

  • separate_effects (bool) – If True return (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. None processes all baselines in one pass.

  • dim_chunk_size (int | None) – Number of feature dimensions to process at a time when computing surrogate Jacobians. None uses all.

  • has_closed_form_jacobian (bool) – Set True when 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 to False.

  • 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 input shape, or tuple (direct, indirect) when separate_effects=True. If return_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 PermutationExplainer with a CausalMasker so that each coalition’s background distribution is generated via do-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 to n_samples rows 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 call torch.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. None uses 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 PermutationExplainer with a ConditionalMasker so 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 to background.

  • 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. None uses 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) -> Tensor that 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. If None, a zero background is used.

__call__(mask, x)[source]

Generate interventional samples for a SHAP coalition.

Called by SHAP’s PermutationExplainer for each coalition subset.

Parameters:
  • mask – Boolean array of length d; True means 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 distribution P(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:
  • batch (int) – Number of noise samples to draw.

  • p (int) – Number of features (noise dimensions).

  • sigma (float) – Standard deviation. Defaults to 1e-6 (near-zero noise, used when the SCM is evaluated near-deterministically).

  • device (device | None) – Target device.

Returns:

Tensor of shape (batch, p).

Return type:

Tensor

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_sampler to 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:
  • conditional_sampler (Callable) – Callable with signature (x, mask, n_samples) -> array (n_samples, n_masked). Given instance x and boolean mask, returns conditional samples for the masked (False) features.

  • n_samples (int) – Number of conditional samples per coalition. Default 50.

__call__(mask, x)[source]

Generate conditionally-imputed samples for a SHAP coalition.

Called by SHAP’s PermutationExplainer for 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 in x.

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 GaussianConditionalSampler and sample once.

Prefer constructing GaussianConditionalSampler directly 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).