Skip to content

Commit

Permalink
ruff check fix
Browse files Browse the repository at this point in the history
  • Loading branch information
hbaniecki committed Mar 29, 2024
1 parent 988d982 commit 5188884
Show file tree
Hide file tree
Showing 46 changed files with 123 additions and 86 deletions.
41 changes: 23 additions & 18 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,24 @@
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

from sphinx.builders.html import StandaloneHTMLBuilder
import os
import sys

from sphinx.builders.html import StandaloneHTMLBuilder

sys.path.insert(0, os.path.abspath("../.."))
sys.path.insert(0, os.path.abspath("../../shapiq"))

import shapiq

# -- Read the Docs ---------------------------------------------------------------------------------
master_doc = 'index'
master_doc = "index"

# -- Project information ---------------------------------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = 'shapiq'
copyright = '2023, the shapiq developers'
author = 'Maximilian Muschalik and Fabian Fumagalli'
project = "shapiq"
copyright = "2023, the shapiq developers"
author = "Maximilian Muschalik and Fabian Fumagalli"
release = shapiq.__version__
version = shapiq.__version__

Expand All @@ -34,15 +36,15 @@
"sphinx.ext.autodoc",
"sphinx.ext.doctest",
"sphinx.ext.autosummary",
'sphinx_copybutton',
"sphinx_copybutton",
"sphinx.ext.viewcode",
"sphinx.ext.autosectionlabel",
"sphinx_autodoc_typehints",
"sphinx_toolbox.more_autodoc.autoprotocol",
]

templates_path = ['_templates']
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
templates_path = ["_templates"]
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]

source_suffix = {
".rst": "restructuredtext",
Expand All @@ -59,9 +61,9 @@

# -- Options for HTML output -----------------------------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
html_theme = 'furo'
html_theme = "furo"
html_static_path = ["_static"]
html_favicon = '_static/shapiq.ico'
html_favicon = "_static/shapiq.ico"
pygments_dark_style = "monokai"
html_theme_options = {
"sidebar_hide_name": True,
Expand All @@ -83,19 +85,22 @@
# -- Autodoc ---------------------------------------------------------------------------------------
autosummary_generate = True
autodoc_default_options = {
'show-inheritance': True,
'members': True,
'member-order': 'groupwise',
'special-members': '__call__',
'undoc-members': True,
'exclude-members': '__weakref__'
"show-inheritance": True,
"members": True,
"member-order": "groupwise",
"special-members": "__call__",
"undoc-members": True,
"exclude-members": "__weakref__",
}
autoclass_content = 'class'
autoclass_content = "class"
autodoc_inherit_docstrings = False

# -- Images ----------------------------------------------------------------------------------------
StandaloneHTMLBuilder.supported_image_types = [
"image/svg+xml", "image/gif", "image/png", "image/jpeg"
"image/svg+xml",
"image/gif",
"image/png",
"image/jpeg",
]
# -- Copy Paste Button -----------------------------------------------------------------------------
# Ignore >>> when copying code
Expand Down
17 changes: 10 additions & 7 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import setuptools
import io
import os
import codecs
import os

import setuptools

NAME = "shapiq"
DESCRIPTION = "SHAPley Interaction Quantification (SHAP-IQ) for Explainable AI"
Expand All @@ -13,18 +13,21 @@

work_directory = os.path.abspath(os.path.dirname(__file__))


# https://packaging.python.org/guides/single-sourcing-package-version/
def read(rel_path):
with codecs.open(os.path.join(work_directory, rel_path), 'r') as fp:
with codecs.open(os.path.join(work_directory, rel_path), "r") as fp:
return fp.read()



def get_version(rel_path):
for line in read(rel_path).splitlines():
if line.startswith('__version__'):
if line.startswith("__version__"):
delimiter = '"' if '"' in line else "'"
return line.split(delimiter)[1]

with io.open(os.path.join(work_directory, "README.md"), encoding="utf-8") as f:

with open(os.path.join(work_directory, "README.md"), encoding="utf-8") as f:
long_description = "\n" + f.read()

base_packages = ["numpy", "scipy", "pandas", "tqdm"]
Expand Down
2 changes: 1 addition & 1 deletion shapiq/approximator/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

import numpy as np

from shapiq.approximator._config import AVAILABLE_INDICES
from shapiq.interaction_values import InteractionValues
from shapiq.utils.sets import generate_interaction_lookup
from shapiq.approximator._config import AVAILABLE_INDICES

__all__ = [
"Approximator",
Expand Down
4 changes: 3 additions & 1 deletion shapiq/approximator/permutation/sti.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ def approximate(
counts: np.ndarray[int] = self._init_result(dtype=int)

# compute all lower order interactions if budget allows it
lower_order_cost = sum(int(sp.special.binom(self.n, s)) for s in range(self.min_order, self.max_order))
lower_order_cost = sum(
int(sp.special.binom(self.n, s)) for s in range(self.min_order, self.max_order)
)
if self.max_order > 1 and budget >= lower_order_cost:
budget -= lower_order_cost
used_budget += lower_order_cost
Expand Down
3 changes: 1 addition & 2 deletions shapiq/approximator/regression/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""This module contains the regression-based approximators to estimate Shapley interaction values.
"""
"""This module contains the regression-based approximators to estimate Shapley interaction values."""

from .fsi import RegressionFSI
from .sii import RegressionSII
Expand Down
12 changes: 9 additions & 3 deletions shapiq/approximator/regression/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,9 @@ def _get_fsi_subset_representation(
of players.
"""
n_subsets = all_subsets.shape[0]
num_players = sum(int(sp.special.binom(self.n, order)) for order in range(1, self.max_order + 1))
num_players = sum(
int(sp.special.binom(self.n, order)) for order in range(1, self.max_order + 1)
)
regression_subsets = np.zeros(shape=(n_subsets, num_players), dtype=bool)
for interaction_index, interaction in enumerate(
powerset(self.N, min_size=1, max_size=self.max_order)
Expand All @@ -193,7 +195,9 @@ def _get_sii_subset_representation(
of players.
"""
n_subsets = all_subsets.shape[0]
num_players = sum(int(sp.special.binom(self.n, order)) for order in range(1, self.max_order + 1))
num_players = sum(
int(sp.special.binom(self.n, order)) for order in range(1, self.max_order + 1)
)
regression_subsets = np.zeros(shape=(n_subsets, num_players), dtype=float)
for interaction_index, interaction in enumerate(
powerset(self.N, min_size=1, max_size=self.max_order)
Expand All @@ -216,7 +220,9 @@ def _get_bernoulli_weight(self, intersection_size: int, r_prime: int) -> float:
"""
weight = 0
for size in range(1, intersection_size + 1):
weight += sp.special.binom(intersection_size, size) * self._bernoulli_numbers[r_prime - size]
weight += (
sp.special.binom(intersection_size, size) * self._bernoulli_numbers[r_prime - size]
)
return weight

def _get_bernoulli_weights(
Expand Down
6 changes: 4 additions & 2 deletions shapiq/approximator/sampling.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ShapleySamplingMixin(ABC):
"""

def _init_ksh_sampling_weights(
self: Union[Approximator, "ShapleySamplingMixin"]
self: Union[Approximator, "ShapleySamplingMixin"],
) -> np.ndarray[float]:
"""Initializes the weights for sampling subsets.
Expand Down Expand Up @@ -54,7 +54,9 @@ def _get_ksh_subset_weights(
ksh_weights = self._init_ksh_sampling_weights() # indexed by subset size
subset_sizes = np.sum(subsets, axis=1)
weights = ksh_weights[subset_sizes] # set the weights for each subset size
weights /= sp.special.binom(self.n, subset_sizes) # divide by the number of subsets of the same size
weights /= sp.special.binom(
self.n, subset_sizes
) # divide by the number of subsets of the same size

# set the weights for the empty and full sets to big M
weights[np.logical_not(subsets).all(axis=1)] = float(1_000_000)
Expand Down
1 change: 0 additions & 1 deletion shapiq/explainer/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""This module contains the explainer for the shapiq package."""


from .tabular import TabularExplainer
from .tree import TreeExplainer

Expand Down
2 changes: 1 addition & 1 deletion shapiq/explainer/tabular.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
ShapIQ,
)
from shapiq.approximator._base import Approximator
from shapiq.interaction_values import InteractionValues
from shapiq.explainer._base import Explainer
from shapiq.explainer.imputer import MarginalImputer
from shapiq.interaction_values import InteractionValues

__all__ = ["TabularExplainer"]

Expand Down
1 change: 1 addition & 0 deletions shapiq/explainer/tree/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""This module contains the tree explainer implementation."""

from .base import TreeModel
from .explainer import TreeExplainer
from .treeshapiq import TreeSHAPIQ
Expand Down
1 change: 1 addition & 0 deletions shapiq/explainer/tree/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""This module contains the base class for tree model conversion."""

from dataclasses import dataclass
from typing import Any, Optional

Expand Down
1 change: 1 addition & 0 deletions shapiq/explainer/tree/conversion/edges.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""This module contains the conversion functions to parse a tree model into the edge representation.
The edge representation is used by the TreeSHAP-IQ algorithm to compute the interaction values of a
tree-based model."""

import numpy as np
from scipy.special import binom

Expand Down
2 changes: 1 addition & 1 deletion shapiq/explainer/tree/conversion/sklearn.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""This module contains functions for converting scikit-learn decision trees to the format used by
shapiq."""
shapiq."""

from typing import Optional

Expand Down
1 change: 1 addition & 0 deletions shapiq/explainer/tree/explainer.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""This module contains the TreeExplainer class making use of the TreeSHAPIQ algorithm for
computing any-order Shapley Interactions for tree ensembles."""

import copy
from typing import Any, Optional, Union

Expand Down
5 changes: 4 additions & 1 deletion shapiq/explainer/tree/treeshapiq.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""This module contains the tree explainer implementation."""

import copy
from math import factorial
from typing import Any, Optional, Union
Expand Down Expand Up @@ -489,7 +490,9 @@ def _precompute_subsets_with_feature(

# prepare the interaction updates and positions
for feature_i in range(n_features):
positions = np.zeros(int(sp.special.binom(n_features - 1, interaction_order - 1)), dtype=int)
positions = np.zeros(
int(sp.special.binom(n_features - 1, interaction_order - 1)), dtype=int
)
interaction_update_positions[feature_i] = positions.copy()
interaction_updates[feature_i] = []

Expand Down
1 change: 1 addition & 0 deletions shapiq/explainer/tree/validation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""This module contains conversion functions for the tree explainer implementation."""

import warnings
from typing import Any, Optional, Union

Expand Down
1 change: 0 additions & 1 deletion shapiq/games/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""This module contains sample game functions for the shapiq package."""


from .dummy import DummyGame

__all__ = [
Expand Down
2 changes: 2 additions & 0 deletions shapiq/interaction_values.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
"""This module contains the InteractionValues Dataclass, which is used to store the interaction
scores."""

import copy
import warnings
from dataclasses import dataclass
from typing import Optional, Union

import numpy as np

from shapiq.utils import generate_interaction_lookup, powerset

AVAILABLE_INDICES = {"k-SII", "SII", "STI", "FSI", "SV", "BZF"}
Expand Down
2 changes: 1 addition & 1 deletion shapiq/plot/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import math
from typing import Any, Optional, Union

import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
import numpy as np
from PIL import Image

from shapiq.interaction_values import InteractionValues
Expand Down
2 changes: 1 addition & 1 deletion shapiq/plot/stacked_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from copy import deepcopy
from typing import Optional, Union

import numpy as np
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Patch

from ._config import COLORS_N_SII
Expand Down
1 change: 1 addition & 0 deletions shapiq/utils/types.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""This module contains all custom types used in the shapiq package."""

from typing import TypeVar

# Model type for all machine learning models
Expand Down
7 changes: 4 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
If it becomes too large, it can be split into multiple files like here:
https://gist.github.com/peterhurford/09f7dcda0ab04b95c026c60fa49c2a68
"""

import numpy as np
import pytest
from sklearn.datasets import make_regression, make_classification
from sklearn.tree import DecisionTreeRegressor, DecisionTreeClassifier
from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from sklearn.datasets import make_classification, make_regression
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor

from shapiq.explainer.tree import TreeModel

Expand Down
5 changes: 3 additions & 2 deletions tests/test_abstract_classes.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
"""This test module contains all tests regarding the base approximator class."""

import numpy as np
import pytest

from shapiq.games.base import Game
from shapiq.approximator._base import Approximator
from shapiq.explainer.imputer._base import Imputer
from shapiq.explainer._base import Explainer
from shapiq.explainer.imputer._base import Imputer
from shapiq.games.base import Game


def concreter(abclass):
Expand Down
1 change: 1 addition & 0 deletions tests/test_base_interaction_values.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""This test module contains all tests regarding the InteractionValues dataclass."""

from copy import copy, deepcopy

import numpy as np
Expand Down
8 changes: 2 additions & 6 deletions tests/test_integration_import_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,11 @@
import importlib
import pkgutil
import sys

import pytest

import shapiq
from shapiq import approximator
from shapiq import explainer
from shapiq import games
from shapiq import utils
from shapiq import plot
from shapiq import datasets
from shapiq import approximator, datasets, explainer, games, plot, utils


@pytest.mark.parametrize(
Expand Down
Loading

0 comments on commit 5188884

Please sign in to comment.