shapiq 1.3.0__tar.gz → 1.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {shapiq-1.3.0 → shapiq-1.3.2}/CHANGELOG.md +37 -19
- {shapiq-1.3.0/shapiq.egg-info → shapiq-1.3.2}/PKG-INFO +40 -22
- {shapiq-1.3.0 → shapiq-1.3.2}/pyproject.toml +22 -4
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/__init__.py +3 -1
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tabpfn.py +6 -8
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tabular.py +0 -3
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/base.py +21 -17
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/conversion/edges.py +11 -6
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/utils.py +12 -6
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/base.py +202 -73
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/local_xai/base.py +3 -7
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/local_xai/benchmark_language.py +11 -1
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/setup.py +5 -1
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/imputer/conditional_imputer.py +1 -1
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/imputer/tabpfn_imputer.py +5 -3
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/interaction_values.py +136 -40
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/__init__.py +2 -0
- shapiq-1.3.2/shapiq/plot/beeswarm.py +425 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/si_graph.py +1 -1
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/utils.py +1 -1
- shapiq-1.3.2/shapiq/py.typed +0 -0
- shapiq-1.3.2/shapiq/typing.py +72 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/utils/__init__.py +3 -3
- shapiq-1.3.2/shapiq/utils/errors.py +19 -0
- shapiq-1.3.2/shapiq/utils/saving.py +116 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/utils/sets.py +25 -16
- {shapiq-1.3.0 → shapiq-1.3.2/shapiq.egg-info}/PKG-INFO +40 -22
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq.egg-info/SOURCES.txt +5 -1
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq.egg-info/requires.txt +1 -1
- shapiq-1.3.0/shapiq/utils/custom_types.py +0 -30
- {shapiq-1.3.0 → shapiq-1.3.2}/LICENSE +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/README.md +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/setup.cfg +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/base.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/marginals/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/marginals/owen.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/marginals/stratified.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/montecarlo/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/montecarlo/base.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/montecarlo/shapiq.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/montecarlo/svarmiq.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/permutation/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/permutation/sii.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/permutation/stii.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/permutation/sv.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/regression/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/regression/base.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/regression/faithful.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/regression/kadd_shap.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/regression/kernelshap.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/regression/kernelshapiq.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/sampling.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/sparse/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/sparse/base.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/sparse/spex.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/benchmark/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/benchmark/configuration.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/benchmark/load.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/benchmark/metrics.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/benchmark/plot.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/benchmark/precompute.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/benchmark/run.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/datasets/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/datasets/_all.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/agnostic.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/base.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/configuration.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/custom_types.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/conversion/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/conversion/lightgbm.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/conversion/sklearn.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/conversion/xgboost.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/explainer.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/treeshapiq.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/validation.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/utils.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/validation.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/game_theory/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/game_theory/aggregation.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/game_theory/core.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/game_theory/exact.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/game_theory/indices.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/game_theory/moebius_converter.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/_setup/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/_setup/_california_torch_setup.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/_setup/_resnet_setup.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/_setup/_vit_setup.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/data_valuation/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/data_valuation/base.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/data_valuation/benchmark.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/dataset_valuation/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/dataset_valuation/base.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/dataset_valuation/benchmark.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/ensemble_selection/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/ensemble_selection/base.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/ensemble_selection/benchmark.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/ensemble_selection/benchmark_random_forest.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/feature_selection/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/feature_selection/base.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/feature_selection/benchmark.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/global_xai/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/global_xai/base.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/global_xai/benchmark_tabular.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/local_xai/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/local_xai/benchmark_image.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/local_xai/benchmark_tabular.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/synthetic/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/synthetic/dummy.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/synthetic/random_game.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/synthetic/soum.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/treeshapiq_xai/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/treeshapiq_xai/base.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/treeshapiq_xai/benchmark.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/uncertainty/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/uncertainty/base.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/uncertainty/benchmark.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/unsupervised_cluster/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/unsupervised_cluster/base.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/unsupervised_cluster/benchmark.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/unsupervised_data/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/unsupervised_data/base.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/unsupervised_data/benchmark.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/imputer/__init__.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/imputer/base.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/imputer/baseline_imputer.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/imputer/marginal_imputer.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/_config.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/bar.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/force.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/network.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/sentence.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/stacked_bar.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/upset.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/waterfall.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/utils/datasets.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/utils/modules.py +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq.egg-info/dependency_links.txt +0 -0
- {shapiq-1.3.0 → shapiq-1.3.2}/shapiq.egg-info/top_level.txt +0 -0
|
@@ -1,13 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## v1.3.2 (2025-10-14)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### Hotfix
|
|
6
|
+
Removes `overrides` import in tabular explainer, which is not part of the package dependencies resulting in an ImportError when importing `shapiq`. [#436](https://github.com/mmschlk/shapiq/issues/436)
|
|
7
|
+
|
|
8
|
+
## v1.3.1 (2025-07-11)
|
|
9
|
+
|
|
10
|
+
### New Features
|
|
11
|
+
- adds the `shapiq.plot.beesvarm_plot()` function to shapiq. The beeswarm plot was extended to also support interactions of features. Beeswarm plots are useful in visualizing dependencies between feature values. The beeswarm plot was adapted from the SHAP library by sub-dividing the y-axis for each interaction term. [#399](https://github.com/mmschlk/shapiq/issues/399)
|
|
12
|
+
- adds JSON support to `InteractionValues` and `Game` objects, allowing for easy serialization and deserialization of interaction values and game objects [#412](https://github.com/mmschlk/shapiq/pull/412) usage of `pickle` is now deprecated. This change allows us to revamp the data structures in the future and offers more flexibility.
|
|
13
|
+
|
|
14
|
+
### Testing, Code-Quality and Documentation
|
|
15
|
+
- adds a testing suite for testing deprecations in `tests/tests_deprecations/` which allows for easier deprecation managment and tracking of deprecated features [#412](https://github.com/mmschlk/shapiq/pull/412)
|
|
16
|
+
|
|
17
|
+
## Deprecated
|
|
18
|
+
- The `Game(path_to_values=...)` constructor is now deprecated and will be removed in version 1.4.0. Use `Game.load(...)` or `Game().load_values(...)` instead.
|
|
19
|
+
- Saving and loading `InteactionValues` via `InteractionValues.save(..., as_pickle=True)` and `InteractionValues.save(..., as_npz=True)` is now deprecated and will be removed in version 1.4.0. Use `InteractionValues.save(...)` to save as json.
|
|
20
|
+
|
|
21
|
+
## v1.3.0 (2025-06-17)
|
|
22
|
+
|
|
23
|
+
### Highlights
|
|
6
24
|
- `shapiq.SPEX` (Sparse Exact) approximator for efficient computation of sparse interaction values for really large models and games. Paper: [SPEX: Scaling Feature Interaction Explanations for LLMs](https://arxiv.org/abs/2502.13870)
|
|
7
25
|
- `shapiq.AgnosticExplainer` a generic explainer that works for any value function or `shapiq.Game` object, allowing for more flexibility in explainers.
|
|
8
26
|
- prettier graph-based plots via `shapiq.si_graph_plot()` and `shapiq.network_plot()`, which now use the same backend for more flexibility and easier maintenance.
|
|
9
27
|
|
|
10
|
-
|
|
28
|
+
### New Features
|
|
11
29
|
- adds the SPEX (Sparse Exact) module in `approximator.sparse` for efficient computation of sparse interaction values [#379](https://github.com/mmschlk/shapiq/pull/379)
|
|
12
30
|
- adds `shapiq.AgnosticExplainer` which is a generic explainer that can be used for any value function or `shapiq.Game` object. This allows for more flexibility in the explainers. [#100](https://github.com/mmschlk/shapiq/issues/100), [#395](https://github.com/mmschlk/shapiq/pull/395)
|
|
13
31
|
- changes `budget` to be a mandatory parameter given to the `TabularExplainer.explain()` method [#355](https://github.com/mmschlk/shapiq/pull/356)
|
|
@@ -19,7 +37,7 @@
|
|
|
19
37
|
- adds `Game.compute()` method to the `shapiq.Game` class to compute game values without changing the state of the game object. The compute method also introduces a `shapiq.utils.sets.generate_interaction_lookup_from_coalitions()` utility method which creates an interaction lookup dict from an array of coalitions. [#397](https://github.com/mmschlk/shapiq/pull/397)
|
|
20
38
|
- streamlines the creation of network plots and graph plots which now uses the same backend. The network plot via `shapiq.network_plot()` or `InteractionValues.plot_network()` is now a special case of the `shapiq.si_graph_plot()` and `InteractionValues.plot_si_graph()`. This allows to create more beautiful plots and easier maintenance in the future. [#349](https://github.com/mmschlk/shapiq/pull/349)
|
|
21
39
|
|
|
22
|
-
|
|
40
|
+
### Testing, Code-Quality and Documentation
|
|
23
41
|
- activates ``"ALL"`` rules in ``ruff-format`` configuration to enforce stricter code quality checks and addressed around 500 (not automatically solvable) issues in the code base. [#391](https://github.com/mmschlk/shapiq/pull/391)
|
|
24
42
|
- improved the testing environment by adding a new fixture module containing mock `InteractionValues` objects to be used in the tests. This allows for more efficient and cleaner tests, as well as easier debugging of the tests [#372](https://github.com/mmschlk/shapiq/pull/372)
|
|
25
43
|
- removed check and error message if the ``index`` parameter is not in the list of available indices in the ``TabularExplainer`` since the type hints were replaced by Literals [#391](https://github.com/mmschlk/shapiq/pull/391)
|
|
@@ -29,12 +47,12 @@
|
|
|
29
47
|
- refactors the tests into ``tests_unit/`` and ``tests_integration/`` to better separate unit tests from integration tests. [#395](https://github.com/mmschlk/shapiq/pull/395)
|
|
30
48
|
- adds new integration tests in ``tests/tests_integration/test_explainer_california_housing`` which compares the different explainers against ground-truth interaction values computed by ``shapiq.ExactComputer`` and interaction values stored on [disk](https://github.com/mmschlk/shapiq/tree/main/tests/data/interaction_values/california_housing) as a form of regression test. This test should help finding bugs in the future when the approximators, explainers, or exact computation are changed. [#395](https://github.com/mmschlk/shapiq/pull/395)
|
|
31
49
|
|
|
32
|
-
|
|
50
|
+
### Bug Fixes
|
|
33
51
|
- fixed a bug in the `shapiq.waterfall_plot` function that caused the plot to not display correctly resulting in cutoff y_ticks. Additionally, the file was renamed from `watefall.py` to `waterfall.py` to match the function name [#377](https://github.com/mmschlk/shapiq/pull/377)
|
|
34
52
|
- fixes a bug with `TabPFNExplainer`, where the model was not able to be used for predictions after it was explained. This was due to the model being fitted on a subset of features, which caused inconsistencies in the model's predictions after explanation. The fix includes that after each call to the `TabPFNImputer.value_function`, the tabpfn model is fitted on the whole dataset (without omitting features). This means that the original model can be used for predictions after it has been explained. [#396](https://github.com/mmschlk/shapiq/issues/396).
|
|
35
53
|
- fixed a bug in computing `BII` or `BV` indices with `shapiq.approximator.MonteCarlo` approximators (affecting `SHAP-IQ`, `SVARM` and `SVARM-IQ`). All orders of BII should now be computed correctly. [#395](https://github.com/mmschlk/shapiq/pull/395)
|
|
36
54
|
|
|
37
|
-
|
|
55
|
+
## v1.2.3 (2025-03-24)
|
|
38
56
|
- substantially improves the runtime of all `Regression` approximators by a) a faster pre-computation of the regression matrices and b) a faster computation of the weighted least squares regression [#340](https://github.com/mmschlk/shapiq/issues/340)
|
|
39
57
|
- removes `sample_replacements` parameter from `MarginalImputer` and removes the DeprecationWarning for it
|
|
40
58
|
- adds a trivial computation to `TreeSHAP-IQ` for trees that use only one feature in the tree (this works for decision stumps or trees splitting on only one feature multiple times). In such trees, the computation is trivial as the whole effect of $\nu(N) - \nu(\emptyset)$ is all on the main effect of the single feature and there is no interaction effect. This expands on the fix in v1.2.1 [#286](https://github.com/mmschlk/shapiq/issues/286).
|
|
@@ -45,18 +63,18 @@
|
|
|
45
63
|
- adds the `RegressionFBII` approximator to estimate Faithful Banzhaf interactions via least squares regression [#333](https://github.com/mmschlk/shapiq/pull/333). Additionally, FBII support was introduced in TabularExplainer and MonteCarlo-Approximator.
|
|
46
64
|
- adds a `RandomGame` class as part of `shapiq.games.benchmark` which always returns a random vector of integers between 0 and 100.
|
|
47
65
|
|
|
48
|
-
|
|
66
|
+
## v1.2.2 (2025-03-11)
|
|
49
67
|
- changes python support to 3.10-3.13 [#318](https://github.com/mmschlk/shapiq/pull/318)
|
|
50
68
|
- fixes a bug that prohibited importing shapiq in environments without write access [#326](https://github.com/mmschlk/shapiq/issues/326)
|
|
51
69
|
- adds `ExtraTreeRegressors` to supported models [#309](https://github.com/mmschlk/shapiq/pull/309)
|
|
52
70
|
|
|
53
|
-
|
|
71
|
+
## v1.2.1 (2025-02-17)
|
|
54
72
|
- fixes bugs regarding plotting [#315](https://github.com/mmschlk/shapiq/issues/315) and [#316](https://github.com/mmschlk/shapiq/issues/316)
|
|
55
73
|
- fixes a bug with TreeExplainer and Trees that consist of only one feature [#286](https://github.com/mmschlk/shapiq/issues/286)
|
|
56
74
|
- fixes SV init with explainer for permutation, svarm, kernelshap, and unbiased kernelshap [#319](https://github.com/mmschlk/shapiq/issues/319)
|
|
57
75
|
- adds a progress bar to `explain_X()` [#324](https://github.com/mmschlk/shapiq/issues/324)
|
|
58
76
|
|
|
59
|
-
|
|
77
|
+
## v1.2.0 (2025-01-15)
|
|
60
78
|
- adds ``shapiq.TabPFNExplainer`` as a specialized version of the ``shapiq.TabularExplainer`` which offers a streamlined variant of the explainer for the TabPFN model [#301](https://github.com/mmschlk/shapiq/issues/301)
|
|
61
79
|
- handles ``explainer.explain()`` now through a common interface for all explainer classes which now need to implement a ``explain_function()`` method
|
|
62
80
|
- adds the baseline_value into the InteractionValues object's value storage for the ``()`` interaction if ``min_order=0`` (default usually) for all indices that are not ``SII```(SII has another baseline value) such that the values are efficient (sum up to the model prediction) without the awkward handling of the baseline_value attribute
|
|
@@ -71,20 +89,20 @@
|
|
|
71
89
|
- refactors game theory computations like `ExactComputer`, `MoebiusConverter`, `core`, among others to be more modular and flexible into the `game_theory` module [#258](https://github.com/mmschlk/shapiq/issues/258)
|
|
72
90
|
- improves quality of the tests by adding many more semantic tests to the different interaction indices and computations [#285](https://github.com/mmschlk/shapiq/pull/285)
|
|
73
91
|
|
|
74
|
-
|
|
92
|
+
## v1.1.1 (2024-11-13)
|
|
75
93
|
|
|
76
|
-
|
|
94
|
+
### Improvements and Ease of Use
|
|
77
95
|
- adds a `class_index` parameter to `TabularExplainer` and `Explainer` to specify the class index to be explained for classification models [#271](https://github.com/mmschlk/shapiq/issues/271) (renames `class_label` parameter in TreeExplainer to `class_index`)
|
|
78
96
|
- adds support for `PyTorch` models to `Explainer` [#272](https://github.com/mmschlk/shapiq/issues/272)
|
|
79
97
|
- adds new tests comparing `shapiq` outputs for SVs with alues computed with `shap`
|
|
80
98
|
- adds new tests for checking `shapiq` explainers with different types of models
|
|
81
99
|
|
|
82
|
-
|
|
100
|
+
### Bug Fixes
|
|
83
101
|
- fixes a bug that `RandomForestClassifier` models were not working with the `TreeExplainer` [#273](https://github.com/mmschlk/shapiq/issues/273)
|
|
84
102
|
|
|
85
|
-
|
|
103
|
+
## v1.1.0 (2024-11-07)
|
|
86
104
|
|
|
87
|
-
|
|
105
|
+
### New Features and Improvements
|
|
88
106
|
- adds computation of the Egalitarian Core (`EC`) and Egalitarian Least-Core (`ELC`) to the `ExactComputer` [#182](https://github.com/mmschlk/shapiq/issues/182)
|
|
89
107
|
- adds `waterfall_plot` [#34](https://github.com/mmschlk/shapiq/issues/34) that visualizes the contributions of features to the model prediction
|
|
90
108
|
- adds `BaselineImputer` [#107](https://github.com/mmschlk/shapiq/issues/107) which is now responsible for handling the `sample_replacements` parameter. Added a DeprecationWarning for the parameter in `MarginalImputer`, which will be removed in the next release.
|
|
@@ -97,7 +115,7 @@
|
|
|
97
115
|
- a `shapiq.Game` can now be called more intuitively with coalitions data types (tuples of int or str) and also allows to add `player_names` to the game at initialization [#183](https://github.com/mmschlk/shapiq/issues/183)
|
|
98
116
|
- improve tests across the package
|
|
99
117
|
|
|
100
|
-
|
|
118
|
+
### Documentation
|
|
101
119
|
- adds a notebook showing how to use custom tree models with the `TreeExplainer` [#66](https://github.com/mmschlk/shapiq/issues/66)
|
|
102
120
|
- adds a notebook show how to use the `shapiq.Game` API to create custom games [#184](https://github.com/mmschlk/shapiq/issues/184)
|
|
103
121
|
- adds a notebook showing hot to visualize interactions [#252](https://github.com/mmschlk/shapiq/issues/252)
|
|
@@ -105,17 +123,17 @@
|
|
|
105
123
|
- adds a notebook for conducting data valuation [#190](https://github.com/mmschlk/shapiq/issues/190)
|
|
106
124
|
- adds a notebook showcasing introducing the Core and how to compute it with `shapiq` [#191](https://github.com/mmschlk/shapiq/issues/191)
|
|
107
125
|
|
|
108
|
-
|
|
126
|
+
### Bug Fixes
|
|
109
127
|
- fixes a bug with SIs not adding up to the model prediction because of wrong values in the empty set [#264](https://github.com/mmschlk/shapiq/issues/264)
|
|
110
128
|
- fixes a bug that `TreeExplainer` did not have the correct baseline_value when using XGBoost models [#250](https://github.com/mmschlk/shapiq/issues/250)
|
|
111
129
|
- fixes the force plot not showing and its baseline value
|
|
112
130
|
|
|
113
|
-
|
|
131
|
+
## v1.0.1 (2024-06-05)
|
|
114
132
|
|
|
115
133
|
- add `max_order=1` to `TabularExplainer` and `TreeExplainer`
|
|
116
134
|
- fix `TreeExplainer.explain_X(..., n_jobs=2, random_state=0)`
|
|
117
135
|
|
|
118
|
-
|
|
136
|
+
## v1.0.0 (2024-06-04)
|
|
119
137
|
|
|
120
138
|
Major release of the `shapiq` Python package including (among others):
|
|
121
139
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shapiq
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.2
|
|
4
4
|
Summary: Shapley Interactions for Machine Learning
|
|
5
5
|
Author: Hubert Baniecki, Fabian Fumagalli
|
|
6
6
|
Author-email: Maximilian Muschalik <Maximilian.Muschalik@lmu.de>
|
|
@@ -48,8 +48,8 @@ Requires-Dist: lightgbm; extra == "ml"
|
|
|
48
48
|
Requires-Dist: transformers; extra == "ml"
|
|
49
49
|
Requires-Dist: scikit-image; extra == "ml"
|
|
50
50
|
Requires-Dist: joblib; extra == "ml"
|
|
51
|
-
Requires-Dist: tensorflow; python_version < "3.13" and extra == "ml"
|
|
52
|
-
Requires-Dist: tf-keras; python_version < "3.13" and extra == "ml"
|
|
51
|
+
Requires-Dist: tensorflow; (python_version < "3.13" and platform_system != "Windows") and extra == "ml"
|
|
52
|
+
Requires-Dist: tf-keras; (python_version < "3.13" and platform_system != "Windows") and extra == "ml"
|
|
53
53
|
Dynamic: license-file
|
|
54
54
|
|
|
55
55
|
# shapiq: Shapley Interactions for Machine Learning <img src="https://raw.githubusercontent.com/mmschlk/shapiq/main/docs/source/_static/logo/logo_shapiq_light.svg" alt="shapiq_logo" align="right" height="250px"/>
|
|
@@ -273,16 +273,34 @@ Some authors acknowledge the financial support by the German Research Foundation
|
|
|
273
273
|
---
|
|
274
274
|
Built with ❤️ by the shapiq team.
|
|
275
275
|
|
|
276
|
-
|
|
276
|
+
# Changelog
|
|
277
277
|
|
|
278
|
-
|
|
278
|
+
## v1.3.2 (2025-10-14)
|
|
279
279
|
|
|
280
|
-
|
|
280
|
+
### Hotfix
|
|
281
|
+
Removes `overrides` import in tabular explainer, which is not part of the package dependencies resulting in an ImportError when importing `shapiq`. [#436](https://github.com/mmschlk/shapiq/issues/436)
|
|
282
|
+
|
|
283
|
+
## v1.3.1 (2025-07-11)
|
|
284
|
+
|
|
285
|
+
### New Features
|
|
286
|
+
- adds the `shapiq.plot.beesvarm_plot()` function to shapiq. The beeswarm plot was extended to also support interactions of features. Beeswarm plots are useful in visualizing dependencies between feature values. The beeswarm plot was adapted from the SHAP library by sub-dividing the y-axis for each interaction term. [#399](https://github.com/mmschlk/shapiq/issues/399)
|
|
287
|
+
- adds JSON support to `InteractionValues` and `Game` objects, allowing for easy serialization and deserialization of interaction values and game objects [#412](https://github.com/mmschlk/shapiq/pull/412) usage of `pickle` is now deprecated. This change allows us to revamp the data structures in the future and offers more flexibility.
|
|
288
|
+
|
|
289
|
+
### Testing, Code-Quality and Documentation
|
|
290
|
+
- adds a testing suite for testing deprecations in `tests/tests_deprecations/` which allows for easier deprecation managment and tracking of deprecated features [#412](https://github.com/mmschlk/shapiq/pull/412)
|
|
291
|
+
|
|
292
|
+
## Deprecated
|
|
293
|
+
- The `Game(path_to_values=...)` constructor is now deprecated and will be removed in version 1.4.0. Use `Game.load(...)` or `Game().load_values(...)` instead.
|
|
294
|
+
- Saving and loading `InteactionValues` via `InteractionValues.save(..., as_pickle=True)` and `InteractionValues.save(..., as_npz=True)` is now deprecated and will be removed in version 1.4.0. Use `InteractionValues.save(...)` to save as json.
|
|
295
|
+
|
|
296
|
+
## v1.3.0 (2025-06-17)
|
|
297
|
+
|
|
298
|
+
### Highlights
|
|
281
299
|
- `shapiq.SPEX` (Sparse Exact) approximator for efficient computation of sparse interaction values for really large models and games. Paper: [SPEX: Scaling Feature Interaction Explanations for LLMs](https://arxiv.org/abs/2502.13870)
|
|
282
300
|
- `shapiq.AgnosticExplainer` a generic explainer that works for any value function or `shapiq.Game` object, allowing for more flexibility in explainers.
|
|
283
301
|
- prettier graph-based plots via `shapiq.si_graph_plot()` and `shapiq.network_plot()`, which now use the same backend for more flexibility and easier maintenance.
|
|
284
302
|
|
|
285
|
-
|
|
303
|
+
### New Features
|
|
286
304
|
- adds the SPEX (Sparse Exact) module in `approximator.sparse` for efficient computation of sparse interaction values [#379](https://github.com/mmschlk/shapiq/pull/379)
|
|
287
305
|
- adds `shapiq.AgnosticExplainer` which is a generic explainer that can be used for any value function or `shapiq.Game` object. This allows for more flexibility in the explainers. [#100](https://github.com/mmschlk/shapiq/issues/100), [#395](https://github.com/mmschlk/shapiq/pull/395)
|
|
288
306
|
- changes `budget` to be a mandatory parameter given to the `TabularExplainer.explain()` method [#355](https://github.com/mmschlk/shapiq/pull/356)
|
|
@@ -294,7 +312,7 @@ Built with ❤️ by the shapiq team.
|
|
|
294
312
|
- adds `Game.compute()` method to the `shapiq.Game` class to compute game values without changing the state of the game object. The compute method also introduces a `shapiq.utils.sets.generate_interaction_lookup_from_coalitions()` utility method which creates an interaction lookup dict from an array of coalitions. [#397](https://github.com/mmschlk/shapiq/pull/397)
|
|
295
313
|
- streamlines the creation of network plots and graph plots which now uses the same backend. The network plot via `shapiq.network_plot()` or `InteractionValues.plot_network()` is now a special case of the `shapiq.si_graph_plot()` and `InteractionValues.plot_si_graph()`. This allows to create more beautiful plots and easier maintenance in the future. [#349](https://github.com/mmschlk/shapiq/pull/349)
|
|
296
314
|
|
|
297
|
-
|
|
315
|
+
### Testing, Code-Quality and Documentation
|
|
298
316
|
- activates ``"ALL"`` rules in ``ruff-format`` configuration to enforce stricter code quality checks and addressed around 500 (not automatically solvable) issues in the code base. [#391](https://github.com/mmschlk/shapiq/pull/391)
|
|
299
317
|
- improved the testing environment by adding a new fixture module containing mock `InteractionValues` objects to be used in the tests. This allows for more efficient and cleaner tests, as well as easier debugging of the tests [#372](https://github.com/mmschlk/shapiq/pull/372)
|
|
300
318
|
- removed check and error message if the ``index`` parameter is not in the list of available indices in the ``TabularExplainer`` since the type hints were replaced by Literals [#391](https://github.com/mmschlk/shapiq/pull/391)
|
|
@@ -304,12 +322,12 @@ Built with ❤️ by the shapiq team.
|
|
|
304
322
|
- refactors the tests into ``tests_unit/`` and ``tests_integration/`` to better separate unit tests from integration tests. [#395](https://github.com/mmschlk/shapiq/pull/395)
|
|
305
323
|
- adds new integration tests in ``tests/tests_integration/test_explainer_california_housing`` which compares the different explainers against ground-truth interaction values computed by ``shapiq.ExactComputer`` and interaction values stored on [disk](https://github.com/mmschlk/shapiq/tree/main/tests/data/interaction_values/california_housing) as a form of regression test. This test should help finding bugs in the future when the approximators, explainers, or exact computation are changed. [#395](https://github.com/mmschlk/shapiq/pull/395)
|
|
306
324
|
|
|
307
|
-
|
|
325
|
+
### Bug Fixes
|
|
308
326
|
- fixed a bug in the `shapiq.waterfall_plot` function that caused the plot to not display correctly resulting in cutoff y_ticks. Additionally, the file was renamed from `watefall.py` to `waterfall.py` to match the function name [#377](https://github.com/mmschlk/shapiq/pull/377)
|
|
309
327
|
- fixes a bug with `TabPFNExplainer`, where the model was not able to be used for predictions after it was explained. This was due to the model being fitted on a subset of features, which caused inconsistencies in the model's predictions after explanation. The fix includes that after each call to the `TabPFNImputer.value_function`, the tabpfn model is fitted on the whole dataset (without omitting features). This means that the original model can be used for predictions after it has been explained. [#396](https://github.com/mmschlk/shapiq/issues/396).
|
|
310
328
|
- fixed a bug in computing `BII` or `BV` indices with `shapiq.approximator.MonteCarlo` approximators (affecting `SHAP-IQ`, `SVARM` and `SVARM-IQ`). All orders of BII should now be computed correctly. [#395](https://github.com/mmschlk/shapiq/pull/395)
|
|
311
329
|
|
|
312
|
-
|
|
330
|
+
## v1.2.3 (2025-03-24)
|
|
313
331
|
- substantially improves the runtime of all `Regression` approximators by a) a faster pre-computation of the regression matrices and b) a faster computation of the weighted least squares regression [#340](https://github.com/mmschlk/shapiq/issues/340)
|
|
314
332
|
- removes `sample_replacements` parameter from `MarginalImputer` and removes the DeprecationWarning for it
|
|
315
333
|
- adds a trivial computation to `TreeSHAP-IQ` for trees that use only one feature in the tree (this works for decision stumps or trees splitting on only one feature multiple times). In such trees, the computation is trivial as the whole effect of $\nu(N) - \nu(\emptyset)$ is all on the main effect of the single feature and there is no interaction effect. This expands on the fix in v1.2.1 [#286](https://github.com/mmschlk/shapiq/issues/286).
|
|
@@ -320,18 +338,18 @@ Built with ❤️ by the shapiq team.
|
|
|
320
338
|
- adds the `RegressionFBII` approximator to estimate Faithful Banzhaf interactions via least squares regression [#333](https://github.com/mmschlk/shapiq/pull/333). Additionally, FBII support was introduced in TabularExplainer and MonteCarlo-Approximator.
|
|
321
339
|
- adds a `RandomGame` class as part of `shapiq.games.benchmark` which always returns a random vector of integers between 0 and 100.
|
|
322
340
|
|
|
323
|
-
|
|
341
|
+
## v1.2.2 (2025-03-11)
|
|
324
342
|
- changes python support to 3.10-3.13 [#318](https://github.com/mmschlk/shapiq/pull/318)
|
|
325
343
|
- fixes a bug that prohibited importing shapiq in environments without write access [#326](https://github.com/mmschlk/shapiq/issues/326)
|
|
326
344
|
- adds `ExtraTreeRegressors` to supported models [#309](https://github.com/mmschlk/shapiq/pull/309)
|
|
327
345
|
|
|
328
|
-
|
|
346
|
+
## v1.2.1 (2025-02-17)
|
|
329
347
|
- fixes bugs regarding plotting [#315](https://github.com/mmschlk/shapiq/issues/315) and [#316](https://github.com/mmschlk/shapiq/issues/316)
|
|
330
348
|
- fixes a bug with TreeExplainer and Trees that consist of only one feature [#286](https://github.com/mmschlk/shapiq/issues/286)
|
|
331
349
|
- fixes SV init with explainer for permutation, svarm, kernelshap, and unbiased kernelshap [#319](https://github.com/mmschlk/shapiq/issues/319)
|
|
332
350
|
- adds a progress bar to `explain_X()` [#324](https://github.com/mmschlk/shapiq/issues/324)
|
|
333
351
|
|
|
334
|
-
|
|
352
|
+
## v1.2.0 (2025-01-15)
|
|
335
353
|
- adds ``shapiq.TabPFNExplainer`` as a specialized version of the ``shapiq.TabularExplainer`` which offers a streamlined variant of the explainer for the TabPFN model [#301](https://github.com/mmschlk/shapiq/issues/301)
|
|
336
354
|
- handles ``explainer.explain()`` now through a common interface for all explainer classes which now need to implement a ``explain_function()`` method
|
|
337
355
|
- adds the baseline_value into the InteractionValues object's value storage for the ``()`` interaction if ``min_order=0`` (default usually) for all indices that are not ``SII```(SII has another baseline value) such that the values are efficient (sum up to the model prediction) without the awkward handling of the baseline_value attribute
|
|
@@ -346,20 +364,20 @@ Built with ❤️ by the shapiq team.
|
|
|
346
364
|
- refactors game theory computations like `ExactComputer`, `MoebiusConverter`, `core`, among others to be more modular and flexible into the `game_theory` module [#258](https://github.com/mmschlk/shapiq/issues/258)
|
|
347
365
|
- improves quality of the tests by adding many more semantic tests to the different interaction indices and computations [#285](https://github.com/mmschlk/shapiq/pull/285)
|
|
348
366
|
|
|
349
|
-
|
|
367
|
+
## v1.1.1 (2024-11-13)
|
|
350
368
|
|
|
351
|
-
|
|
369
|
+
### Improvements and Ease of Use
|
|
352
370
|
- adds a `class_index` parameter to `TabularExplainer` and `Explainer` to specify the class index to be explained for classification models [#271](https://github.com/mmschlk/shapiq/issues/271) (renames `class_label` parameter in TreeExplainer to `class_index`)
|
|
353
371
|
- adds support for `PyTorch` models to `Explainer` [#272](https://github.com/mmschlk/shapiq/issues/272)
|
|
354
372
|
- adds new tests comparing `shapiq` outputs for SVs with alues computed with `shap`
|
|
355
373
|
- adds new tests for checking `shapiq` explainers with different types of models
|
|
356
374
|
|
|
357
|
-
|
|
375
|
+
### Bug Fixes
|
|
358
376
|
- fixes a bug that `RandomForestClassifier` models were not working with the `TreeExplainer` [#273](https://github.com/mmschlk/shapiq/issues/273)
|
|
359
377
|
|
|
360
|
-
|
|
378
|
+
## v1.1.0 (2024-11-07)
|
|
361
379
|
|
|
362
|
-
|
|
380
|
+
### New Features and Improvements
|
|
363
381
|
- adds computation of the Egalitarian Core (`EC`) and Egalitarian Least-Core (`ELC`) to the `ExactComputer` [#182](https://github.com/mmschlk/shapiq/issues/182)
|
|
364
382
|
- adds `waterfall_plot` [#34](https://github.com/mmschlk/shapiq/issues/34) that visualizes the contributions of features to the model prediction
|
|
365
383
|
- adds `BaselineImputer` [#107](https://github.com/mmschlk/shapiq/issues/107) which is now responsible for handling the `sample_replacements` parameter. Added a DeprecationWarning for the parameter in `MarginalImputer`, which will be removed in the next release.
|
|
@@ -372,7 +390,7 @@ Built with ❤️ by the shapiq team.
|
|
|
372
390
|
- a `shapiq.Game` can now be called more intuitively with coalitions data types (tuples of int or str) and also allows to add `player_names` to the game at initialization [#183](https://github.com/mmschlk/shapiq/issues/183)
|
|
373
391
|
- improve tests across the package
|
|
374
392
|
|
|
375
|
-
|
|
393
|
+
### Documentation
|
|
376
394
|
- adds a notebook showing how to use custom tree models with the `TreeExplainer` [#66](https://github.com/mmschlk/shapiq/issues/66)
|
|
377
395
|
- adds a notebook show how to use the `shapiq.Game` API to create custom games [#184](https://github.com/mmschlk/shapiq/issues/184)
|
|
378
396
|
- adds a notebook showing hot to visualize interactions [#252](https://github.com/mmschlk/shapiq/issues/252)
|
|
@@ -380,17 +398,17 @@ Built with ❤️ by the shapiq team.
|
|
|
380
398
|
- adds a notebook for conducting data valuation [#190](https://github.com/mmschlk/shapiq/issues/190)
|
|
381
399
|
- adds a notebook showcasing introducing the Core and how to compute it with `shapiq` [#191](https://github.com/mmschlk/shapiq/issues/191)
|
|
382
400
|
|
|
383
|
-
|
|
401
|
+
### Bug Fixes
|
|
384
402
|
- fixes a bug with SIs not adding up to the model prediction because of wrong values in the empty set [#264](https://github.com/mmschlk/shapiq/issues/264)
|
|
385
403
|
- fixes a bug that `TreeExplainer` did not have the correct baseline_value when using XGBoost models [#250](https://github.com/mmschlk/shapiq/issues/250)
|
|
386
404
|
- fixes the force plot not showing and its baseline value
|
|
387
405
|
|
|
388
|
-
|
|
406
|
+
## v1.0.1 (2024-06-05)
|
|
389
407
|
|
|
390
408
|
- add `max_order=1` to `TabularExplainer` and `TreeExplainer`
|
|
391
409
|
- fix `TreeExplainer.explain_X(..., n_jobs=2, random_state=0)`
|
|
392
410
|
|
|
393
|
-
|
|
411
|
+
## v1.0.0 (2024-06-04)
|
|
394
412
|
|
|
395
413
|
Major release of the `shapiq` Python package including (among others):
|
|
396
414
|
|
|
@@ -84,8 +84,9 @@ ml = [
|
|
|
84
84
|
"transformers",
|
|
85
85
|
"scikit-image",
|
|
86
86
|
"joblib",
|
|
87
|
-
|
|
88
|
-
"
|
|
87
|
+
# tf only for python < 3.13 and not windows
|
|
88
|
+
"tensorflow; python_version < '3.13' and platform_system != 'Windows'",
|
|
89
|
+
"tf-keras; python_version < '3.13' and platform_system != 'Windows'",
|
|
89
90
|
]
|
|
90
91
|
|
|
91
92
|
[tool.pytest.ini_options]
|
|
@@ -106,7 +107,7 @@ ignore = [
|
|
|
106
107
|
"E501", # Line too long
|
|
107
108
|
"N803", # Variable X in function should be lowercase
|
|
108
109
|
"N806", # Variable X in function should be lowercase
|
|
109
|
-
"S301", #
|
|
110
|
+
"S301", # we will remove pickle in version 1.4.0 (https://github.com/mmschlk/shapiq/issues/413)
|
|
110
111
|
"COM812", # this is redundant with the formatter which anyways does this (must be excluded) in the future # TODO: add remove pickle calls and remove this exclusion
|
|
111
112
|
"FIX002", # we use TODOs atm to track potential code improvements # TODO: add this in the future
|
|
112
113
|
"PLR0913", # Too many arguments are passed to function
|
|
@@ -150,6 +151,9 @@ exclude = [
|
|
|
150
151
|
# Exclude a variety of commonly ignored directories.
|
|
151
152
|
# Note to developers: If you add a new ignore at least put a comment next to it why it is ignored
|
|
152
153
|
[tool.ruff.lint.per-file-ignores]
|
|
154
|
+
"shapiq/typing.py" = [
|
|
155
|
+
"A005", # we want to be similar to other libraries that also shadow typing
|
|
156
|
+
]
|
|
153
157
|
"tests/*.py" = [
|
|
154
158
|
# "ALL",
|
|
155
159
|
"S101", # we need asserts in tests
|
|
@@ -197,7 +201,10 @@ exclude = [
|
|
|
197
201
|
"scripts/*.py" = [
|
|
198
202
|
"INP", # imports can be different here
|
|
199
203
|
"I002", # script code does not have to import required modules
|
|
200
|
-
"PTH" # in script code we use a lot of os, which is okay
|
|
204
|
+
"PTH", # in script code we use a lot of os, which is okay
|
|
205
|
+
"T201", # scripts can have print statements
|
|
206
|
+
"BLE001", # scripts can have bare excepts
|
|
207
|
+
"TRY"
|
|
201
208
|
]
|
|
202
209
|
|
|
203
210
|
[tool.ruff.lint.pydocstyle]
|
|
@@ -211,16 +218,23 @@ force-wrap-aliases = true
|
|
|
211
218
|
no-lines-before = ["future"]
|
|
212
219
|
required-imports = ["from __future__ import annotations"]
|
|
213
220
|
|
|
221
|
+
[tool.pyright]
|
|
222
|
+
include = ["shapiq"]
|
|
223
|
+
exclude = ["tests", "docs", "benchmark", "scripts", "shapiq/plot"]
|
|
224
|
+
pythonVersion = "3.10"
|
|
225
|
+
|
|
214
226
|
[dependency-groups]
|
|
215
227
|
test = [
|
|
216
228
|
"pytest>=8.3.5",
|
|
217
229
|
"pytest-cov>=6.0.0",
|
|
218
230
|
"pytest-xdist>=3.6.1",
|
|
219
231
|
"pytest-randomly",
|
|
232
|
+
"packaging>=24.2",
|
|
220
233
|
]
|
|
221
234
|
lint = [
|
|
222
235
|
"ruff>=0.11.2",
|
|
223
236
|
"pre-commit>=4.2.0",
|
|
237
|
+
"pyright>=1.1.402",
|
|
224
238
|
]
|
|
225
239
|
docs = [
|
|
226
240
|
"sphinx>=8.0.0",
|
|
@@ -233,6 +247,10 @@ docs = [
|
|
|
233
247
|
"nbconvert",
|
|
234
248
|
"nbsphinx",
|
|
235
249
|
"commonmark", # Markdown parser and renderer
|
|
250
|
+
# TODO(mmschlk): remove the pin in ipython when we drop python 3.10 support and pin to
|
|
251
|
+
# ipython>=9.0.0, since ipython==8.7.0 introduces a bug with parsing notebooks also discussed
|
|
252
|
+
# here: https://github.com/spatialaudio/nbsphinx/issues/24
|
|
253
|
+
"ipython<8.7.0",
|
|
236
254
|
]
|
|
237
255
|
dev = [
|
|
238
256
|
"build>=1.2.2.post1",
|
|
@@ -4,7 +4,7 @@ shapiq is a library creating explanations for machine learning models based on
|
|
|
4
4
|
the well established Shapley value and its generalization to interaction.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
__version__ = "1.3.
|
|
7
|
+
__version__ = "1.3.2"
|
|
8
8
|
|
|
9
9
|
# approximator classes
|
|
10
10
|
from .approximator import (
|
|
@@ -64,6 +64,7 @@ from .interaction_values import InteractionValues
|
|
|
64
64
|
# plotting functions
|
|
65
65
|
from .plot import (
|
|
66
66
|
bar_plot,
|
|
67
|
+
beeswarm_plot,
|
|
67
68
|
force_plot,
|
|
68
69
|
network_plot,
|
|
69
70
|
sentence_plot,
|
|
@@ -125,6 +126,7 @@ __all__ = [
|
|
|
125
126
|
"waterfall_plot",
|
|
126
127
|
"sentence_plot",
|
|
127
128
|
"upset_plot",
|
|
129
|
+
"beeswarm_plot",
|
|
128
130
|
# public utils
|
|
129
131
|
"powerset",
|
|
130
132
|
"get_explicit_subsets",
|
|
@@ -25,16 +25,14 @@ class TabPFNExplainer(TabularExplainer):
|
|
|
25
25
|
"""The TabPFN explainer as the main interface for the shapiq package.
|
|
26
26
|
|
|
27
27
|
The ``TabPFNExplainer`` class is the dedicated interface for the ``shapiq`` package and
|
|
28
|
-
TabPFN
|
|
29
|
-
does not rely on classical imputation methods and is
|
|
30
|
-
approach. The explanation paradigm for TabPFN is
|
|
31
|
-
essence the explainer is a wrapper around the
|
|
32
|
-
|
|
28
|
+
TabPFN :footcite:t:`Hollmann.2025` models such as the ``TabPFNClassifier`` and
|
|
29
|
+
``TabPFNRegressor``. The explainer does not rely on classical imputation methods and is
|
|
30
|
+
optimized for TabPFN's in-context learning approach. The explanation paradigm for TabPFN is
|
|
31
|
+
described in :footcite:t:`Rundel.2024`. In essence the explainer is a wrapper around the
|
|
32
|
+
:class:~`shapiq.explainer.tabular.TabularExplainer` class and uses the same API.
|
|
33
33
|
|
|
34
34
|
References:
|
|
35
|
-
..
|
|
36
|
-
.. [Hol25] Hollmann, N., Müller, S., Purucker, L. et al. Accurate predictions on small data with a tabular foundation model. Nature 637, 319-326 (2025). https://doi.org/10.1038/s41586-024-08328-6
|
|
37
|
-
|
|
35
|
+
.. footbibliography::
|
|
38
36
|
"""
|
|
39
37
|
|
|
40
38
|
def __init__(
|
|
@@ -5,8 +5,6 @@ from __future__ import annotations
|
|
|
5
5
|
from typing import TYPE_CHECKING, Any, Literal
|
|
6
6
|
from warnings import warn
|
|
7
7
|
|
|
8
|
-
from overrides import overrides
|
|
9
|
-
|
|
10
8
|
from shapiq.explainer.base import Explainer
|
|
11
9
|
from shapiq.interaction_values import InteractionValues, finalize_computed_interactions
|
|
12
10
|
|
|
@@ -165,7 +163,6 @@ class TabularExplainer(Explainer):
|
|
|
165
163
|
approximator, self._index, self._max_order, self._n_features, random_state
|
|
166
164
|
)
|
|
167
165
|
|
|
168
|
-
@overrides
|
|
169
166
|
def explain_function(
|
|
170
167
|
self,
|
|
171
168
|
x: np.ndarray,
|
|
@@ -3,11 +3,15 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from dataclasses import dataclass
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
6
7
|
|
|
7
8
|
import numpy as np
|
|
8
9
|
|
|
9
10
|
from .utils import compute_empty_prediction
|
|
10
11
|
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from numpy.typing import NDArray
|
|
14
|
+
|
|
11
15
|
|
|
12
16
|
@dataclass
|
|
13
17
|
class TreeModel:
|
|
@@ -52,22 +56,22 @@ class TreeModel:
|
|
|
52
56
|
|
|
53
57
|
"""
|
|
54
58
|
|
|
55
|
-
children_left: np.
|
|
56
|
-
children_right: np.
|
|
57
|
-
features: np.
|
|
58
|
-
thresholds: np.
|
|
59
|
-
values: np.
|
|
60
|
-
node_sample_weight: np.
|
|
61
|
-
empty_prediction: float
|
|
62
|
-
leaf_mask: np.
|
|
63
|
-
n_features_in_tree: int
|
|
64
|
-
max_feature_id: int
|
|
65
|
-
feature_ids: set
|
|
66
|
-
root_node_id: int
|
|
67
|
-
n_nodes: int
|
|
68
|
-
nodes: np.
|
|
69
|
-
feature_map_original_internal: dict[int, int]
|
|
70
|
-
feature_map_internal_original: dict[int, int]
|
|
59
|
+
children_left: NDArray[np.int_]
|
|
60
|
+
children_right: NDArray[np.int_]
|
|
61
|
+
features: NDArray[np.int_]
|
|
62
|
+
thresholds: NDArray[np.floating]
|
|
63
|
+
values: NDArray[np.floating]
|
|
64
|
+
node_sample_weight: NDArray[np.floating]
|
|
65
|
+
empty_prediction: float = None # type: ignore[assignment]
|
|
66
|
+
leaf_mask: NDArray[np.bool_] = None # type: ignore[assignment]
|
|
67
|
+
n_features_in_tree: int = None # type: ignore[assignment]
|
|
68
|
+
max_feature_id: int = None # type: ignore[assignment]
|
|
69
|
+
feature_ids: set = None # type: ignore[assignment]
|
|
70
|
+
root_node_id: int = None # type: ignore[assignment]
|
|
71
|
+
n_nodes: int = None # type: ignore[assignment]
|
|
72
|
+
nodes: NDArray[np.int_] = None # type: ignore[assignment]
|
|
73
|
+
feature_map_original_internal: dict[int, int] = None # type: ignore[assignment]
|
|
74
|
+
feature_map_internal_original: dict[int, int] = None # type: ignore[assignment]
|
|
71
75
|
original_output_type: str = "raw" # not used at the moment
|
|
72
76
|
|
|
73
77
|
def compute_empty_prediction(self) -> None:
|
|
@@ -187,7 +191,7 @@ class TreeModel:
|
|
|
187
191
|
else:
|
|
188
192
|
node = self.children_right[node]
|
|
189
193
|
is_leaf = self.leaf_mask[node]
|
|
190
|
-
return self.values[node]
|
|
194
|
+
return float(self.values[node])
|
|
191
195
|
|
|
192
196
|
|
|
193
197
|
@dataclass
|
|
@@ -2,22 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
5
7
|
import numpy as np
|
|
6
8
|
from scipy.special import binom
|
|
7
9
|
|
|
8
10
|
from shapiq.explainer.tree.base import EdgeTree
|
|
9
11
|
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from numpy.typing import NDArray
|
|
14
|
+
|
|
10
15
|
|
|
11
16
|
def create_edge_tree(
|
|
12
|
-
children_left: np.
|
|
13
|
-
children_right: np.
|
|
14
|
-
features: np.
|
|
15
|
-
node_sample_weight: np.
|
|
16
|
-
values: np.
|
|
17
|
+
children_left: NDArray[np.int_],
|
|
18
|
+
children_right: NDArray[np.int_],
|
|
19
|
+
features: NDArray[np.int_],
|
|
20
|
+
node_sample_weight: NDArray[np.floating],
|
|
21
|
+
values: NDArray[np.floating],
|
|
17
22
|
n_nodes: int,
|
|
18
23
|
n_features: int,
|
|
19
24
|
max_interaction: int,
|
|
20
|
-
subset_updates_pos_store: dict[int, dict[int, np.
|
|
25
|
+
subset_updates_pos_store: dict[int, dict[int, NDArray[np.int_]]],
|
|
21
26
|
) -> EdgeTree:
|
|
22
27
|
"""Extracts edge information recursively from the tree information.
|
|
23
28
|
|
|
@@ -2,15 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
5
7
|
import numpy as np
|
|
6
8
|
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from numpy.typing import NDArray
|
|
11
|
+
|
|
12
|
+
|
|
7
13
|
__all__ = ["compute_empty_prediction", "get_conditional_sample_weights"]
|
|
8
14
|
|
|
9
15
|
|
|
10
16
|
def get_conditional_sample_weights(
|
|
11
|
-
sample_count: np.
|
|
12
|
-
parent_array: np.
|
|
13
|
-
) -> np.
|
|
17
|
+
sample_count: NDArray[np.int_],
|
|
18
|
+
parent_array: NDArray[np.int_],
|
|
19
|
+
) -> NDArray[np.floating]:
|
|
14
20
|
"""Get the conditional sample weights for a tree at each decision node.
|
|
15
21
|
|
|
16
22
|
The conditional sample weights are the probabilities of going left or right at each decision
|
|
@@ -41,8 +47,8 @@ def get_conditional_sample_weights(
|
|
|
41
47
|
|
|
42
48
|
|
|
43
49
|
def compute_empty_prediction(
|
|
44
|
-
leaf_values: np.
|
|
45
|
-
leaf_sample_weights: np.
|
|
50
|
+
leaf_values: NDArray[np.floating],
|
|
51
|
+
leaf_sample_weights: NDArray[np.floating],
|
|
46
52
|
) -> float:
|
|
47
53
|
"""Compute the empty prediction of a tree model.
|
|
48
54
|
|
|
@@ -56,4 +62,4 @@ def compute_empty_prediction(
|
|
|
56
62
|
The empty prediction of the tree model.
|
|
57
63
|
|
|
58
64
|
"""
|
|
59
|
-
return np.sum(leaf_values * leaf_sample_weights) / np.sum(leaf_sample_weights)
|
|
65
|
+
return float(np.sum(leaf_values * leaf_sample_weights) / np.sum(leaf_sample_weights))
|