xai4tsc.xai.feature_attribution =============================== .. py:module:: xai4tsc.xai.feature_attribution .. autoapi-nested-parse:: Captum-backed feature attribution explainers (IG, DeepLIFT, Occlusion, ...). Also hosts :class:`TSHAPExplainer`, a pure-NumPy perturbation method (exact 2-player Shapley over time windows) that only queries ``model.predict``. Attributes ---------- .. autoapisummary:: xai4tsc.xai.feature_attribution.logger Classes ------- .. autoapisummary:: xai4tsc.xai.feature_attribution.IntegratedGradientsExplainer xai4tsc.xai.feature_attribution.DeepLiftExplainer xai4tsc.xai.feature_attribution.DeconvolutionExplainer xai4tsc.xai.feature_attribution.GuidedBackpropagationExplainer xai4tsc.xai.feature_attribution.OcclusionExplainer xai4tsc.xai.feature_attribution.TSHAPExplainer Module Contents --------------- .. py:data:: logger .. py:class:: IntegratedGradientsExplainer(multiply_by_inputs: bool = True, n_steps: int = 50, integration_method: str = 'gausslegendre', baselines: int = 0, internal_batch_size: int | None = None) Bases: :py:obj:`xai4tsc.xai.base.GradientExplainer` Feature attribution via Integrated Gradients (Captum). :param multiply_by_inputs: Multiply attributions by ``(input - baseline)``. Matches the standard IG formulation. :type multiply_by_inputs: bool :param n_steps: Number of steps along the integration path. Higher values give more accurate approximations at the cost of compute. :type n_steps: int :param integration_method: Quadrature rule for approximating the integral. One of ``"gausslegendre"`` (default), ``"riemann_trapezoid"``, ``"riemann_middle"``, ``"riemann_right"``, ``"riemann_left"``. :type integration_method: str :param baselines: Reference input value used as the integration baseline. :type baselines: int or float :param internal_batch_size: Split the integration steps into sub-batches of this size to reduce memory usage. ``None`` processes all steps at once. :type internal_batch_size: int or None .. py:attribute:: data_applicability :type: ClassVar[set[xai4tsc.xai._types.DataType]] Gradient attribution is domain-agnostic — applies to any input. .. py:class:: DeepLiftExplainer(multiply_by_inputs: bool = True, eps: float = 1e-10) Bases: :py:obj:`xai4tsc.xai.base.GradientExplainer` Feature attribution via DeepLIFT (Captum). :param multiply_by_inputs: Multiply contribution scores by ``(input - reference)``. Matches the original DeepLIFT paper formulation. :type multiply_by_inputs: bool :param eps: Small constant added for numerical stability in gradient computation. :type eps: float .. py:attribute:: data_applicability :type: ClassVar[set[xai4tsc.xai._types.DataType]] Data domains this explainer applies to. A set of :class:`~xai4tsc.xai.DataType` members — ``{DataType.AGNOSTIC}`` (any input) or ``{DataType.TIME_SERIES}``. .. py:class:: DeconvolutionExplainer Bases: :py:obj:`xai4tsc.xai.base.GradientExplainer` Feature attribution via Deconvolution (Captum). .. py:attribute:: data_applicability :type: ClassVar[set[xai4tsc.xai._types.DataType]] Data domains this explainer applies to. A set of :class:`~xai4tsc.xai.DataType` members — ``{DataType.AGNOSTIC}`` (any input) or ``{DataType.TIME_SERIES}``. .. py:class:: GuidedBackpropagationExplainer Bases: :py:obj:`xai4tsc.xai.base.GradientExplainer` Feature attribution via Guided Backpropagation (Captum). .. py:attribute:: data_applicability :type: ClassVar[set[xai4tsc.xai._types.DataType]] Data domains this explainer applies to. A set of :class:`~xai4tsc.xai.DataType` members — ``{DataType.AGNOSTIC}`` (any input) or ``{DataType.TIME_SERIES}``. .. py:class:: OcclusionExplainer(window_shape: list | None = None, baseline: int = 0, strides: int = 4) Bases: :py:obj:`xai4tsc.xai.base.PerturbationExplainer` Feature attribution via Occlusion (Captum). :param window_shape: Shape of the sliding occlusion window, e.g. ``[1, 5]``. :type window_shape: list :param baseline: Value used to fill the occluded region. :type baseline: int or float :param strides: Step size of the sliding window. :type strides: int .. py:attribute:: data_applicability :type: ClassVar[set[xai4tsc.xai._types.DataType]] Data domains this explainer applies to. A set of :class:`~xai4tsc.xai.DataType` members — ``{DataType.AGNOSTIC}`` (any input) or ``{DataType.TIME_SERIES}``. .. py:attribute:: window_shape .. py:attribute:: baseline :value: 0 .. py:attribute:: strides :value: 4 .. py:method:: explain(model: torch.nn.Module, exp: xai4tsc.xai._types.Explanation, device: str | torch.device, targets: list | None, **kwargs: object) -> numpy.ndarray Compute occlusion attributions for the samples in *exp*. .. py:class:: TSHAPExplainer(window_length: float | int = 0.1, stride: int = 5, perturb_baseline: str = 'centroid', perturb_func: str | collections.abc.Callable | None = None, n_perturb_samples: int = 1, channel_mode: str = 'shared', roi: bool = False, background_data: numpy.ndarray | None = None, seed: int | None = None) Bases: :py:obj:`xai4tsc.xai.base.PerturbationExplainer` Feature attribution via TSHAP — exact 2-player Shapley over time windows. For a sample ``x`` and a background series ``x̄``, the exact Shapley value of a window ``w`` (the timesteps inside it, with ``w̄`` the rest) is .. math:: \varphi(w) = \tfrac12\,[\,f(x) - f(\{\bar x_w, x_{\bar w}\}) + f(\{x_w, \bar x_{\bar w}\}) - f(\bar x)\,] where ``f`` is the predicted probability of the per-sample target class. ``{x̄_w, x_w̄}`` masks the window (inside replaced by background, rest original) and ``{x_w, x̄_w̄}`` keeps only the window (rest replaced by background). Per-timestep relevance is the mean of ``φ(w) / window_length`` over all windows containing that timestep. With ``stride > 1`` the Shapley value is computed only at strided window starts and linearly interpolated in between. .. note:: The per-window Shapley values are identical to the original ``mlgig/tshap`` reference implementation (verified to machine precision). The per-timestep aggregation here follows the paper's Eq. 9 — the **mean** over the windows covering each timestep (i.e. divided by the coverage count). The reference *code* instead **sums** ``φ(w) / window_length`` without dividing by the coverage count, so its per-timestep magnitudes equal these multiplied by the per-timestep coverage count. This implementation is the paper-faithful one. :param window_length: Window size. A float in ``(0, 1]`` is a fraction of the series length ``T``; an int is an absolute number of timesteps. :type window_length: float or int :param stride: Compute the Shapley value every ``stride`` window starts and interpolate the rest. ``1`` evaluates every window. :type stride: int :param perturb_baseline: Background strategy (see :func:`xai4tsc.utils.perturbation.baseline_replacement`): ``"centroid"`` (default), ``"black"``, ``"white"``, ``"mean"`` or ``"random"``. ``"centroid"`` requires *background_data*; without it a warning is emitted and ``"mean"`` is used. :type perturb_baseline: str :param perturb_func: Override the perturbation function. A callable, a baseline name, a ``quantus`` attribute name, or a dotted import path. ``None`` uses the built-in :func:`baseline_replacement`. :type perturb_func: str or callable, optional :param n_perturb_samples: Number of background draws to average over (Eq. 8). Only meaningful for the stochastic ``"random"`` baseline. :type n_perturb_samples: int :param channel_mode: ``"shared"`` (default) — a window spans all channels and one Shapley value is broadcast to every channel (cost independent of ``C``). ``"per_channel"`` — each ``(channel, window)`` is its own player, giving a channel-resolved map at ``C`` times the cost (an extension beyond the paper's univariate scope). :type channel_mode: str :param roi: If ``True`` apply TSHAP-ROI (Algorithm 2): keep only windows whose ``|φ(w)|`` exceeds ``0.1 · max|φ(w)|``, merge consecutive kept windows into regions, recompute one Shapley value per region, and assign it uniformly inside the region (zero elsewhere). :type roi: bool :param background_data: Background samples of shape ``(n, C, T)``. The centroid ``background_data.mean(axis=0)`` is used as the ``"centroid"`` reference. The runner resolves the YAML ``background_data`` selector to this array; passing a non-array raises (selectors are a runner-only concept). :type background_data: np.ndarray, optional :param seed: Seed for the random baseline, for reproducible draws. :type seed: int, optional .. py:attribute:: explanation_type :value: 'feature_attribution' Type of explanation produced by this explainer. .. py:attribute:: data_applicability :type: ClassVar[set[xai4tsc.xai._types.DataType]] TSHAP is a time-series-specific perturbation method (windows over time). .. py:attribute:: window_length :value: 0.1 .. py:attribute:: stride .. py:attribute:: channel_mode :value: 'shared' .. py:attribute:: roi :value: False .. py:attribute:: n_perturb_samples .. py:attribute:: prng .. py:attribute:: perturb_baseline :value: 'centroid' .. py:attribute:: centroid :type: numpy.ndarray | None :value: None .. py:method:: explain(model: torch.nn.Module, exp: xai4tsc.xai._types.Explanation, device: str | torch.device, targets: list | None, **kwargs: object) -> numpy.ndarray Compute TSHAP attributions for the samples in *exp*.