Repository navigation
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].
-
shapiq_gamesis a tested collection of game definitions we encountered in the wild. It replaces the about 130 dataset-specific classes ofshapiq_games.benchmark. We made the existing infrastructure for creating games more stable and added new ones, such as DINOv2 inImageClassifier, CLIP inImageTextSimilarity(which also explains SigLIP and SigLIP 2), and TabPFN with absent features as+inf(TabularLocalExplanation(imputer="baseline", baseline=np.inf)). -
shapiq_benchmarkis 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.InterventionalGameis nowshapiq_games.tree.InterventionalTreeGame,shapiq.explainer.nn.gamesis nowshapiq_games.nn, andshapiq.explainer.product_kernel.game.ProductKernelGameis nowshapiq_games.kernel.ProductKernelGame. - removes
shapiq.datasetsandshapiq.load_california_housing,load_bike_sharingandload_adult_census: load them withshapiq_benchmark.datasets.load_dataset(california_housingcomes from scikit-learn;bike_sharingandadult_censuscome from OpenML and needshapiq[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 indexF(S) = (-1/2)^|S| BII(S). The index is computable byExactComputerand byTreeExplainerin both modes (path-dependent throughQuadratureTreeSHAP, interventional throughInterventionalTreeSHAPIQ). - adds
"Moebius"index computation toTreeExplainerin both modes (path-dependent throughQuadratureTreeSHAP, interventional throughInterventionalTreeSHAPIQand Woodelf).
Bugfixes
- fixes
ProxySPEXaggregatingindex="k-SII"twice. #596 - fixes path-dependent
TreeExplainer/QuadratureTreeSHAPdropping 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
TreeExplainerwithclass_index=0on binary gradient boosting classifiers (scikit-learnGradientBoostingClassifierandHistGradientBoostingClassifier,XGBClassifier,LGBMClassifier,CatBoostClassifier) silently returning the class-1 explanation in bothmode="pathdependent"andmode="interventional". #618 - fixes
TreeExplainerwithclass_index=Noneon 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
ProxySHAPandRegressionMSR(k_folds > 1), now applying the correct size-conditional scaling of held-out residuals. #606 - fixes
MarginalImputerhaving wrongbaseline_value(computed over the whole dataset) andv(S)(computed on a subsample of data). Now both are based on the subsample of background rows created byinit_backgroundand controlled viasample_size(using all whensample_size=None). #615 - fixes
OddSHAPscaling 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
MarginalImputerviasample_size. All rows of the dataset are used withsample_size=None, and a background with fewer rows thansample_sizeis used in full( defaultsample_size=100). The sample size must be bigger than1, indicated by aValueErrorotherwise. #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
TabularExplainerthat the marginal imputer only uses a subsample of background data. Passingsample_sizeexplicitly silences the warning. #615 - exposing
ProductKernelExplainerto be used fromshapiq.explainer. #622 - the documentation build runs on request only (label
build docsor the Actions tab) #622 - speeds up
InterventionalTreeSHAPIQ(TreeExplainer(mode="interventional")) for higher-order interactions #619 - unifies
QuadratureTreeSHAPandInterventionalTreeSHAPIQto share the C++ preprocessing. #619 ProxySPEXandOddSHAPread the Fourier coefficients of their tree proxies with the new interventional C++ kernel (tree_to_fourier) instead of Python recursions. #596- constructing an
InteractionValuesfrom an array and aninteraction_lookupis 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_gamesandshapiq_benchmarkby @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
- @ThrashLion made their first contribution in #559
Full Changelog: v1.7.0...v1.8.0