Skip to content

v1.8.0 (2026-10-20)

Latest

Choose a tag to compare

@mmschlk mmschlk released this 20 Oct 08:45
· 65 commits to main since this release
91f05b8

v1.8.0 (2026-10-20)

New PolySHAP Approximator #559

Adds the PolySHAP approximator in shapiq.approximator.regression for Shapley value estimation via interaction-informed polynomial regression (Fumagalli et al., 2026). PolySHAP generalizes KernelSHAP by fitting a k-additive polynomial surrogate of the game before reading off the Shapley values. The estimator can be used with a pre-defined set of interactions to estimate on. This interaction frontier can be the full k-additive frontier up to max_order (with max_order=1 recovering KernelSHAP), a budget-controlled partial frontier (max_terms), or a user-supplied set of interaction terms (prior_frontier). It is registered as a Shapley value (SV) approximator.

Harmonized shapiq_games and shapiq_benchmark #616

We made both shapiq_games and shapiq_benchmark into sub-packages and improved its usability for evaluating. Note, this is still under development and might change in the near future. The games and the benchmark need the new extras shapiq[games] and shapiq[benchmark].

  1. shapiq_games is a tested collection of game definitions we encountered in the wild. It replaces the about 130 dataset-specific classes of shapiq_games.benchmark. We made the existing infrastructure for creating games more stable and added new ones, such as DINOv2 in ImageClassifier, CLIP in ImageTextSimilarity (which also explains SigLIP and SigLIP 2), and TabPFN with absent features as +inf (TabularLocalExplanation(imputer="baseline", baseline=np.inf)).

  2. shapiq_benchmark is a package for evaluating estimators. It builds games from names (shapiq_benchmark.setups), downloads and caches datasets on first use, and computes exact values with shapiq's algorithms (Benchmark(game), Benchmark.from_setup(setup), run). Importanlty, no data files ship in the wheel anymore (previously ~89 MB).

Note, that moving games and datasets into separate packages also added some breaking changes in obscure places:

  • the ground-truth games move out of core: shapiq.tree.InterventionalGame is now shapiq_games.tree.InterventionalTreeGame, shapiq.explainer.nn.games is now shapiq_games.nn, and shapiq.explainer.product_kernel.game.ProductKernelGame is now shapiq_games.kernel.ProductKernelGame.
  • removes shapiq.datasets and shapiq.load_california_housing, load_bike_sharing and load_adult_census: load them with shapiq_benchmark.datasets.load_dataset (california_housing comes from scikit-learn; bike_sharing and adult_census come from OpenML and need shapiq[benchmark]) or scikit-learn's fetchers.

Better Documentation #622

We started reworking the documentation wich makes it easier to get into the core of the library. The rework adds a new landing page, adds more examples and groups them, adds an interactive timeline of Shapley-based methods, an API reference for shapiq_games and shapiq_benchmark, and a consistent bibliography of every cited work.

"Fourier" and "Moebius" Support #596

  • adds the "Fourier" (Walsh-Hadamard) transform as an index F(S) = (-1/2)^|S| BII(S). The index is computable by ExactComputer and by TreeExplainer in both modes (path-dependent through QuadratureTreeSHAP, interventional through InterventionalTreeSHAPIQ).
  • adds "Moebius" index computation to TreeExplainer in both modes (path-dependent through QuadratureTreeSHAP, interventional through InterventionalTreeSHAPIQ and Woodelf).

Bugfixes

  • fixes ProxySPEX aggregating index="k-SII" twice. #596
  • fixes path-dependent TreeExplainer/QuadratureTreeSHAP dropping zero-cover subtree whenever the explained point's routing enters it, which could occur via the default paths routing. A zero-cover node now splits its (zero) mass equally among its children. #617
  • fixes InterventionalTreeSHAPIQ(weight_fn=...) dropping interactions sizes equal to |E| + |R|. #619
  • fixes TreeExplainer with class_index=0 on binary gradient boosting classifiers (scikit-learn GradientBoostingClassifier and HistGradientBoostingClassifier, XGBClassifier, LGBMClassifier, CatBoostClassifier) silently returning the class-1 explanation in both mode="pathdependent" and mode="interventional". #618
  • fixes TreeExplainer with class_index=None on a multiclass LightGBM model explaining raw marginals, it now explains class 1, consistent with all other libraries. #618
  • fixes bias in the cross-fitted MSR residual adjustment of ProxySHAP and RegressionMSR (k_folds > 1), now applying the correct size-conditional scaling of held-out residuals. #606
  • fixes MarginalImputer having wrong baseline_value (computed over the whole dataset) and v(S) (computed on a subsample of data). Now both are based on the subsample of background rows created by init_background and controlled via sample_size (using all when sample_size=None). #615
  • fixes OddSHAP scaling not beyond 1,030 players, by switching to log space adjustment weights, as in the other regression approximators. #621

Maintenance

  • adds support for Python 3.15 (wheels built with CPython 3.15).
  • more control over the number of background datasets in MarginalImputer via sample_size. All rows of the dataset are used with sample_size=None, and a background with fewer rows than sample_size is used in full( default sample_size=100). The sample size must be bigger than 1, indicated by a ValueError otherwise. #615
  • vectorizes MarginalImputer.value_function. Imputed rows are now passed ot the model in a single call (or chunked to at most 2^20 elements), instead of one model call per background row. #615
  • adding a warning in  TabularExplainer that the marginal imputer only uses a subsample of background data. Passing sample_size explicitly silences the warning. #615
  • exposing ProductKernelExplainer to be used from shapiq.explainer. #622
  • the documentation build runs on request only (label build docs or the Actions tab) #622
  • speeds up InterventionalTreeSHAPIQ (TreeExplainer(mode="interventional")) for higher-order interactions #619
  • unifies QuadratureTreeSHAP and InterventionalTreeSHAPIQ to share the C++ preprocessing. #619
  • ProxySPEX and OddSHAP read the Fourier coefficients of their tree proxies with the new interventional C++ kernel (tree_to_fourier) instead of Python recursions. #596
  • constructing an InteractionValues from an array and an interaction_lookup is several times faster (one vectorised gather instead of a numpy scalar lookup per interaction). #619

All PRs

  • Feature/woodelf stii fsii fbii by @ron-wettenstein in #595
  • Bugfix of ProxySHAP Convergence by @Advueu963 in #606
  • Fix Game passing int/float 0/1 coalitions to value_function unchanged by @mmschlk in #614
  • Fix TreeExplainer class selection: class_index=0 on binary boosters, out-of-range indices, LightGBM default by @mmschlk in #618
  • Fix MarginalImputer empty-coalition estimator, improve sample_size handling, vectorize evaluation by @mmschlk in #615
  • Feature/speedup quadrature tree shap by @ron-wettenstein in #594
  • Speedups for InterventionalTreeSHAPIQ and QuadratureSHAP by @Advueu963 in #619
  • Harmonize shapiq_games and shapiq_benchmark by @mmschlk in #616
  • Fix path-dependent TreeSHAP dropping zero-cover subtrees entered by the explained point by @mmschlk in #617
  • Add Python 3.15 support by @mmschlk in #620
  • Feature/mobius and fourier for trees by @ron-wettenstein in #596
  • Rework the documentation: grouped examples, a timeline of methods, one bibliography by @mmschlk in #622
  • Delete AGENTS.md by @mmschlk in #624
  • Docs: logo springs follow the interaction strength, ripple and scroll bump by @mmschlk in #625
  • Fix OddSHAP failing for more than ~1,030 players (#621) by @mmschlk in #623
  • Docs: faster builds on Read the Docs by @mmschlk in #626
  • Add PolySHAP Approximator by @ThrashLion in #559

New Contributors

Full Changelog: v1.7.0...v1.8.0