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.
Files changed (143) hide show
  1. {shapiq-1.3.0 → shapiq-1.3.2}/CHANGELOG.md +37 -19
  2. {shapiq-1.3.0/shapiq.egg-info → shapiq-1.3.2}/PKG-INFO +40 -22
  3. {shapiq-1.3.0 → shapiq-1.3.2}/pyproject.toml +22 -4
  4. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/__init__.py +3 -1
  5. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tabpfn.py +6 -8
  6. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tabular.py +0 -3
  7. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/base.py +21 -17
  8. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/conversion/edges.py +11 -6
  9. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/utils.py +12 -6
  10. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/base.py +202 -73
  11. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/local_xai/base.py +3 -7
  12. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/local_xai/benchmark_language.py +11 -1
  13. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/setup.py +5 -1
  14. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/imputer/conditional_imputer.py +1 -1
  15. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/imputer/tabpfn_imputer.py +5 -3
  16. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/interaction_values.py +136 -40
  17. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/__init__.py +2 -0
  18. shapiq-1.3.2/shapiq/plot/beeswarm.py +425 -0
  19. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/si_graph.py +1 -1
  20. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/utils.py +1 -1
  21. shapiq-1.3.2/shapiq/py.typed +0 -0
  22. shapiq-1.3.2/shapiq/typing.py +72 -0
  23. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/utils/__init__.py +3 -3
  24. shapiq-1.3.2/shapiq/utils/errors.py +19 -0
  25. shapiq-1.3.2/shapiq/utils/saving.py +116 -0
  26. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/utils/sets.py +25 -16
  27. {shapiq-1.3.0 → shapiq-1.3.2/shapiq.egg-info}/PKG-INFO +40 -22
  28. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq.egg-info/SOURCES.txt +5 -1
  29. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq.egg-info/requires.txt +1 -1
  30. shapiq-1.3.0/shapiq/utils/custom_types.py +0 -30
  31. {shapiq-1.3.0 → shapiq-1.3.2}/LICENSE +0 -0
  32. {shapiq-1.3.0 → shapiq-1.3.2}/README.md +0 -0
  33. {shapiq-1.3.0 → shapiq-1.3.2}/setup.cfg +0 -0
  34. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/__init__.py +0 -0
  35. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/base.py +0 -0
  36. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/marginals/__init__.py +0 -0
  37. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/marginals/owen.py +0 -0
  38. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/marginals/stratified.py +0 -0
  39. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/montecarlo/__init__.py +0 -0
  40. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/montecarlo/base.py +0 -0
  41. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/montecarlo/shapiq.py +0 -0
  42. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/montecarlo/svarmiq.py +0 -0
  43. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/permutation/__init__.py +0 -0
  44. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/permutation/sii.py +0 -0
  45. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/permutation/stii.py +0 -0
  46. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/permutation/sv.py +0 -0
  47. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/regression/__init__.py +0 -0
  48. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/regression/base.py +0 -0
  49. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/regression/faithful.py +0 -0
  50. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/regression/kadd_shap.py +0 -0
  51. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/regression/kernelshap.py +0 -0
  52. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/regression/kernelshapiq.py +0 -0
  53. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/sampling.py +0 -0
  54. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/sparse/__init__.py +0 -0
  55. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/sparse/base.py +0 -0
  56. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/approximator/sparse/spex.py +0 -0
  57. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/benchmark/__init__.py +0 -0
  58. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/benchmark/configuration.py +0 -0
  59. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/benchmark/load.py +0 -0
  60. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/benchmark/metrics.py +0 -0
  61. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/benchmark/plot.py +0 -0
  62. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/benchmark/precompute.py +0 -0
  63. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/benchmark/run.py +0 -0
  64. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/datasets/__init__.py +0 -0
  65. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/datasets/_all.py +0 -0
  66. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/__init__.py +0 -0
  67. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/agnostic.py +0 -0
  68. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/base.py +0 -0
  69. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/configuration.py +0 -0
  70. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/custom_types.py +0 -0
  71. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/__init__.py +0 -0
  72. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/conversion/__init__.py +0 -0
  73. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/conversion/lightgbm.py +0 -0
  74. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/conversion/sklearn.py +0 -0
  75. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/conversion/xgboost.py +0 -0
  76. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/explainer.py +0 -0
  77. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/treeshapiq.py +0 -0
  78. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/tree/validation.py +0 -0
  79. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/utils.py +0 -0
  80. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/explainer/validation.py +0 -0
  81. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/game_theory/__init__.py +0 -0
  82. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/game_theory/aggregation.py +0 -0
  83. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/game_theory/core.py +0 -0
  84. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/game_theory/exact.py +0 -0
  85. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/game_theory/indices.py +0 -0
  86. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/game_theory/moebius_converter.py +0 -0
  87. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/__init__.py +0 -0
  88. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/__init__.py +0 -0
  89. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/_setup/__init__.py +0 -0
  90. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/_setup/_california_torch_setup.py +0 -0
  91. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/_setup/_resnet_setup.py +0 -0
  92. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/_setup/_vit_setup.py +0 -0
  93. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/data_valuation/__init__.py +0 -0
  94. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/data_valuation/base.py +0 -0
  95. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/data_valuation/benchmark.py +0 -0
  96. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/dataset_valuation/__init__.py +0 -0
  97. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/dataset_valuation/base.py +0 -0
  98. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/dataset_valuation/benchmark.py +0 -0
  99. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/ensemble_selection/__init__.py +0 -0
  100. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/ensemble_selection/base.py +0 -0
  101. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/ensemble_selection/benchmark.py +0 -0
  102. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/ensemble_selection/benchmark_random_forest.py +0 -0
  103. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/feature_selection/__init__.py +0 -0
  104. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/feature_selection/base.py +0 -0
  105. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/feature_selection/benchmark.py +0 -0
  106. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/global_xai/__init__.py +0 -0
  107. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/global_xai/base.py +0 -0
  108. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/global_xai/benchmark_tabular.py +0 -0
  109. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/local_xai/__init__.py +0 -0
  110. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/local_xai/benchmark_image.py +0 -0
  111. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/local_xai/benchmark_tabular.py +0 -0
  112. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/synthetic/__init__.py +0 -0
  113. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/synthetic/dummy.py +0 -0
  114. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/synthetic/random_game.py +0 -0
  115. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/synthetic/soum.py +0 -0
  116. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/treeshapiq_xai/__init__.py +0 -0
  117. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/treeshapiq_xai/base.py +0 -0
  118. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/treeshapiq_xai/benchmark.py +0 -0
  119. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/uncertainty/__init__.py +0 -0
  120. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/uncertainty/base.py +0 -0
  121. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/uncertainty/benchmark.py +0 -0
  122. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/unsupervised_cluster/__init__.py +0 -0
  123. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/unsupervised_cluster/base.py +0 -0
  124. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/unsupervised_cluster/benchmark.py +0 -0
  125. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/unsupervised_data/__init__.py +0 -0
  126. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/unsupervised_data/base.py +0 -0
  127. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/benchmark/unsupervised_data/benchmark.py +0 -0
  128. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/imputer/__init__.py +0 -0
  129. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/imputer/base.py +0 -0
  130. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/imputer/baseline_imputer.py +0 -0
  131. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/games/imputer/marginal_imputer.py +0 -0
  132. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/_config.py +0 -0
  133. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/bar.py +0 -0
  134. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/force.py +0 -0
  135. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/network.py +0 -0
  136. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/sentence.py +0 -0
  137. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/stacked_bar.py +0 -0
  138. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/upset.py +0 -0
  139. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/plot/waterfall.py +0 -0
  140. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/utils/datasets.py +0 -0
  141. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq/utils/modules.py +0 -0
  142. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq.egg-info/dependency_links.txt +0 -0
  143. {shapiq-1.3.0 → shapiq-1.3.2}/shapiq.egg-info/top_level.txt +0 -0
@@ -1,13 +1,31 @@
1
- ## Changelog
1
+ # Changelog
2
2
 
3
- ### v1.3.0 (2025-06-17)
3
+ ## v1.3.2 (2025-10-14)
4
4
 
5
- #### Highlights
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
- #### New Features
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
- #### Testing, Code-Quality and Documentation
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
- #### Bug Fixes
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
- ### v1.2.3 (2025-03-24)
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
- ### v1.2.2 (2025-03-11)
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
- ### v1.2.1 (2025-02-17)
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
- ### v1.2.0 (2025-01-15)
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
- ### v1.1.1 (2024-11-13)
92
+ ## v1.1.1 (2024-11-13)
75
93
 
76
- #### Improvements and Ease of Use
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
- #### Bug Fixes
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
- ### v1.1.0 (2024-11-07)
103
+ ## v1.1.0 (2024-11-07)
86
104
 
87
- #### New Features and Improvements
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
- #### Documentation
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
- #### Bug Fixes
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
- ### v1.0.1 (2024-06-05)
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
- ### v1.0.0 (2024-06-04)
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.0
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
- ## Changelog
276
+ # Changelog
277
277
 
278
- ### v1.3.0 (2025-06-17)
278
+ ## v1.3.2 (2025-10-14)
279
279
 
280
- #### Highlights
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
- #### New Features
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
- #### Testing, Code-Quality and Documentation
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
- #### Bug Fixes
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
- ### v1.2.3 (2025-03-24)
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
- ### v1.2.2 (2025-03-11)
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
- ### v1.2.1 (2025-02-17)
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
- ### v1.2.0 (2025-01-15)
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
- ### v1.1.1 (2024-11-13)
367
+ ## v1.1.1 (2024-11-13)
350
368
 
351
- #### Improvements and Ease of Use
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
- #### Bug Fixes
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
- ### v1.1.0 (2024-11-07)
378
+ ## v1.1.0 (2024-11-07)
361
379
 
362
- #### New Features and Improvements
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
- #### Documentation
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
- #### Bug Fixes
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
- ### v1.0.1 (2024-06-05)
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
- ### v1.0.0 (2024-06-04)
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
- "tensorflow; python_version < '3.13'",
88
- "tf-keras; python_version < '3.13'",
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", # exclude pickle restriction, atm. games are unpickled this will need to be fixed # TODO: must be fixed in the future
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.0"
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 [Hof25]_ models such as the ``TabPFNClassifier`` and ``TabPFNRegressor``. The explainer
29
- does not rely on classical imputation methods and is optimized for TabPFN's in-context learning
30
- approach. The explanation paradigm for TabPFN is described in Rundel et al. (2024) [Run24]_. In
31
- essence the explainer is a wrapper around the ``TabularExplainer`` class and uses the same API.
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
- .. [Run24] Rundel, D., Kobialka, J., von Crailsheim, C., Feurer, M., Nagler, T., Rügamer, D. (2024). Interpretable Machine Learning for TabPFN. In: Longo, L., Lapuschkin, S., Seifert, C. (eds) Explainable Artificial Intelligence. xAI 2024. Communications in Computer and Information Science, vol 2154. Springer, Cham. https://doi.org/10.1007/978-3-031-63797-1_23
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.ndarray[int]
56
- children_right: np.ndarray[int]
57
- features: np.ndarray[int]
58
- thresholds: np.ndarray[float]
59
- values: np.ndarray[float]
60
- node_sample_weight: np.ndarray[float]
61
- empty_prediction: float | None = None
62
- leaf_mask: np.ndarray[bool] | None = None
63
- n_features_in_tree: int | None = None
64
- max_feature_id: int | None = None
65
- feature_ids: set | None = None
66
- root_node_id: int | None = None
67
- n_nodes: int | None = None
68
- nodes: np.ndarray[int] | None = None
69
- feature_map_original_internal: dict[int, int] | None = None
70
- feature_map_internal_original: dict[int, int] | None = None
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.ndarray[int],
13
- children_right: np.ndarray[int],
14
- features: np.ndarray[int],
15
- node_sample_weight: np.ndarray[float],
16
- values: np.ndarray[float],
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.ndarray[int]]],
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.ndarray[int],
12
- parent_array: np.ndarray[int],
13
- ) -> np.ndarray[float]:
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.ndarray[float],
45
- leaf_sample_weights: np.ndarray[float],
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))