shapiq 1.2.1__tar.gz → 1.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {shapiq-1.2.1 → shapiq-1.2.2}/CHANGELOG.md +5 -1
- {shapiq-1.2.1/shapiq.egg-info → shapiq-1.2.2}/PKG-INFO +9 -5
- {shapiq-1.2.1 → shapiq-1.2.2}/README.md +1 -1
- {shapiq-1.2.1 → shapiq-1.2.2}/pyproject.toml +2 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/setup.py +2 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/__init__.py +1 -1
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/_base.py +9 -9
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/marginals/owen.py +2 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/marginals/stratified.py +2 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/montecarlo/_base.py +2 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/montecarlo/shapiq.py +4 -6
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/montecarlo/svarmiq.py +4 -6
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/permutation/sii.py +3 -3
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/permutation/stii.py +2 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/permutation/sv.py +3 -3
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/regression/_base.py +3 -3
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/regression/fsi.py +2 -4
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/regression/kadd_shap.py +2 -4
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/regression/kernelshap.py +2 -4
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/regression/kernelshapiq.py +4 -6
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/sampling.py +12 -15
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/benchmark/configuration.py +2 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/benchmark/load.py +3 -3
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/benchmark/metrics.py +1 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/benchmark/plot.py +8 -8
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/benchmark/precompute.py +8 -8
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/benchmark/run.py +20 -24
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/datasets/_all.py +9 -5
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/explainer/_base.py +1 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/explainer/tabpfn.py +15 -6
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/explainer/tabular.py +5 -6
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/explainer/tree/base.py +12 -12
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/explainer/tree/conversion/lightgbm.py +25 -35
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/explainer/tree/conversion/sklearn.py +2 -4
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/explainer/tree/conversion/xgboost.py +23 -31
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/explainer/tree/explainer.py +4 -4
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/explainer/tree/treeshapiq.py +3 -3
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/explainer/tree/validation.py +6 -4
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/explainer/utils.py +6 -3
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/game_theory/aggregation.py +1 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/game_theory/core.py +1 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/game_theory/exact.py +5 -5
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/game_theory/moebius_converter.py +2 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/base.py +19 -20
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/data_valuation/base.py +2 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/data_valuation/benchmark.py +3 -5
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/dataset_valuation/base.py +10 -10
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/dataset_valuation/benchmark.py +6 -8
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/ensemble_selection/base.py +6 -6
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/ensemble_selection/benchmark.py +6 -8
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/ensemble_selection/benchmark_random_forest.py +3 -5
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/feature_selection/base.py +5 -4
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/feature_selection/benchmark.py +3 -5
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/global_xai/base.py +2 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/global_xai/benchmark_tabular.py +3 -5
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/local_xai/base.py +4 -4
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/local_xai/benchmark_image.py +1 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/local_xai/benchmark_tabular.py +7 -9
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/setup.py +5 -6
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/synthetic/dummy.py +1 -3
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/synthetic/soum.py +5 -7
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/treeshapiq_xai/base.py +1 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/treeshapiq_xai/benchmark.py +8 -10
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/uncertainty/base.py +2 -4
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/uncertainty/benchmark.py +2 -4
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/unsupervised_cluster/base.py +4 -6
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/unsupervised_cluster/benchmark.py +3 -5
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/imputer/base.py +4 -5
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/imputer/baseline_imputer.py +2 -3
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/imputer/conditional_imputer.py +3 -4
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/imputer/marginal_imputer.py +3 -4
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/imputer/tabpfn_imputer.py +4 -4
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/interaction_values.py +18 -20
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/plot/bar.py +5 -7
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/plot/force.py +2 -4
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/plot/network.py +13 -13
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/plot/sentence.py +3 -4
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/plot/si_graph.py +12 -15
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/plot/stacked_bar.py +6 -6
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/plot/upset.py +2 -3
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/plot/utils.py +1 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/plot/watefall.py +3 -5
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/utils/datasets.py +1 -3
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/utils/modules.py +2 -2
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/utils/sets.py +6 -6
- {shapiq-1.2.1 → shapiq-1.2.2/shapiq.egg-info}/PKG-INFO +9 -5
- {shapiq-1.2.1 → shapiq-1.2.2}/LICENSE +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/MANIFEST.in +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/setup.cfg +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/marginals/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/montecarlo/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/permutation/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/approximator/regression/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/benchmark/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/datasets/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/explainer/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/explainer/tree/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/explainer/tree/conversion/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/explainer/tree/conversion/edges.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/explainer/tree/utils.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/game_theory/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/game_theory/indices.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/_setup/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/_setup/_california_torch_setup.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/_setup/_resnet_setup.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/_setup/_vit_setup.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/data_valuation/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/dataset_valuation/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/ensemble_selection/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/feature_selection/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/global_xai/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/local_xai/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/local_xai/benchmark_language.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/synthetic/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/treeshapiq_xai/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/uncertainty/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/unsupervised_cluster/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/unsupervised_data/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/unsupervised_data/base.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/benchmark/unsupervised_data/benchmark.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/games/imputer/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/plot/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/plot/_config.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/utils/__init__.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq/utils/types.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq.egg-info/SOURCES.txt +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq.egg-info/dependency_links.txt +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq.egg-info/requires.txt +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq.egg-info/top_level.txt +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/shapiq.egg-info/zip-safe +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/tests/test_abstract_classes.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/tests/test_base_interaction_values.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/tests/test_configuration.py +0 -0
- {shapiq-1.2.1 → shapiq-1.2.2}/tests/test_integration_import_all.py +0 -0
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
## Changelog
|
|
2
2
|
|
|
3
3
|
### Development
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
### v1.2.2 (2025-03-11)
|
|
6
|
+
- changes python support to 3.10-3.13 [#318](https://github.com/mmschlk/shapiq/pull/318)
|
|
7
|
+
- fixes a bug that prohibited importing shapiq in environments without write access [#326](https://github.com/mmschlk/shapiq/issues/326)
|
|
8
|
+
- adds `ExtraTreeRegressors` to supported models [#309](https://github.com/mmschlk/shapiq/pull/309)
|
|
5
9
|
|
|
6
10
|
### v1.2.1 (2025-02-17)
|
|
7
11
|
- fixes bugs regarding plotting [#315](https://github.com/mmschlk/shapiq/issues/315) and [#316](https://github.com/mmschlk/shapiq/issues/316)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: shapiq
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: Shapley Interactions for Machine Learning
|
|
5
5
|
Home-page: https://github.com/mmschlk/shapiq
|
|
6
6
|
Author: Maximilian Muschalik et al.
|
|
@@ -17,11 +17,11 @@ Classifier: Intended Audience :: Science/Research
|
|
|
17
17
|
Classifier: Topic :: Scientific/Engineering
|
|
18
18
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
19
|
Classifier: Programming Language :: Python
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.11
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
-
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Requires-Python: >=3.10.0
|
|
25
25
|
Description-Content-Type: text/markdown
|
|
26
26
|
License-File: LICENSE
|
|
27
27
|
Requires-Dist: numpy
|
|
@@ -108,7 +108,7 @@ Dynamic: summary
|
|
|
108
108
|
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.
|
|
109
109
|
|
|
110
110
|
## 🛠️ Install
|
|
111
|
-
`shapiq` is intended to work with **Python 3.
|
|
111
|
+
`shapiq` is intended to work with **Python 3.10 and above**. Installation can be done via `pip`:
|
|
112
112
|
|
|
113
113
|
```sh
|
|
114
114
|
pip install shapiq
|
|
@@ -283,7 +283,11 @@ Built with ❤️ by the shapiq team.
|
|
|
283
283
|
## Changelog
|
|
284
284
|
|
|
285
285
|
### Development
|
|
286
|
-
|
|
286
|
+
|
|
287
|
+
### v1.2.2 (2025-03-11)
|
|
288
|
+
- changes python support to 3.10-3.13 [#318](https://github.com/mmschlk/shapiq/pull/318)
|
|
289
|
+
- fixes a bug that prohibited importing shapiq in environments without write access [#326](https://github.com/mmschlk/shapiq/issues/326)
|
|
290
|
+
- adds `ExtraTreeRegressors` to supported models [#309](https://github.com/mmschlk/shapiq/pull/309)
|
|
287
291
|
|
|
288
292
|
### v1.2.1 (2025-02-17)
|
|
289
293
|
- fixes bugs regarding plotting [#315](https://github.com/mmschlk/shapiq/issues/315) and [#316](https://github.com/mmschlk/shapiq/issues/316)
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
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.
|
|
18
18
|
|
|
19
19
|
## 🛠️ Install
|
|
20
|
-
`shapiq` is intended to work with **Python 3.
|
|
20
|
+
`shapiq` is intended to work with **Python 3.10 and above**. Installation can be done via `pip`:
|
|
21
21
|
|
|
22
22
|
```sh
|
|
23
23
|
pip install shapiq
|
|
@@ -7,10 +7,10 @@ testpaths = "tests"
|
|
|
7
7
|
|
|
8
8
|
[tool.black]
|
|
9
9
|
line-length = 100
|
|
10
|
-
target-version = ['
|
|
10
|
+
target-version = ['py310', 'py311', 'py312', 'py313']
|
|
11
11
|
|
|
12
12
|
[tool.ruff]
|
|
13
13
|
lint.select = ["E", "F", "I", "UP"] # https://beta.ruff.rs/docs/rules/
|
|
14
14
|
lint.ignore = ["E501"]
|
|
15
15
|
line-length = 100
|
|
16
|
-
target-version = "
|
|
16
|
+
target-version = "py310"
|
|
@@ -9,7 +9,7 @@ LONG_DESCRIPTION_CONTENT_TYPE = "text/markdown"
|
|
|
9
9
|
URL = "https://github.com/mmschlk/shapiq"
|
|
10
10
|
EMAIL = "maximilian.muschalik@ifi.lmu.de"
|
|
11
11
|
AUTHOR = "Maximilian Muschalik et al."
|
|
12
|
-
REQUIRES_PYTHON = ">=3.
|
|
12
|
+
REQUIRES_PYTHON = ">=3.10.0"
|
|
13
13
|
|
|
14
14
|
work_directory = os.path.abspath(os.path.dirname(__file__))
|
|
15
15
|
|
|
@@ -89,10 +89,10 @@ setuptools.setup(
|
|
|
89
89
|
"Topic :: Scientific/Engineering",
|
|
90
90
|
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
91
91
|
"Programming Language :: Python",
|
|
92
|
-
"Programming Language :: Python :: 3.9",
|
|
93
92
|
"Programming Language :: Python :: 3.10",
|
|
94
93
|
"Programming Language :: Python :: 3.11",
|
|
95
94
|
"Programming Language :: Python :: 3.12",
|
|
95
|
+
"Programming Language :: Python :: 3.13",
|
|
96
96
|
],
|
|
97
97
|
keywords=[
|
|
98
98
|
"python",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import copy
|
|
4
4
|
from abc import ABC, abstractmethod
|
|
5
|
-
from
|
|
5
|
+
from collections.abc import Callable
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
|
|
@@ -66,8 +66,8 @@ class Approximator(ABC):
|
|
|
66
66
|
top_order: bool,
|
|
67
67
|
min_order: int = 0,
|
|
68
68
|
pairing_trick: bool = False,
|
|
69
|
-
sampling_weights:
|
|
70
|
-
random_state:
|
|
69
|
+
sampling_weights: np.ndarray[float] | None = None,
|
|
70
|
+
random_state: int | None = None,
|
|
71
71
|
) -> None:
|
|
72
72
|
# check if index can be approximated
|
|
73
73
|
self.index: str = index
|
|
@@ -92,8 +92,8 @@ class Approximator(ABC):
|
|
|
92
92
|
)
|
|
93
93
|
|
|
94
94
|
# set up random state and random number generators
|
|
95
|
-
self._random_state:
|
|
96
|
-
self._rng:
|
|
95
|
+
self._random_state: int | None = random_state
|
|
96
|
+
self._rng: np.random.Generator | None = np.random.default_rng(seed=self._random_state)
|
|
97
97
|
|
|
98
98
|
# set up a coalition sampler
|
|
99
99
|
self._big_M: int = 100_000_000 # large number for sampling weights
|
|
@@ -178,8 +178,8 @@ class Approximator(ABC):
|
|
|
178
178
|
result,
|
|
179
179
|
baseline_value: float,
|
|
180
180
|
*,
|
|
181
|
-
estimated:
|
|
182
|
-
budget:
|
|
181
|
+
estimated: bool | None = None,
|
|
182
|
+
budget: int | None = None,
|
|
183
183
|
) -> InteractionValues:
|
|
184
184
|
"""Finalizes the result dictionary.
|
|
185
185
|
|
|
@@ -303,8 +303,8 @@ class Approximator(ABC):
|
|
|
303
303
|
@staticmethod
|
|
304
304
|
def aggregate_interaction_values(
|
|
305
305
|
base_interactions: InteractionValues,
|
|
306
|
-
order:
|
|
307
|
-
player_set:
|
|
306
|
+
order: int | None = None,
|
|
307
|
+
player_set: set[int] | None = None,
|
|
308
308
|
) -> InteractionValues:
|
|
309
309
|
"""Aggregates the interaction values.
|
|
310
310
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Okhrati and Lipani (2020). It estimates the Shapley values in its integral representation by
|
|
3
3
|
sampling random marginal contributions."""
|
|
4
4
|
|
|
5
|
-
from
|
|
5
|
+
from collections.abc import Callable
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
|
|
@@ -34,7 +34,7 @@ class OwenSamplingSV(Approximator):
|
|
|
34
34
|
self,
|
|
35
35
|
n: int,
|
|
36
36
|
n_anchor_points: int = 10,
|
|
37
|
-
random_state:
|
|
37
|
+
random_state: int | None = None,
|
|
38
38
|
) -> None:
|
|
39
39
|
super().__init__(n, max_order=1, index="SV", top_order=False, random_state=random_state)
|
|
40
40
|
self.iteration_cost: int = 2
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""This module contains the Stratified Sampling approximation method for the Shapley values."""
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from collections.abc import Callable
|
|
4
4
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
|
|
@@ -31,7 +31,7 @@ class StratifiedSamplingSV(Approximator):
|
|
|
31
31
|
def __init__(
|
|
32
32
|
self,
|
|
33
33
|
n: int,
|
|
34
|
-
random_state:
|
|
34
|
+
random_state: int | None = None,
|
|
35
35
|
) -> None:
|
|
36
36
|
super().__init__(n, max_order=1, index="SV", top_order=False, random_state=random_state)
|
|
37
37
|
self.iteration_cost: int = 2
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""This module contains the Base Regression approximator to compute SII and k-SII of arbitrary max_order."""
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from collections.abc import Callable
|
|
4
4
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
from scipy.special import binom, factorial
|
|
@@ -41,7 +41,7 @@ class MonteCarlo(Approximator):
|
|
|
41
41
|
stratify_coalition_size: bool = True,
|
|
42
42
|
stratify_intersection: bool = True,
|
|
43
43
|
top_order: bool = False,
|
|
44
|
-
random_state:
|
|
44
|
+
random_state: int | None = None,
|
|
45
45
|
pairing_trick: bool = False,
|
|
46
46
|
sampling_weights: np.ndarray = None,
|
|
47
47
|
):
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
The Unbiased KernelSHAP method is a variant of KernelSHAP. However, it was shown that Unbiased
|
|
3
3
|
KernelSHAP is a more specific variant of the ShapIQ interaction method."""
|
|
4
4
|
|
|
5
|
-
from typing import Optional
|
|
6
|
-
|
|
7
5
|
from ._base import MonteCarlo
|
|
8
6
|
|
|
9
7
|
|
|
@@ -53,9 +51,9 @@ class SHAPIQ(MonteCarlo):
|
|
|
53
51
|
max_order: int = 2,
|
|
54
52
|
index: str = "k-SII",
|
|
55
53
|
top_order: bool = False,
|
|
56
|
-
sampling_weights:
|
|
54
|
+
sampling_weights: float | None = None,
|
|
57
55
|
pairing_trick: bool = False,
|
|
58
|
-
random_state:
|
|
56
|
+
random_state: int | None = None,
|
|
59
57
|
):
|
|
60
58
|
super().__init__(
|
|
61
59
|
n,
|
|
@@ -117,8 +115,8 @@ class UnbiasedKernelSHAP(SHAPIQ):
|
|
|
117
115
|
self,
|
|
118
116
|
n: int,
|
|
119
117
|
pairing_trick: bool = False,
|
|
120
|
-
sampling_weights:
|
|
121
|
-
random_state:
|
|
118
|
+
sampling_weights: float | None = None,
|
|
119
|
+
random_state: int | None = None,
|
|
122
120
|
**kwargs,
|
|
123
121
|
):
|
|
124
122
|
super().__init__(
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"""SVARM-IQ approximation."""
|
|
2
2
|
|
|
3
|
-
from typing import Optional
|
|
4
|
-
|
|
5
3
|
from ._base import MonteCarlo
|
|
6
4
|
|
|
7
5
|
|
|
@@ -37,8 +35,8 @@ class SVARMIQ(MonteCarlo):
|
|
|
37
35
|
index: str = "k-SII",
|
|
38
36
|
top_order: bool = False,
|
|
39
37
|
pairing_trick: bool = False,
|
|
40
|
-
sampling_weights:
|
|
41
|
-
random_state:
|
|
38
|
+
sampling_weights: float | None = None,
|
|
39
|
+
random_state: int | None = None,
|
|
42
40
|
):
|
|
43
41
|
super().__init__(
|
|
44
42
|
n,
|
|
@@ -75,9 +73,9 @@ class SVARM(SVARMIQ):
|
|
|
75
73
|
def __init__(
|
|
76
74
|
self,
|
|
77
75
|
n: int,
|
|
78
|
-
random_state:
|
|
76
|
+
random_state: int | None = None,
|
|
79
77
|
pairing_trick: bool = False,
|
|
80
|
-
sampling_weights:
|
|
78
|
+
sampling_weights: float | None = None,
|
|
81
79
|
**kwargs,
|
|
82
80
|
):
|
|
83
81
|
super().__init__(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""This module implements the Permutation Sampling approximator for the SII (and k-SII) index."""
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from collections.abc import Callable
|
|
4
4
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
|
|
@@ -33,7 +33,7 @@ class PermutationSamplingSII(Approximator):
|
|
|
33
33
|
max_order: int = 2,
|
|
34
34
|
index: str = "SII",
|
|
35
35
|
top_order: bool = False,
|
|
36
|
-
random_state:
|
|
36
|
+
random_state: int | None = None,
|
|
37
37
|
) -> None:
|
|
38
38
|
if index not in ["SII", "k-SII"]:
|
|
39
39
|
raise ValueError(f"Invalid index {index}. Must be either 'SII' or 'k-SII'.")
|
|
@@ -68,7 +68,7 @@ class PermutationSamplingSII(Approximator):
|
|
|
68
68
|
self,
|
|
69
69
|
budget: int,
|
|
70
70
|
game: Callable[[np.ndarray], np.ndarray],
|
|
71
|
-
batch_size:
|
|
71
|
+
batch_size: int | None = 5,
|
|
72
72
|
) -> InteractionValues:
|
|
73
73
|
"""Approximates the interaction values.
|
|
74
74
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""This module contains the permutation sampling algorithms to estimate STII scores."""
|
|
2
2
|
|
|
3
3
|
import warnings
|
|
4
|
-
from
|
|
4
|
+
from collections.abc import Callable
|
|
5
5
|
|
|
6
6
|
import numpy as np
|
|
7
7
|
import scipy as sp
|
|
@@ -54,7 +54,7 @@ class PermutationSamplingSTII(Approximator):
|
|
|
54
54
|
)
|
|
55
55
|
"""
|
|
56
56
|
|
|
57
|
-
def __init__(self, n: int, max_order: int, random_state:
|
|
57
|
+
def __init__(self, n: int, max_order: int, random_state: int | None = None) -> None:
|
|
58
58
|
super().__init__(
|
|
59
59
|
n=n, max_order=max_order, index="STII", top_order=False, random_state=random_state
|
|
60
60
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""This module contains the permutation sampling approximation method for the Shapley value (SV)."""
|
|
2
2
|
|
|
3
|
-
from
|
|
3
|
+
from collections.abc import Callable
|
|
4
4
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
|
|
@@ -30,12 +30,12 @@ class PermutationSamplingSV(Approximator):
|
|
|
30
30
|
|
|
31
31
|
"""
|
|
32
32
|
|
|
33
|
-
def __init__(self, n: int, random_state:
|
|
33
|
+
def __init__(self, n: int, random_state: int | None = None, **kwargs) -> None:
|
|
34
34
|
super().__init__(n=n, max_order=1, index="SV", top_order=False, random_state=random_state)
|
|
35
35
|
self.iteration_cost: int = n - 1
|
|
36
36
|
|
|
37
37
|
def approximate(
|
|
38
|
-
self, budget: int, game: Callable[[np.ndarray], np.ndarray], batch_size:
|
|
38
|
+
self, budget: int, game: Callable[[np.ndarray], np.ndarray], batch_size: int | None = 5
|
|
39
39
|
) -> InteractionValues:
|
|
40
40
|
"""Approximates the Shapley values using ApproShapley.
|
|
41
41
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import copy
|
|
4
4
|
import warnings
|
|
5
|
-
from
|
|
5
|
+
from collections.abc import Callable
|
|
6
6
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
from scipy.special import bernoulli, binom
|
|
@@ -42,8 +42,8 @@ class Regression(Approximator):
|
|
|
42
42
|
index: str,
|
|
43
43
|
sii_consistent: bool = True,
|
|
44
44
|
pairing_trick: bool = False,
|
|
45
|
-
sampling_weights:
|
|
46
|
-
random_state:
|
|
45
|
+
sampling_weights: np.ndarray | None = None,
|
|
46
|
+
random_state: int | None = None,
|
|
47
47
|
):
|
|
48
48
|
if index not in AVAILABLE_INDICES_REGRESSION:
|
|
49
49
|
raise ValueError(
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"""Regression with Shapley interaction index (SII) approximation."""
|
|
2
2
|
|
|
3
|
-
from typing import Optional
|
|
4
|
-
|
|
5
3
|
import numpy as np
|
|
6
4
|
|
|
7
5
|
from ._base import Regression
|
|
@@ -40,8 +38,8 @@ class RegressionFSII(Regression):
|
|
|
40
38
|
n: int,
|
|
41
39
|
max_order: int = 2,
|
|
42
40
|
pairing_trick: bool = False,
|
|
43
|
-
sampling_weights:
|
|
44
|
-
random_state:
|
|
41
|
+
sampling_weights: np.ndarray | None = None,
|
|
42
|
+
random_state: int | None = None,
|
|
45
43
|
):
|
|
46
44
|
super().__init__(
|
|
47
45
|
n,
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"""Regression with Shapley interaction index (SII) approximation."""
|
|
2
2
|
|
|
3
|
-
from typing import Optional
|
|
4
|
-
|
|
5
3
|
import numpy as np
|
|
6
4
|
|
|
7
5
|
from ._base import Regression
|
|
@@ -43,8 +41,8 @@ class kADDSHAP(Regression):
|
|
|
43
41
|
n: int,
|
|
44
42
|
max_order: int = 2,
|
|
45
43
|
pairing_trick: bool = False,
|
|
46
|
-
sampling_weights:
|
|
47
|
-
random_state:
|
|
44
|
+
sampling_weights: np.ndarray | None = None,
|
|
45
|
+
random_state: int | None = None,
|
|
48
46
|
):
|
|
49
47
|
super().__init__(
|
|
50
48
|
n,
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"""This module contains the KernelSHAP regression approximator for estimating the SV."""
|
|
2
2
|
|
|
3
|
-
from typing import Optional
|
|
4
|
-
|
|
5
3
|
import numpy as np
|
|
6
4
|
|
|
7
5
|
from ._base import Regression
|
|
@@ -55,8 +53,8 @@ class KernelSHAP(Regression):
|
|
|
55
53
|
self,
|
|
56
54
|
n: int,
|
|
57
55
|
pairing_trick: bool = False,
|
|
58
|
-
sampling_weights:
|
|
59
|
-
random_state:
|
|
56
|
+
sampling_weights: np.ndarray | None = None,
|
|
57
|
+
random_state: int | None = None,
|
|
60
58
|
**kwargs,
|
|
61
59
|
):
|
|
62
60
|
super().__init__(
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"""Regression with Shapley interaction index (SII) approximation."""
|
|
2
2
|
|
|
3
|
-
from typing import Optional
|
|
4
|
-
|
|
5
3
|
import numpy as np
|
|
6
4
|
|
|
7
5
|
from ._base import Regression
|
|
@@ -55,8 +53,8 @@ class KernelSHAPIQ(Regression):
|
|
|
55
53
|
max_order: int = 2,
|
|
56
54
|
index: str = "k-SII",
|
|
57
55
|
pairing_trick: bool = False,
|
|
58
|
-
sampling_weights:
|
|
59
|
-
random_state:
|
|
56
|
+
sampling_weights: np.ndarray | None = None,
|
|
57
|
+
random_state: int | None = None,
|
|
60
58
|
) -> None:
|
|
61
59
|
if index not in AVAILABLE_INDICES_KERNELSHAPIQ:
|
|
62
60
|
raise ValueError(
|
|
@@ -115,8 +113,8 @@ class InconsistentKernelSHAPIQ(Regression):
|
|
|
115
113
|
max_order: int = 2,
|
|
116
114
|
index: str = "k-SII",
|
|
117
115
|
pairing_trick: bool = False,
|
|
118
|
-
sampling_weights:
|
|
119
|
-
random_state:
|
|
116
|
+
sampling_weights: np.ndarray | None = None,
|
|
117
|
+
random_state: int | None = None,
|
|
120
118
|
) -> None:
|
|
121
119
|
if index not in AVAILABLE_INDICES_KERNELSHAPIQ:
|
|
122
120
|
raise ValueError(
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import copy
|
|
4
4
|
import warnings
|
|
5
|
-
from typing import Optional
|
|
6
5
|
|
|
7
6
|
import numpy as np
|
|
8
7
|
from scipy.special import binom
|
|
@@ -76,7 +75,7 @@ class CoalitionSampler:
|
|
|
76
75
|
n_players: int,
|
|
77
76
|
sampling_weights: np.ndarray,
|
|
78
77
|
pairing_trick: bool = False,
|
|
79
|
-
random_state:
|
|
78
|
+
random_state: int | None = None,
|
|
80
79
|
) -> None:
|
|
81
80
|
self.pairing_trick: bool = pairing_trick
|
|
82
81
|
|
|
@@ -115,28 +114,26 @@ class CoalitionSampler:
|
|
|
115
114
|
if weight == 0 and 0 < size < self.n:
|
|
116
115
|
self.n_max_coalitions -= int(binom(self.n, size))
|
|
117
116
|
self._coalitions_to_exclude.extend([size])
|
|
118
|
-
self.adjusted_sampling_weights:
|
|
117
|
+
self.adjusted_sampling_weights: np.ndarray[float] | None = None
|
|
119
118
|
|
|
120
119
|
# set sample size variables (for border trick)
|
|
121
|
-
self._coalitions_to_compute:
|
|
122
|
-
self._coalitions_to_sample:
|
|
120
|
+
self._coalitions_to_compute: list[int] | None = None # coalitions to compute
|
|
121
|
+
self._coalitions_to_sample: list[int] | None = None # coalitions to sample
|
|
123
122
|
|
|
124
123
|
# initialize variables to be computed and stored
|
|
125
|
-
self.sampled_coalitions_dict:
|
|
126
|
-
self.coalitions_per_size:
|
|
124
|
+
self.sampled_coalitions_dict: dict[tuple[int, ...], int] | None = None # coal -> count
|
|
125
|
+
self.coalitions_per_size: np.ndarray[int] | None = None # number of coalitions per size
|
|
127
126
|
|
|
128
127
|
# variables accessible through properties
|
|
129
|
-
self._sampled_coalitions_matrix:
|
|
130
|
-
self._sampled_coalitions_counter:
|
|
131
|
-
self._sampled_coalitions_size_prob:
|
|
128
|
+
self._sampled_coalitions_matrix: np.ndarray[bool] | None = None # coalitions
|
|
129
|
+
self._sampled_coalitions_counter: np.ndarray[int] | None = None # coalitions_counter
|
|
130
|
+
self._sampled_coalitions_size_prob: np.ndarray[float] | None = (
|
|
132
131
|
None # coalitions_size_probability
|
|
133
132
|
)
|
|
134
|
-
self._sampled_coalitions_in_size_prob:
|
|
133
|
+
self._sampled_coalitions_in_size_prob: np.ndarray[float] | None = (
|
|
135
134
|
None # coalitions_in_size_probability
|
|
136
135
|
)
|
|
137
|
-
self._is_coalition_size_sampled:
|
|
138
|
-
None # is_coalition_size_sampled
|
|
139
|
-
)
|
|
136
|
+
self._is_coalition_size_sampled: np.ndarray[bool] | None = None # is_coalition_size_sampled
|
|
140
137
|
|
|
141
138
|
@property
|
|
142
139
|
def n_coalitions(self) -> int:
|
|
@@ -272,7 +269,7 @@ class CoalitionSampler:
|
|
|
272
269
|
return np.sum(self.coalitions_matrix, axis=1)
|
|
273
270
|
|
|
274
271
|
@property
|
|
275
|
-
def empty_coalition_index(self) ->
|
|
272
|
+
def empty_coalition_index(self) -> int | None:
|
|
276
273
|
"""Returns the index of the empty coalition.
|
|
277
274
|
|
|
278
275
|
Returns:
|
|
@@ -34,7 +34,7 @@ information:
|
|
|
34
34
|
"""
|
|
35
35
|
|
|
36
36
|
import os
|
|
37
|
-
from typing import Any
|
|
37
|
+
from typing import Any
|
|
38
38
|
|
|
39
39
|
from shapiq.approximator import (
|
|
40
40
|
FSII_APPROXIMATORS,
|
|
@@ -757,7 +757,7 @@ APPROXIMATION_BENCHMARK_PARAMS.update(
|
|
|
757
757
|
|
|
758
758
|
|
|
759
759
|
def get_game_file_name_from_config(
|
|
760
|
-
configuration: dict[str, Any], iteration:
|
|
760
|
+
configuration: dict[str, Any], iteration: int | None = None
|
|
761
761
|
) -> str:
|
|
762
762
|
"""Get the file name for the game data with the given configuration and iteration.
|
|
763
763
|
|
|
@@ -4,7 +4,7 @@ from the precomputed data (GitHub repository)."""
|
|
|
4
4
|
import os
|
|
5
5
|
import time
|
|
6
6
|
from collections.abc import Generator
|
|
7
|
-
from typing import Any
|
|
7
|
+
from typing import Any
|
|
8
8
|
|
|
9
9
|
import requests
|
|
10
10
|
|
|
@@ -26,9 +26,9 @@ __all__ = [
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
def load_games_from_configuration(
|
|
29
|
-
game_class:
|
|
29
|
+
game_class: Game.__class__ | str,
|
|
30
30
|
config_id: int,
|
|
31
|
-
n_games:
|
|
31
|
+
n_games: int | None = None,
|
|
32
32
|
n_player_id: int = 0,
|
|
33
33
|
check_pre_computed: bool = True,
|
|
34
34
|
only_pre_computed: bool = True,
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import copy
|
|
4
4
|
import warnings
|
|
5
|
-
from typing import Optional
|
|
6
5
|
|
|
7
6
|
import numpy as np
|
|
8
7
|
from scipy.stats import kendalltau
|
|
@@ -145,7 +144,7 @@ def compute_precision_at_k(
|
|
|
145
144
|
def get_all_metrics(
|
|
146
145
|
ground_truth: InteractionValues,
|
|
147
146
|
estimated: InteractionValues,
|
|
148
|
-
order_indicator:
|
|
147
|
+
order_indicator: str | None = None,
|
|
149
148
|
) -> dict:
|
|
150
149
|
"""Get all metrics for the interaction values.
|
|
151
150
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""This module contains the plotting utilities for the benchmark results."""
|
|
2
2
|
|
|
3
3
|
from collections import defaultdict
|
|
4
|
-
from
|
|
4
|
+
from collections.abc import Callable
|
|
5
5
|
|
|
6
6
|
import numpy as np
|
|
7
7
|
import pandas as pd
|
|
@@ -162,14 +162,14 @@ def agg_percentile(q: float) -> Callable[[np.ndarray], float]:
|
|
|
162
162
|
|
|
163
163
|
|
|
164
164
|
def plot_approximation_quality(
|
|
165
|
-
data:
|
|
165
|
+
data: pd.DataFrame | None = None,
|
|
166
166
|
*,
|
|
167
|
-
data_path:
|
|
167
|
+
data_path: str | None = None,
|
|
168
168
|
metric: str = "MSE",
|
|
169
|
-
orders:
|
|
170
|
-
approximators:
|
|
169
|
+
orders: list[int | str] | None = None,
|
|
170
|
+
approximators: list[str] | None = None,
|
|
171
171
|
aggregation: str = "mean",
|
|
172
|
-
confidence_metric:
|
|
172
|
+
confidence_metric: str | None = "sem",
|
|
173
173
|
log_scale_y: bool = False,
|
|
174
174
|
log_scale_min: float = LOG_SCALE_MIN,
|
|
175
175
|
log_scale_max: float = LOG_SCALE_MAX,
|
|
@@ -421,8 +421,8 @@ def get_metric_data(results_df: pd.DataFrame, metric: str = "MSE") -> pd.DataFra
|
|
|
421
421
|
|
|
422
422
|
def add_legend(
|
|
423
423
|
axis: plt.Axes,
|
|
424
|
-
approximators: list[
|
|
425
|
-
orders:
|
|
424
|
+
approximators: list[str | Approximator],
|
|
425
|
+
orders: list[int | str] | None = None,
|
|
426
426
|
legend_subtitle: bool = True,
|
|
427
427
|
loc: str = "best",
|
|
428
428
|
) -> None:
|