shapiq 1.2.3__tar.gz → 1.3.0__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 (160) hide show
  1. {shapiq-1.2.3 → shapiq-1.3.0}/CHANGELOG.md +33 -1
  2. {shapiq-1.2.3/shapiq.egg-info → shapiq-1.3.0}/PKG-INFO +72 -8
  3. {shapiq-1.2.3 → shapiq-1.3.0}/README.md +35 -6
  4. shapiq-1.3.0/pyproject.toml +245 -0
  5. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/__init__.py +14 -3
  6. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/approximator/__init__.py +8 -3
  7. shapiq-1.2.3/shapiq/approximator/_base.py → shapiq-1.3.0/shapiq/approximator/base.py +139 -61
  8. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/approximator/marginals/owen.py +58 -24
  9. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/approximator/marginals/stratified.py +40 -14
  10. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/approximator/montecarlo/__init__.py +1 -1
  11. shapiq-1.2.3/shapiq/approximator/montecarlo/_base.py → shapiq-1.3.0/shapiq/approximator/montecarlo/base.py +105 -64
  12. shapiq-1.3.0/shapiq/approximator/montecarlo/shapiq.py +165 -0
  13. shapiq-1.3.0/shapiq/approximator/montecarlo/svarmiq.py +124 -0
  14. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/approximator/permutation/sii.py +50 -18
  15. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/approximator/permutation/stii.py +67 -28
  16. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/approximator/permutation/sv.py +46 -8
  17. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/approximator/regression/__init__.py +1 -1
  18. shapiq-1.2.3/shapiq/approximator/regression/_base.py → shapiq-1.3.0/shapiq/approximator/regression/base.py +138 -83
  19. shapiq-1.3.0/shapiq/approximator/regression/faithful.py +134 -0
  20. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/approximator/regression/kadd_shap.py +34 -15
  21. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/approximator/regression/kernelshap.py +33 -15
  22. shapiq-1.3.0/shapiq/approximator/regression/kernelshapiq.py +157 -0
  23. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/approximator/sampling.py +128 -57
  24. shapiq-1.3.0/shapiq/approximator/sparse/__init__.py +9 -0
  25. shapiq-1.3.0/shapiq/approximator/sparse/base.py +303 -0
  26. shapiq-1.3.0/shapiq/approximator/sparse/spex.py +67 -0
  27. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/benchmark/__init__.py +0 -2
  28. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/benchmark/configuration.py +29 -37
  29. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/benchmark/load.py +41 -33
  30. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/benchmark/metrics.py +29 -18
  31. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/benchmark/plot.py +41 -31
  32. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/benchmark/precompute.py +44 -51
  33. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/benchmark/run.py +76 -61
  34. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/datasets/_all.py +28 -16
  35. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/explainer/__init__.py +3 -2
  36. shapiq-1.3.0/shapiq/explainer/agnostic.py +131 -0
  37. shapiq-1.3.0/shapiq/explainer/base.py +265 -0
  38. shapiq-1.3.0/shapiq/explainer/configuration.py +189 -0
  39. shapiq-1.3.0/shapiq/explainer/custom_types.py +7 -0
  40. shapiq-1.3.0/shapiq/explainer/tabpfn.py +159 -0
  41. shapiq-1.3.0/shapiq/explainer/tabular.py +209 -0
  42. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/explainer/tree/base.py +25 -22
  43. shapiq-1.3.0/shapiq/explainer/tree/conversion/__init__.py +1 -0
  44. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/explainer/tree/conversion/edges.py +39 -25
  45. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/explainer/tree/conversion/lightgbm.py +15 -14
  46. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/explainer/tree/conversion/sklearn.py +36 -18
  47. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/explainer/tree/conversion/xgboost.py +21 -12
  48. shapiq-1.3.0/shapiq/explainer/tree/explainer.py +152 -0
  49. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/explainer/tree/treeshapiq.py +194 -105
  50. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/explainer/tree/utils.py +7 -2
  51. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/explainer/tree/validation.py +21 -8
  52. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/explainer/utils.py +103 -43
  53. shapiq-1.3.0/shapiq/explainer/validation.py +137 -0
  54. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/game_theory/__init__.py +4 -2
  55. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/game_theory/aggregation.py +16 -11
  56. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/game_theory/core.py +26 -12
  57. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/game_theory/exact.py +301 -174
  58. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/game_theory/indices.py +57 -29
  59. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/game_theory/moebius_converter.py +184 -124
  60. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/__init__.py +0 -3
  61. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/base.py +155 -71
  62. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/__init__.py +1 -1
  63. shapiq-1.3.0/shapiq/games/benchmark/_setup/__init__.py +7 -0
  64. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/_setup/_california_torch_setup.py +30 -16
  65. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/_setup/_resnet_setup.py +24 -15
  66. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/_setup/_vit_setup.py +36 -24
  67. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/data_valuation/__init__.py +0 -2
  68. shapiq-1.3.0/shapiq/games/benchmark/data_valuation/base.py +124 -0
  69. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/data_valuation/benchmark.py +48 -0
  70. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/dataset_valuation/__init__.py +0 -2
  71. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/dataset_valuation/base.py +65 -33
  72. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/dataset_valuation/benchmark.py +68 -30
  73. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/ensemble_selection/__init__.py +0 -2
  74. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/ensemble_selection/base.py +116 -58
  75. shapiq-1.3.0/shapiq/games/benchmark/ensemble_selection/benchmark.py +201 -0
  76. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/ensemble_selection/benchmark_random_forest.py +68 -36
  77. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/feature_selection/__init__.py +0 -2
  78. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/feature_selection/base.py +55 -31
  79. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/feature_selection/benchmark.py +52 -32
  80. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/global_xai/__init__.py +0 -2
  81. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/global_xai/base.py +45 -23
  82. shapiq-1.3.0/shapiq/games/benchmark/global_xai/benchmark_tabular.py +194 -0
  83. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/local_xai/__init__.py +0 -2
  84. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/local_xai/base.py +41 -22
  85. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/local_xai/benchmark_image.py +70 -32
  86. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/local_xai/benchmark_language.py +34 -28
  87. shapiq-1.3.0/shapiq/games/benchmark/local_xai/benchmark_tabular.py +213 -0
  88. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/setup.py +66 -41
  89. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/synthetic/__init__.py +1 -3
  90. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/synthetic/dummy.py +20 -13
  91. shapiq-1.2.3/shapiq/games/benchmark/synthetic/random.py → shapiq-1.3.0/shapiq/games/benchmark/synthetic/random_game.py +17 -4
  92. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/synthetic/soum.py +93 -44
  93. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/treeshapiq_xai/__init__.py +0 -2
  94. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/treeshapiq_xai/base.py +67 -33
  95. shapiq-1.3.0/shapiq/games/benchmark/treeshapiq_xai/benchmark.py +270 -0
  96. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/uncertainty/__init__.py +0 -2
  97. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/uncertainty/base.py +60 -11
  98. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/uncertainty/benchmark.py +33 -7
  99. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/unsupervised_cluster/__init__.py +0 -2
  100. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/unsupervised_cluster/base.py +49 -18
  101. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/unsupervised_cluster/benchmark.py +55 -24
  102. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/unsupervised_data/__init__.py +0 -2
  103. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/benchmark/unsupervised_data/base.py +31 -15
  104. shapiq-1.3.0/shapiq/games/benchmark/unsupervised_data/benchmark.py +76 -0
  105. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/imputer/base.py +56 -28
  106. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/imputer/baseline_imputer.py +48 -21
  107. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/imputer/conditional_imputer.py +73 -37
  108. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/imputer/marginal_imputer.py +55 -25
  109. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/imputer/tabpfn_imputer.py +61 -29
  110. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/interaction_values.py +208 -130
  111. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/plot/__init__.py +1 -1
  112. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/plot/_config.py +4 -1
  113. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/plot/bar.py +13 -2
  114. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/plot/force.py +88 -50
  115. shapiq-1.3.0/shapiq/plot/network.py +70 -0
  116. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/plot/sentence.py +15 -8
  117. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/plot/si_graph.py +486 -242
  118. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/plot/stacked_bar.py +21 -16
  119. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/plot/upset.py +25 -9
  120. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/plot/utils.py +62 -8
  121. shapiq-1.2.3/shapiq/plot/watefall.py → shapiq-1.3.0/shapiq/plot/waterfall.py +54 -21
  122. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/utils/__init__.py +3 -1
  123. shapiq-1.3.0/shapiq/utils/custom_types.py +30 -0
  124. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/utils/datasets.py +6 -1
  125. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/utils/modules.py +23 -16
  126. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/utils/sets.py +67 -23
  127. {shapiq-1.2.3 → shapiq-1.3.0/shapiq.egg-info}/PKG-INFO +72 -8
  128. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq.egg-info/SOURCES.txt +15 -11
  129. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq.egg-info/requires.txt +3 -0
  130. shapiq-1.2.3/pyproject.toml +0 -121
  131. shapiq-1.2.3/shapiq/approximator/montecarlo/shapiq.py +0 -130
  132. shapiq-1.2.3/shapiq/approximator/montecarlo/svarmiq.py +0 -89
  133. shapiq-1.2.3/shapiq/approximator/regression/faithful.py +0 -97
  134. shapiq-1.2.3/shapiq/approximator/regression/kernelshapiq.py +0 -132
  135. shapiq-1.2.3/shapiq/explainer/_base.py +0 -153
  136. shapiq-1.2.3/shapiq/explainer/tabpfn.py +0 -129
  137. shapiq-1.2.3/shapiq/explainer/tabular.py +0 -291
  138. shapiq-1.2.3/shapiq/explainer/tree/conversion/__init__.py +0 -0
  139. shapiq-1.2.3/shapiq/explainer/tree/explainer.py +0 -125
  140. shapiq-1.2.3/shapiq/games/benchmark/_setup/__init__.py +0 -4
  141. shapiq-1.2.3/shapiq/games/benchmark/data_valuation/base.py +0 -92
  142. shapiq-1.2.3/shapiq/games/benchmark/ensemble_selection/benchmark.py +0 -166
  143. shapiq-1.2.3/shapiq/games/benchmark/global_xai/benchmark_tabular.py +0 -157
  144. shapiq-1.2.3/shapiq/games/benchmark/local_xai/benchmark_tabular.py +0 -171
  145. shapiq-1.2.3/shapiq/games/benchmark/treeshapiq_xai/benchmark.py +0 -216
  146. shapiq-1.2.3/shapiq/games/benchmark/unsupervised_data/benchmark.py +0 -37
  147. shapiq-1.2.3/shapiq/plot/network.py +0 -382
  148. shapiq-1.2.3/shapiq/utils/types.py +0 -6
  149. shapiq-1.2.3/tests/test_base_interaction_values.py +0 -774
  150. shapiq-1.2.3/tests/test_configuration.py +0 -17
  151. shapiq-1.2.3/tests/test_integration_import_all.py +0 -60
  152. {shapiq-1.2.3 → shapiq-1.3.0}/LICENSE +0 -0
  153. {shapiq-1.2.3 → shapiq-1.3.0}/setup.cfg +0 -0
  154. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/approximator/marginals/__init__.py +0 -0
  155. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/approximator/permutation/__init__.py +0 -0
  156. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/datasets/__init__.py +0 -0
  157. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/explainer/tree/__init__.py +0 -0
  158. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq/games/imputer/__init__.py +0 -0
  159. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq.egg-info/dependency_links.txt +0 -0
  160. {shapiq-1.2.3 → shapiq-1.3.0}/shapiq.egg-info/top_level.txt +0 -0
@@ -1,6 +1,38 @@
1
1
  ## Changelog
2
2
 
3
- ### Development
3
+ ### v1.3.0 (2025-06-17)
4
+
5
+ #### Highlights
6
+ - `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
+ - `shapiq.AgnosticExplainer` a generic explainer that works for any value function or `shapiq.Game` object, allowing for more flexibility in explainers.
8
+ - 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
+
10
+ #### New Features
11
+ - 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
+ - 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
+ - changes `budget` to be a mandatory parameter given to the `TabularExplainer.explain()` method [#355](https://github.com/mmschlk/shapiq/pull/356)
14
+ - changes logic of `InteractionValues.get_n_order()` function to be callable with **either** the `order: int` parameter and optional assignment of `min_order: int` and `max_order: int` parameters **or** with the min/max order parameters [#372](https://github.com/mmschlk/shapiq/pull/372)
15
+ - renamed `min_percentage` parameter in the force plot to `contribution_threshold` to better reflect its purpose [#391](https://github.com/mmschlk/shapiq/pull/391)
16
+ - adds ``verbose`` parameter to the ``Explainer``'s ``explain_X()`` method to control weather a progress bar is shown or not which is defaulted to ``False``. [#391](https://github.com/mmschlk/shapiq/pull/391)
17
+ - made `InteractionValues.get_n_order()` and `InteractionValues.get_n_order_values()` function more efficient by iterating over the stored interactions and not over the powerset of all potential interactions, which made the function not usable for higher player counts (models with many features, and results obtained from `TreeExplainer`). Note, this change does not really help `get_n_order_values()` as it still needs to create a numpy array of shape `n_players` times `order` [#372](https://github.com/mmschlk/shapiq/pull/372)
18
+ - streamlined the ``network_plot()`` plot function to use the ``si_graph_plot()`` as its backend function. This allows for more flexibility in the plot function and makes it easier to use the same code for different purposes. In addition, the ``si_graph_plot`` was modified to make plotting more easy and allow for more flexibility with new parameters. [#349](https://github.com/mmschlk/shapiq/pull/349)
19
+ - 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
+ - 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
+
22
+ #### Testing, Code-Quality and Documentation
23
+ - 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
+ - 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
+ - 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)
26
+ - removed multiple instances where ``shapiq`` tests if some approximators/explainers can be instantiated with certain indices or not in favor of using Literals in the ``__init__`` method of the approximator classes. This allows for better type hinting and IDE support, as well as cleaner code. [#391](https://github.com/mmschlk/shapiq/pull/391)
27
+ - Added documentation for all public modules, classes, and functions in the code base to improve the documentation quality and make it easier to understand how to use the package. [#391](https://github.com/mmschlk/shapiq/pull/391)
28
+ - suppress a ``RuntimeWarning`` in ``Regression`` approximators ``solve_regression()``method when the solver is not able to find good interim solutions for the regression problem.
29
+ - 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
+ - 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
+
32
+ #### Bug Fixes
33
+ - 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
+ - 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
+ - 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)
4
36
 
5
37
  ### v1.2.3 (2025-03-24)
6
38
  - 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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shapiq
3
- Version: 1.2.3
3
+ Version: 1.3.0
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>
@@ -33,9 +33,12 @@ Requires-Dist: pandas
33
33
  Requires-Dist: scikit-learn
34
34
  Requires-Dist: tqdm
35
35
  Requires-Dist: requests
36
+ Requires-Dist: sparse-transform
37
+ Requires-Dist: galois
36
38
  Requires-Dist: matplotlib
37
39
  Requires-Dist: networkx
38
40
  Requires-Dist: colour
41
+ Requires-Dist: pillow
39
42
  Provides-Extra: ml
40
43
  Requires-Dist: tabpfn; extra == "ml"
41
44
  Requires-Dist: torchvision; extra == "ml"
@@ -62,15 +65,21 @@ Dynamic: license-file
62
65
  [![PePy](https://static.pepy.tech/badge/shapiq?style=flat-square)](https://pepy.tech/project/shapiq)
63
66
 
64
67
  [![Code Style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
65
- ![Contributions Welcome](https://img.shields.io/badge/contributions-welcome-brightgreen)
66
- ![Last Commit](https://img.shields.io/github/last-commit/mmschlk/shapiq)
68
+ [![Contributions Welcome](https://img.shields.io/badge/contributions-welcome-brightgreen)](https://github.com/mmschlk/shapiq/issues)
69
+ [![Last Commit](https://img.shields.io/github/last-commit/mmschlk/shapiq)](https://github.com/mmschlk/shapiq/commits/main)
67
70
 
68
71
  > An interaction may speak more than a thousand main effects.
69
72
 
70
73
  Shapley Interaction Quantification (`shapiq`) is a Python package for (1) approximating any-order Shapley interactions, (2) benchmarking game-theoretical algorithms for machine learning, (3) explaining feature interactions of model predictions. `shapiq` extends the well-known [shap](https://github.com/shap/shap) package for both researchers working on game theory in machine learning, as well as the end-users explaining models. SHAP-IQ extends individual Shapley values by quantifying the **synergy** effect between entities (aka **players** in the jargon of game theory) like explanatory features, data points, or weak learners in ensemble models. Synergies between players give a more comprehensive view of machine learning models.
71
74
 
72
75
  ## 🛠️ Install
73
- `shapiq` is intended to work with **Python 3.10 and above**. Installation can be done via `pip`:
76
+ `shapiq` is intended to work with **Python 3.10 and above**.
77
+ Installation can be done via `uv` :
78
+ ```sh
79
+ uv add shapiq
80
+ ```
81
+
82
+ or via `pip`:
74
83
 
75
84
  ```sh
76
85
  pip install shapiq
@@ -84,6 +93,7 @@ If you are interested in the underlying game theoretic algorithms, then check ou
84
93
  ### Compute any-order feature interactions
85
94
 
86
95
  Explain your models with Shapley interactions:
96
+ Just load your data and model, and then use a `shapiq.Explainer` to compute Shapley interactions.
87
97
 
88
98
  ```python
89
99
  import shapiq
@@ -182,7 +192,7 @@ The pseudo-code above can produce the following plot (here also an image is adde
182
192
 
183
193
  ### Explain TabPFN
184
194
 
185
- With ``shapiq`` you can also [``TabPFN``](https://github.com/PriorLabs/TabPFN) by making use of the _remove-and-recontextualize_ explanation paradigm implemented in ``shapiq.TabPFNExplainer``.
195
+ With ``shapiq`` you can also explain [``TabPFN``](https://github.com/PriorLabs/TabPFN) by making use of the _remove-and-recontextualize_ explanation paradigm implemented in ``shapiq.TabPFNExplainer``.
186
196
 
187
197
  ```python
188
198
  import tabpfn, shapiq
@@ -195,7 +205,7 @@ explainer = shapiq.TabPFNExplainer( # setup the explainer
195
205
  labels=labels,
196
206
  index="FSII"
197
207
  )
198
- fsii_values = explainer.explain(X[0]) # explain with Faithful Shapley values
208
+ fsii_values = explainer.explain(data[0]) # explain with Faithful Shapley values
199
209
  fsii_values.plot_force() # plot the force plot
200
210
  ```
201
211
 
@@ -203,6 +213,28 @@ fsii_values.plot_force() # plot the force plot
203
213
  <img width="800px" src="https://raw.githubusercontent.com/mmschlk/shapiq/main/docs/source/_static/images/fsii_tabpfn_force_plot_example.png" alt="Force Plot of FSII values as derived from the example tabpfn notebook">
204
214
  </p>
205
215
 
216
+ ### Use SPEX (SParse EXplainer) <img src="https://raw.githubusercontent.com/mmschlk/shapiq/main/docs/source/_static/images/spex_logo.png" alt="spex_logo" align="right" height="75px"/>
217
+ For large-scale use-cases you can also check out the [👓``SPEX``](https://shapiq.readthedocs.io/en/latest/api/shapiq.approximator.sparse.html#shapiq.approximator.sparse.SPEX) approximator.
218
+
219
+ ```python
220
+ # load your data and model with large number of features
221
+ data, model, n_features = ...
222
+
223
+ # use the SPEX approximator directly
224
+ approximator = shapiq.SPEX(n=n_features, index="FBII", max_order=2)
225
+ fbii_scores = approximator.approximate(budget=2000, game=model.predict)
226
+
227
+ # or use SPEX with an explainer
228
+ explainer = shapiq.Explainer(
229
+ model=model,
230
+ data=data,
231
+ index="FBII",
232
+ max_order=2,
233
+ approximator="spex" # specify SPEX as approximator
234
+ )
235
+ explanation = explainer.explain(data[0])
236
+ ```
237
+
206
238
 
207
239
  ## 📖 Documentation with tutorials
208
240
  The documentation of ``shapiq`` can be found at https://shapiq.readthedocs.io.
@@ -214,7 +246,7 @@ There is a lot of great resources available to get you started with Shapley valu
214
246
  If you use ``shapiq`` and enjoy it, please consider citing our [NeurIPS paper](https://arxiv.org/abs/2410.01649) or consider starring this repository.
215
247
 
216
248
  ```bibtex
217
- @inproceedings{muschalik2024shapiq,
249
+ @inproceedings{Muschalik.2024b,
218
250
  title = {shapiq: Shapley Interactions for Machine Learning},
219
251
  author = {Maximilian Muschalik and Hubert Baniecki and Fabian Fumagalli and
220
252
  Patrick Kolpaczki and Barbara Hammer and Eyke H\"{u}llermeier},
@@ -243,7 +275,39 @@ Built with ❤️ by the shapiq team.
243
275
 
244
276
  ## Changelog
245
277
 
246
- ### Development
278
+ ### v1.3.0 (2025-06-17)
279
+
280
+ #### Highlights
281
+ - `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
+ - `shapiq.AgnosticExplainer` a generic explainer that works for any value function or `shapiq.Game` object, allowing for more flexibility in explainers.
283
+ - 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
+
285
+ #### New Features
286
+ - 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
+ - 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
+ - changes `budget` to be a mandatory parameter given to the `TabularExplainer.explain()` method [#355](https://github.com/mmschlk/shapiq/pull/356)
289
+ - changes logic of `InteractionValues.get_n_order()` function to be callable with **either** the `order: int` parameter and optional assignment of `min_order: int` and `max_order: int` parameters **or** with the min/max order parameters [#372](https://github.com/mmschlk/shapiq/pull/372)
290
+ - renamed `min_percentage` parameter in the force plot to `contribution_threshold` to better reflect its purpose [#391](https://github.com/mmschlk/shapiq/pull/391)
291
+ - adds ``verbose`` parameter to the ``Explainer``'s ``explain_X()`` method to control weather a progress bar is shown or not which is defaulted to ``False``. [#391](https://github.com/mmschlk/shapiq/pull/391)
292
+ - made `InteractionValues.get_n_order()` and `InteractionValues.get_n_order_values()` function more efficient by iterating over the stored interactions and not over the powerset of all potential interactions, which made the function not usable for higher player counts (models with many features, and results obtained from `TreeExplainer`). Note, this change does not really help `get_n_order_values()` as it still needs to create a numpy array of shape `n_players` times `order` [#372](https://github.com/mmschlk/shapiq/pull/372)
293
+ - streamlined the ``network_plot()`` plot function to use the ``si_graph_plot()`` as its backend function. This allows for more flexibility in the plot function and makes it easier to use the same code for different purposes. In addition, the ``si_graph_plot`` was modified to make plotting more easy and allow for more flexibility with new parameters. [#349](https://github.com/mmschlk/shapiq/pull/349)
294
+ - 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
+ - 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
+
297
+ #### Testing, Code-Quality and Documentation
298
+ - 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
+ - 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
+ - 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)
301
+ - removed multiple instances where ``shapiq`` tests if some approximators/explainers can be instantiated with certain indices or not in favor of using Literals in the ``__init__`` method of the approximator classes. This allows for better type hinting and IDE support, as well as cleaner code. [#391](https://github.com/mmschlk/shapiq/pull/391)
302
+ - Added documentation for all public modules, classes, and functions in the code base to improve the documentation quality and make it easier to understand how to use the package. [#391](https://github.com/mmschlk/shapiq/pull/391)
303
+ - suppress a ``RuntimeWarning`` in ``Regression`` approximators ``solve_regression()``method when the solver is not able to find good interim solutions for the regression problem.
304
+ - 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
+ - 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
+
307
+ #### Bug Fixes
308
+ - 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
+ - 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
+ - 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)
247
311
 
248
312
  ### v1.2.3 (2025-03-24)
249
313
  - 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)
@@ -11,15 +11,21 @@
11
11
  [![PePy](https://static.pepy.tech/badge/shapiq?style=flat-square)](https://pepy.tech/project/shapiq)
12
12
 
13
13
  [![Code Style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
14
- ![Contributions Welcome](https://img.shields.io/badge/contributions-welcome-brightgreen)
15
- ![Last Commit](https://img.shields.io/github/last-commit/mmschlk/shapiq)
14
+ [![Contributions Welcome](https://img.shields.io/badge/contributions-welcome-brightgreen)](https://github.com/mmschlk/shapiq/issues)
15
+ [![Last Commit](https://img.shields.io/github/last-commit/mmschlk/shapiq)](https://github.com/mmschlk/shapiq/commits/main)
16
16
 
17
17
  > An interaction may speak more than a thousand main effects.
18
18
 
19
19
  Shapley Interaction Quantification (`shapiq`) is a Python package for (1) approximating any-order Shapley interactions, (2) benchmarking game-theoretical algorithms for machine learning, (3) explaining feature interactions of model predictions. `shapiq` extends the well-known [shap](https://github.com/shap/shap) package for both researchers working on game theory in machine learning, as well as the end-users explaining models. SHAP-IQ extends individual Shapley values by quantifying the **synergy** effect between entities (aka **players** in the jargon of game theory) like explanatory features, data points, or weak learners in ensemble models. Synergies between players give a more comprehensive view of machine learning models.
20
20
 
21
21
  ## 🛠️ Install
22
- `shapiq` is intended to work with **Python 3.10 and above**. Installation can be done via `pip`:
22
+ `shapiq` is intended to work with **Python 3.10 and above**.
23
+ Installation can be done via `uv` :
24
+ ```sh
25
+ uv add shapiq
26
+ ```
27
+
28
+ or via `pip`:
23
29
 
24
30
  ```sh
25
31
  pip install shapiq
@@ -33,6 +39,7 @@ If you are interested in the underlying game theoretic algorithms, then check ou
33
39
  ### Compute any-order feature interactions
34
40
 
35
41
  Explain your models with Shapley interactions:
42
+ Just load your data and model, and then use a `shapiq.Explainer` to compute Shapley interactions.
36
43
 
37
44
  ```python
38
45
  import shapiq
@@ -131,7 +138,7 @@ The pseudo-code above can produce the following plot (here also an image is adde
131
138
 
132
139
  ### Explain TabPFN
133
140
 
134
- With ``shapiq`` you can also [``TabPFN``](https://github.com/PriorLabs/TabPFN) by making use of the _remove-and-recontextualize_ explanation paradigm implemented in ``shapiq.TabPFNExplainer``.
141
+ With ``shapiq`` you can also explain [``TabPFN``](https://github.com/PriorLabs/TabPFN) by making use of the _remove-and-recontextualize_ explanation paradigm implemented in ``shapiq.TabPFNExplainer``.
135
142
 
136
143
  ```python
137
144
  import tabpfn, shapiq
@@ -144,7 +151,7 @@ explainer = shapiq.TabPFNExplainer( # setup the explainer
144
151
  labels=labels,
145
152
  index="FSII"
146
153
  )
147
- fsii_values = explainer.explain(X[0]) # explain with Faithful Shapley values
154
+ fsii_values = explainer.explain(data[0]) # explain with Faithful Shapley values
148
155
  fsii_values.plot_force() # plot the force plot
149
156
  ```
150
157
 
@@ -152,6 +159,28 @@ fsii_values.plot_force() # plot the force plot
152
159
  <img width="800px" src="https://raw.githubusercontent.com/mmschlk/shapiq/main/docs/source/_static/images/fsii_tabpfn_force_plot_example.png" alt="Force Plot of FSII values as derived from the example tabpfn notebook">
153
160
  </p>
154
161
 
162
+ ### Use SPEX (SParse EXplainer) <img src="https://raw.githubusercontent.com/mmschlk/shapiq/main/docs/source/_static/images/spex_logo.png" alt="spex_logo" align="right" height="75px"/>
163
+ For large-scale use-cases you can also check out the [👓``SPEX``](https://shapiq.readthedocs.io/en/latest/api/shapiq.approximator.sparse.html#shapiq.approximator.sparse.SPEX) approximator.
164
+
165
+ ```python
166
+ # load your data and model with large number of features
167
+ data, model, n_features = ...
168
+
169
+ # use the SPEX approximator directly
170
+ approximator = shapiq.SPEX(n=n_features, index="FBII", max_order=2)
171
+ fbii_scores = approximator.approximate(budget=2000, game=model.predict)
172
+
173
+ # or use SPEX with an explainer
174
+ explainer = shapiq.Explainer(
175
+ model=model,
176
+ data=data,
177
+ index="FBII",
178
+ max_order=2,
179
+ approximator="spex" # specify SPEX as approximator
180
+ )
181
+ explanation = explainer.explain(data[0])
182
+ ```
183
+
155
184
 
156
185
  ## 📖 Documentation with tutorials
157
186
  The documentation of ``shapiq`` can be found at https://shapiq.readthedocs.io.
@@ -163,7 +192,7 @@ There is a lot of great resources available to get you started with Shapley valu
163
192
  If you use ``shapiq`` and enjoy it, please consider citing our [NeurIPS paper](https://arxiv.org/abs/2410.01649) or consider starring this repository.
164
193
 
165
194
  ```bibtex
166
- @inproceedings{muschalik2024shapiq,
195
+ @inproceedings{Muschalik.2024b,
167
196
  title = {shapiq: Shapley Interactions for Machine Learning},
168
197
  author = {Maximilian Muschalik and Hubert Baniecki and Fabian Fumagalli and
169
198
  Patrick Kolpaczki and Barbara Hammer and Eyke H\"{u}llermeier},
@@ -0,0 +1,245 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "shapiq"
7
+ dynamic = ["version", "readme"]
8
+ description = "Shapley Interactions for Machine Learning"
9
+ requires-python = ">=3.10"
10
+ dependencies = [
11
+ # core
12
+ "numpy",
13
+ "scipy",
14
+ "pandas",
15
+ "scikit-learn",
16
+ "tqdm",
17
+ "requests",
18
+ "sparse-transform",
19
+ "galois",
20
+ # plotting
21
+ "matplotlib",
22
+ "networkx",
23
+ "colour",
24
+ "pillow",
25
+ ]
26
+ authors = [
27
+ {name = "Maximilian Muschalik", email = "Maximilian.Muschalik@lmu.de"},
28
+ {name = "Hubert Baniecki"},
29
+ {name = "Fabian Fumagalli"},
30
+ ]
31
+ maintainers = [
32
+ {name = "Maximilian Muschalik", email = "Maximilian.Muschalik@lmu.de"},
33
+ ]
34
+ license = "MIT"
35
+ classifiers = [
36
+ "Development Status :: 4 - Beta",
37
+ "Intended Audience :: Developers",
38
+ "Intended Audience :: Science/Research",
39
+ "Topic :: Scientific/Engineering",
40
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
41
+ 'Operating System :: Microsoft :: Windows',
42
+ 'Operating System :: Unix',
43
+ 'Operating System :: MacOS',
44
+ 'Programming Language :: Python :: 3',
45
+ 'Programming Language :: Python :: 3.10',
46
+ 'Programming Language :: Python :: 3.11',
47
+ 'Programming Language :: Python :: 3.12',
48
+ 'Programming Language :: Python :: 3.13',
49
+ ]
50
+ keywords = [
51
+ "python",
52
+ "machine learning",
53
+ "interpretable machine learning",
54
+ "shap",
55
+ "xai",
56
+ "explainable ai",
57
+ "interaction",
58
+ "shapley interactions",
59
+ "shapley values",
60
+ "feature interaction",
61
+ ]
62
+
63
+ [tool.setuptools.packages.find]
64
+ where = ["."]
65
+ include = ["shapiq*"]
66
+
67
+ [tool.setuptools.dynamic]
68
+ version = {attr = "shapiq.__version__"}
69
+ readme = {file = ["README.md", "CHANGELOG.md"], content-type = "text/markdown"}
70
+
71
+ [project.urls]
72
+ documentation = "https://shapiq.readthedocs.io"
73
+ source = "https://github.com/mmschlk/shapiq"
74
+ tracker = "https://github.com/mmschlk/shapiq/issues"
75
+ changelog = "https://github.com/mmschlk/shapiq/blob/main/CHANGELOG.md"
76
+
77
+ [project.optional-dependencies]
78
+ ml = [
79
+ "tabpfn",
80
+ "torchvision",
81
+ "torch",
82
+ "xgboost",
83
+ "lightgbm",
84
+ "transformers",
85
+ "scikit-image",
86
+ "joblib",
87
+ "tensorflow; python_version < '3.13'",
88
+ "tf-keras; python_version < '3.13'",
89
+ ]
90
+
91
+ [tool.pytest.ini_options]
92
+ testpaths = ["tests"]
93
+ minversion = "8.0"
94
+
95
+ [tool.ruff]
96
+ line-length = 100
97
+ target-version = "py310"
98
+ src = ["tests", "shapiq", "docs"]
99
+
100
+
101
+ [tool.ruff.lint]
102
+ # we allow star arguments to be of type Any e.g. def func(*args: Any, **kwargs: Any) -> None: is ok
103
+ flake8-annotations.allow-star-arg-any = true
104
+ select = ["ALL"]
105
+ ignore = [
106
+ "E501", # Line too long
107
+ "N803", # Variable X in function should be lowercase
108
+ "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
+ "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
+ "FIX002", # we use TODOs atm to track potential code improvements # TODO: add this in the future
112
+ "PLR0913", # Too many arguments are passed to function
113
+ "PLR0915", # Too many statements in function
114
+ "PLR0912", # Too many branches in function
115
+ "PLR2004", # Magic values in comparison ... this gets flaged with all checks for two-way interactions
116
+ "C901", # Too complex functions
117
+ "PLR0911", # too many return statements in function
118
+ "N802", # Function name should be lowercase
119
+ ]
120
+ exclude = [
121
+ ".bzr",
122
+ ".direnv",
123
+ ".eggs",
124
+ ".git",
125
+ ".git-rewrite",
126
+ ".hg",
127
+ ".ipynb_checkpoints",
128
+ ".mypy_cache",
129
+ ".nox",
130
+ ".pants.d",
131
+ ".pyenv",
132
+ ".pytest_cache",
133
+ ".pytype",
134
+ ".ruff_cache",
135
+ ".svn",
136
+ ".tox",
137
+ ".venv",
138
+ ".vscode",
139
+ "__pypackages__",
140
+ "_build",
141
+ "buck-out",
142
+ "build",
143
+ "dist",
144
+ "node_modules",
145
+ "site-packages",
146
+ "venv",
147
+ "docs/build",
148
+ ]
149
+
150
+ # Exclude a variety of commonly ignored directories.
151
+ # Note to developers: If you add a new ignore at least put a comment next to it why it is ignored
152
+ [tool.ruff.lint.per-file-ignores]
153
+ "tests/*.py" = [
154
+ # "ALL",
155
+ "S101", # we need asserts in tests
156
+ "D", # test docstrings don't matter too much
157
+ "E501", # line too long
158
+ "ANN", # type annotations
159
+ "ARG", # some functions are not used
160
+ "INP", # inports can be different
161
+ "N", # type hints are excludes in tests
162
+ "PTH", # we can use os for now
163
+ "S", # in tests we can use some security issues for now
164
+ "PT", # we can use print statements in tests
165
+ "NPY",
166
+ "SLF", # private members are okay in tests
167
+ "TRY",
168
+ ]
169
+ "*.ipynb" = [
170
+ "E402", # Module level import not at top of file (its .ipynb)
171
+ "T20", # notebooks can have print statements
172
+ "I002", # notebooks do not have to import required modules
173
+ "D", # docstrings are not required in notebooks
174
+ "SLF001", # private members are okay in notebooks
175
+ "ANN001", # type annotations are not required in notebooks
176
+ ]
177
+ "docs/source/*.py" = [
178
+ "A001", # some conf.py variables shadow builtins which is okay here
179
+ "ANN001", # some magic functions I don't want to annotate
180
+ "INP", # docs can be an implicit package (does not need to be imported)
181
+ "I002", # benchmark code does not have to import required modules
182
+ ]
183
+ "benchmark/*.py" = [
184
+ "INP", # imports can be different here
185
+ "I002", # benchmark code does not have to import required modules
186
+ "PTH" # in benchmark code we use a lot of os, which is okay
187
+ ]
188
+ "docs/copy_notebooks.py" = [
189
+ "PTH", # the script uses os, which is not cirtical for shapiq so it's fine
190
+ "I002", # benchmark code does not have to import required modules
191
+ ]
192
+ "__init__.py" = [
193
+ "I002", # __init__.py does not have to import required modules
194
+ "RUF022", # we can have unsorted imports in __init__.py
195
+ "FA",
196
+ ]
197
+ "scripts/*.py" = [
198
+ "INP", # imports can be different here
199
+ "I002", # script code does not have to import required modules
200
+ "PTH" # in script code we use a lot of os, which is okay
201
+ ]
202
+
203
+ [tool.ruff.lint.pydocstyle]
204
+ convention = "google"
205
+
206
+ [tool.ruff.lint.isort]
207
+ known-first-party = ["shapiq"]
208
+ extra-standard-library = ["typing_extensions"]
209
+ combine-as-imports = true
210
+ force-wrap-aliases = true
211
+ no-lines-before = ["future"]
212
+ required-imports = ["from __future__ import annotations"]
213
+
214
+ [dependency-groups]
215
+ test = [
216
+ "pytest>=8.3.5",
217
+ "pytest-cov>=6.0.0",
218
+ "pytest-xdist>=3.6.1",
219
+ "pytest-randomly",
220
+ ]
221
+ lint = [
222
+ "ruff>=0.11.2",
223
+ "pre-commit>=4.2.0",
224
+ ]
225
+ docs = [
226
+ "sphinx>=8.0.0",
227
+ "furo",
228
+ "myst-parser",
229
+ "sphinx-copybutton",
230
+ "sphinx-autodoc-typehints",
231
+ "sphinx_toolbox",
232
+ "sphinxcontrib-bibtex", # references based on bibtex
233
+ "nbconvert",
234
+ "nbsphinx",
235
+ "commonmark", # Markdown parser and renderer
236
+ ]
237
+ dev = [
238
+ "build>=1.2.2.post1",
239
+ "twine>=6.1.0",
240
+ "notebook>=7.3.3",
241
+ "ipywidgets",
242
+ {include-group = "test"},
243
+ {include-group = "lint"},
244
+ {include-group = "docs"},
245
+ ]
@@ -1,12 +1,15 @@
1
- """shapiq is a library creating explanations for machine learning models based on
1
+ """shapiq: Shapley Interactions for Machine Learning.
2
+
3
+ shapiq is a library creating explanations for machine learning models based on
2
4
  the well established Shapley value and its generalization to interaction.
3
5
  """
4
6
 
5
- __version__ = "1.2.3"
7
+ __version__ = "1.3.0"
6
8
 
7
9
  # approximator classes
8
10
  from .approximator import (
9
11
  SHAPIQ,
12
+ SPEX,
10
13
  SVARM,
11
14
  SVARMIQ,
12
15
  InconsistentKernelSHAPIQ,
@@ -40,7 +43,13 @@ from .benchmark import (
40
43
  from .datasets import load_adult_census, load_bike_sharing, load_california_housing
41
44
 
42
45
  # explainer classes
43
- from .explainer import Explainer, TabPFNExplainer, TabularExplainer, TreeExplainer
46
+ from .explainer import (
47
+ AgnosticExplainer,
48
+ Explainer,
49
+ TabPFNExplainer,
50
+ TabularExplainer,
51
+ TreeExplainer,
52
+ )
44
53
 
45
54
  # exact computer classes
46
55
  from .game_theory.exact import ExactComputer
@@ -95,11 +104,13 @@ __all__ = [
95
104
  "SVARMIQ",
96
105
  "kADDSHAP",
97
106
  "UnbiasedKernelSHAP",
107
+ "SPEX",
98
108
  # explainers
99
109
  "Explainer",
100
110
  "TabularExplainer",
101
111
  "TreeExplainer",
102
112
  "TabPFNExplainer",
113
+ "AgnosticExplainer",
103
114
  # imputers
104
115
  "MarginalImputer",
105
116
  "BaselineImputer",
@@ -1,6 +1,6 @@
1
1
  """Approximators to estimate the Shapley interaction values."""
2
2
 
3
- from ._base import Approximator
3
+ from .base import Approximator
4
4
  from .marginals import OwenSamplingSV, StratifiedSamplingSV
5
5
  from .montecarlo import SHAPIQ, SVARM, SVARMIQ, UnbiasedKernelSHAP
6
6
  from .permutation.sii import PermutationSamplingSII
@@ -14,6 +14,7 @@ from .regression import (
14
14
  RegressionFSII,
15
15
  kADDSHAP,
16
16
  )
17
+ from .sparse import SPEX
17
18
 
18
19
  # contains all SV approximators
19
20
  SV_APPROXIMATORS: list[Approximator.__class__] = [
@@ -24,6 +25,7 @@ SV_APPROXIMATORS: list[Approximator.__class__] = [
24
25
  PermutationSamplingSV,
25
26
  KernelSHAP,
26
27
  kADDSHAP,
28
+ SPEX,
27
29
  ]
28
30
 
29
31
  # contains all SI approximators
@@ -44,6 +46,7 @@ SII_APPROXIMATORS: list[Approximator.__class__] = [
44
46
  InconsistentKernelSHAPIQ,
45
47
  SVARMIQ,
46
48
  SHAPIQ,
49
+ SPEX,
47
50
  ]
48
51
 
49
52
  # contains all approximators that can be used for STII
@@ -53,6 +56,7 @@ STII_APPROXIMATORS: list[Approximator.__class__] = [
53
56
  InconsistentKernelSHAPIQ,
54
57
  SVARMIQ,
55
58
  SHAPIQ,
59
+ SPEX,
56
60
  ]
57
61
 
58
62
  # contains all approximators that can be used for FSII
@@ -62,11 +66,13 @@ FSII_APPROXIMATORS: list[Approximator.__class__] = [
62
66
  InconsistentKernelSHAPIQ,
63
67
  SVARMIQ,
64
68
  SHAPIQ,
69
+ SPEX,
65
70
  ]
66
71
 
67
72
  # contains all approximators that can be used for FBII
68
73
  FBII_APPROXIMATORS: list[Approximator.__class__] = [
69
74
  RegressionFBII,
75
+ SPEX,
70
76
  ]
71
77
 
72
78
  __all__ = [
@@ -84,6 +90,7 @@ __all__ = [
84
90
  "SVARM",
85
91
  "SVARMIQ",
86
92
  "kADDSHAP",
93
+ "SPEX",
87
94
  "UnbiasedKernelSHAP",
88
95
  "SV_APPROXIMATORS",
89
96
  "SI_APPROXIMATORS",
@@ -92,5 +99,3 @@ __all__ = [
92
99
  "FSII_APPROXIMATORS",
93
100
  "FBII_APPROXIMATORS",
94
101
  ]
95
-
96
- # Path: shapiq/approximator/__init__.py