• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mmschlk / shapiq / 18688052885

21 Oct 2025 02:53PM UTC coverage: 93.058% (+0.008%) from 93.05%
18688052885

Pull #435

github

web-flow
Merge d8acf3d1f into ac5614648
Pull Request #435: Gaussian and copula imputer

161 of 172 new or added lines in 7 files covered. (93.6%)

4 existing lines in 2 files now uncovered.

5188 of 5575 relevant lines covered (93.06%)

0.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.42
/src/shapiq/explainer/tabular.py
1
"""Tabular Explainer class for the shapiq package."""
2

3
from __future__ import annotations
1✔
4

5
from typing import TYPE_CHECKING, Any, Literal
1✔
6
from warnings import warn
1✔
7

8
from shapiq.explainer.base import Explainer
1✔
9
from shapiq.game_theory.indices import is_empty_value_the_baseline
1✔
10

11
from .configuration import setup_approximator
1✔
12
from .custom_types import ExplainerIndices
1✔
13

14
if TYPE_CHECKING:
1✔
15
    import numpy as np
×
16

17
    from shapiq.approximator.base import Approximator
×
18
    from shapiq.imputer.base import Imputer
×
19
    from shapiq.interaction_values import InteractionValues
×
20
    from shapiq.typing import Model
×
21

22

23
TabularExplainerApproximators = Literal["spex", "montecarlo", "svarm", "permutation", "regression"]
1✔
24
TabularExplainerImputers = Literal["marginal", "baseline", "conditional"]
1✔
25
TabularExplainerIndices = ExplainerIndices
1✔
26

27

28
class TabularExplainer(Explainer):
1✔
29
    """The tabular explainer as the main interface for the shapiq package.
30

31
    The ``TabularExplainer`` class is the main interface for the ``shapiq`` package and tabular
32
    data. It can be used to explain the predictions of any model by estimating the Shapley
33
    interaction values.
34

35
    Attributes:
36
        index: Type of Shapley interaction index to use.
37
        data: A background data to use for the explainer.
38

39
    Properties:
40
        baseline_value: A baseline value of the explainer.
41

42
    """
43

44
    def __init__(
1✔
45
        self,
46
        model: Model,
47
        data: np.ndarray,
48
        *,
49
        class_index: int | None = None,
50
        imputer: Imputer | TabularExplainerImputers = "marginal",
51
        approximator: Literal["auto"]
52
        | TabularExplainerApproximators
53
        | Approximator[TabularExplainerIndices] = "auto",
54
        index: TabularExplainerIndices = "k-SII",
55
        max_order: int = 2,
56
        random_state: int | None = None,
57
        verbose: bool = False,
58
        **kwargs: Any,
59
    ) -> None:
60
        """Initializes the TabularExplainer.
61

62
        Args:
63
            model: The model to be explained as a callable function expecting data points as input
64
                and returning 1-dimensional predictions.
65

66
            data: A background dataset to be used for imputation.
67

68
            class_index: The class index of the model to explain. Defaults to ``None``, which will
69
                set the class index to ``1`` per default for classification models and is ignored
70
                for regression models.
71

72
            imputer: Either an :class:`~shapiq.games.imputer.Imputer` as implemented in the
73
                :mod:`~shapiq.games.imputer` module, or a literal string from
74
                ``["marginal", "baseline", "conditional"]``. Defaults to ``"marginal"``, which
75
                initializes the default
76
                :class:`~shapiq.games.imputer.marginal_imputer.MarginalImputer` with its default
77
                parameters or as provided in ``kwargs``.
78

79
            approximator: An :class:`~shapiq.approximator.Approximator` object to use for the
80
                explainer or a literal string from
81
                ``["auto", "spex", "montecarlo", "svarm", "permutation"]``. Defaults to ``"auto"``
82
                which will automatically choose the approximator based on the number of features and
83
                the desired index.
84
                    - for index ``"SV"``: :class:`~shapiq.approximator.KernelSHAP`
85
                    - for index ``"SII"`` or ``"k-SII"``: :class:`~shapiq.approximator.KernelSHAPIQ`
86
                    - for index ``"FSII"``: :class:`~shapiq.approximator.RegressionFSII`
87
                    - for index ``"FBII"``: :class:`~shapiq.approximator.RegressionFBII`
88
                    - for index ``"STII"``: :class:`~shapiq.approximator.SVARMIQ`
89

90
            index: The index to explain the model with. Defaults to ``"k-SII"`` which computes the
91
                k-Shapley Interaction Index. If ``max_order`` is set to 1, this corresponds to the
92
                Shapley value (``index="SV"``). Options are:
93
                    - ``"SV"``: Shapley value
94
                    - ``"k-SII"``: k-Shapley Interaction Index
95
                    - ``"FSII"``: Faithful Shapley Interaction Index
96
                    - ``"FBII"``: Faithful Banzhaf Interaction Index (becomes ``BV`` for order 1)
97
                    - ``"STII"``: Shapley Taylor Interaction Index
98
                    - ``"SII"``: Shapley Interaction Index
99

100
            max_order: The maximum interaction order to be computed. Defaults to ``2``. Set to
101
                ``1`` for no interactions (single feature importance).
102

103
            random_state: The random state to initialize Imputer and Approximator with. Defaults to
104
                ``None``.
105

106
            verbose: Whether to show a progress bar during the computation. Defaults to ``False``.
107

108
            **kwargs: Additional keyword-only arguments passed to the imputers implemented in
109
                :mod:`~shapiq.games.imputer`.
110
        """
111
        from shapiq.imputer import (
1✔
112
            BaselineImputer,
113
            GenerativeConditionalImputer,
114
            MarginalImputer,
115
            TabPFNImputer,
116
        )
117

118
        super().__init__(model, data, class_index, index=index, max_order=max_order)
1✔
119

120
        # get class for self
121
        class_name = self.__class__.__name__
1✔
122
        if self._model_type == "tabpfn" and class_name == "TabularExplainer":
1✔
123
            warn(
1✔
124
                "You are using a TabPFN model with the ``shapiq.TabularExplainer`` directly. This "
125
                "is not recommended as it uses missing value imputation and not contextualization. "
126
                "Consider using the ``shapiq.TabPFNExplainer`` instead. For more information see "
127
                "the documentation and the example notebooks.",
128
                stacklevel=2,
129
            )
130

131
        if imputer == "marginal":
1✔
132
            self._imputer = MarginalImputer(
1✔
133
                self.predict,
134
                self._data,
135
                random_state=random_state,
136
                **kwargs,
137
            )
138
        elif imputer == "conditional":
1✔
139
            self._imputer = GenerativeConditionalImputer(
1✔
140
                self.predict,
141
                self._data,
142
                random_state=random_state,
143
                **kwargs,
144
            )
145
        elif imputer == "baseline":
1✔
146
            self._imputer = BaselineImputer(
1✔
147
                self.predict,
148
                self._data,
149
                random_state=random_state,
150
                **kwargs,
151
            )
152
        elif isinstance(
1✔
153
            imputer,
154
            MarginalImputer | GenerativeConditionalImputer | BaselineImputer | TabPFNImputer,
155
        ):
156
            self._imputer = imputer
1✔
157
            self._imputer = imputer
1✔
158
        else:
UNCOV
159
            msg = (
×
160
                f"Invalid imputer {imputer}. "
161
                f'Must be one of ["marginal", "baseline", "conditional"], or a valid Imputer '
162
                f"object."
163
            )
UNCOV
164
            raise ValueError(msg)
×
165
        self._n_features: int = self._data.shape[1]
1✔
166
        self.imputer.verbose = verbose  # set the verbose flag for the imputer
1✔
167

168
        self._approximator = setup_approximator(
1✔
169
            approximator,
170
            self.index,
171
            self._max_order,
172
            self._n_features,
173
            random_state,
174
        )
175

176
    def explain_function(
1✔
177
        self,
178
        x: np.ndarray,
179
        budget: int,
180
        *,
181
        random_state: int | None = None,
182
    ) -> InteractionValues:
183
        """Explains the model's predictions.
184

185
        Args:
186
            x: The data point to explain as a 2-dimensional array with shape
187
                (1, n_features).
188

189
            budget: The budget to use for the approximation. It indicates how many coalitions are
190
                sampled, thus high values indicate more accurate approximations, but induce higher
191
                computational costs.
192

193
            random_state: The random state to re-initialize Imputer and Approximator with.
194
                Defaults to ``None``, which will not set a random state.
195

196
        Returns:
197
            An object of class :class:`~shapiq.interaction_values.InteractionValues` containing
198
            the computed interaction values.
199
        """
200
        self.set_random_state(random_state)
1✔
201

202
        # initialize the imputer with the explanation point
203
        self.imputer.fit(x)
1✔
204

205
        # explain
206
        interaction_values = self.approximator(budget=budget, game=self.imputer)
1✔
207
        interaction_values.baseline_value = self.baseline_value
1✔
208
        # Adjust the Baseline Value if the empty value is the baseline
209
        if is_empty_value_the_baseline(interaction_values.index):
1✔
210
            interaction_values[()] = interaction_values.baseline_value
1✔
211
        return interaction_values
1✔
212

213
    @property
1✔
214
    def baseline_value(self) -> float:
1✔
215
        """Returns the baseline value of the explainer."""
216
        return self.imputer.empty_prediction
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc