Skip to content

Commit

Permalink
Merge pull request #21 from Oxid15/develop
Browse files Browse the repository at this point in the history
v0.3.0
  • Loading branch information
Oxid15 authored May 7, 2023
2 parents dcf2cea + eb97561 commit 4a55a77
Show file tree
Hide file tree
Showing 84 changed files with 366 additions and 239 deletions.
50 changes: 0 additions & 50 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,53 +5,3 @@ on:
branches: [ "master" ]
pull_request:
branches: [ "master", "develop" ]

jobs:
build:

runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10"]

steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r explainers_requirements.txt
pip install -r https://raw.githubusercontent.com/oxid15/cascade/main/utils_requirements.txt
pip install .
- name: Feature importance
run: |
cd xaib/evaluation/feature_importance/
./evaluate.sh
zip -r repo .
- name: Example selection
run: |
pwd
ls
cd xaib/evaluation/example_selection
./evaluate.sh
zip -r repo .
- name: Archive feature importance results
uses: actions/upload-artifact@v3
with:
name: Feature importance results
path: xaib/evaluation/feature_importance/repo.zip

- name: Archive example selection results
uses: actions/upload-artifact@v3
with:
name: Example selection results
path: xaib/evaluation/example_selection/repo.zip
2 changes: 1 addition & 1 deletion docs/_modules/index.html

Large diffs are not rendered by default.

26 changes: 18 additions & 8 deletions docs/_modules/xaib/base/base.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions docs/_modules/xaib/datasets/synthetic_dataset.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/_modules/xaib/utils/utils.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/cases.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/contribute.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/contribute/add_dataset.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/contribute/add_explainer.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/contribute/add_metric.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/contribute/add_model.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/datasets.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/genindex.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/index.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/installation.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/metrics.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/models.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/modules.html

Large diffs are not rendered by default.

Binary file modified docs/objects.inv
Binary file not shown.
2 changes: 1 addition & 1 deletion docs/results.html

Large diffs are not rendered by default.

38 changes: 14 additions & 24 deletions docs/results/example_selection.html

Large diffs are not rendered by default.

46 changes: 18 additions & 28 deletions docs/results/feature_importance.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/search.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/searchindex.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/use_cases.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/use_cases/evaluate_method.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/use_cases/try_method.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/xaib/base.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/xaib/cases.example_selection.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/xaib/cases.feature_importance.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/xaib/cases.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/xaib/datasets.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/xaib/explainers.example_selection.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/xaib/explainers.feature_importance.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/xaib/explainers.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/xaib/metrics.example_selection.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/xaib/metrics.feature_importance.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/xaib/metrics.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/xaib/models.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/xaib/utils.html

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cascade-ml<0.11.0
scikit-learn
cascade-ml>=0.11.0
plotly
kaleido
kaleido
numpy==1.23.5
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="xai-benchmark",
version="0.2.0",
version="0.3.0",
author="Ilia Moiseev",
author_email="ilia.moiseev.5@yandex.ru",
license="MIT",
Expand All @@ -20,5 +20,5 @@
package_dir={"xaib": "./xaib"},
packages=setuptools.find_packages(),
python_requires=">=3.8",
install_requires=["cascade-ml>=0.7.2", "scikit-learn", "plotly", "kaleido"],
install_requires=["cascade-ml", "scikit-learn", "plotly", "kaleido"],
)
2 changes: 1 addition & 1 deletion xaib/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "0.2.0"
__version__ = "0.3.0"
__author__ = "Ilia Moiseev"
__author_email__ = "ilia.moiseev.5@yandex.ru"

Expand Down
20 changes: 15 additions & 5 deletions xaib/base/base.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .. import __version__ as version
from typing import Union, List, Dict, Any, Callable
from cascade import data as cdd
from cascade import models as cdm
Expand Down Expand Up @@ -72,7 +73,7 @@ def evaluate(
expl: Explainer,
batch_size: int = 1,
expl_kwargs: Union[Dict[Any, Any], None] = None,
**kwargs: Any
**kwargs: Any,
) -> None:
if expl_kwargs is None:
expl_kwargs = {}
Expand All @@ -82,6 +83,8 @@ def evaluate(
self.params["direction"] = self.direction
self.params["dataset"] = self._ds.name
self.params["model"] = self._model.name
self.params["model_params"] = self._model.params
self.params["model_metrics"] = self._model.metrics
self.metrics[self.name] = value


Expand All @@ -95,6 +98,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self.name = None
self._metric_objs = dict()
self._meta_prefix.update({"xaib_version": version})

def add_metric(self, name: str, metric: Metric) -> None:
self._metric_objs[name] = metric
Expand All @@ -104,7 +108,7 @@ def evaluate(
name: str,
expl: Explainer,
metrics_kwargs: Union[Dict[str, Dict[Any, Any]], None] = None,
**kwargs: Any
**kwargs: Any,
) -> None:
if metrics_kwargs is None:
metrics_kwargs = {name: {} for _ in self._metric_objs}
Expand Down Expand Up @@ -146,9 +150,12 @@ def _get(self, name: str) -> Any:
return constructor(**kwargs)

def get(self, name: str) -> Union[Dict[str, Any], Any]:
if name == "all":
return self._get_all()
return self._get(name)
try:
if name == "all":
return self._get_all()
return self._get(name)
except Exception as e:
raise RuntimeError(f"Failed to create object {name} in {self}") from e

def add(
self,
Expand All @@ -158,3 +165,6 @@ def add(
) -> None:
self._constructors[name] = constructor
self._constructors_kwargs[name] = constr_kwargs

def get_names(self):
return list(self._constructors.keys())
19 changes: 18 additions & 1 deletion xaib/datasets/sk_dataset.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
from typing import Any, Dict
from cascade.base import PipeMeta

import numpy as np
from cascade import data as cdd
from sklearn.datasets import load_iris, load_digits
from sklearn.datasets import (
load_iris,
load_digits,
load_wine,
load_breast_cancer,
)
from sklearn.model_selection import train_test_split


class SkDataset(cdd.SizedDataset):
# TODO: this is classification dataset - should be renamed
def __init__(self, name, split, frac=0.8, *args, **kwargs) -> None:
super().__init__(**kwargs)

self.name = name
self.split = split

constructors = {
"iris": load_iris(return_X_y=True),
"wine": load_wine(return_X_y=True),
"digits": load_digits(return_X_y=True),
"breast_cancer": load_breast_cancer(return_X_y=True),
}

if name not in constructors:
Expand All @@ -37,3 +47,10 @@ def __len__(self) -> int:

def __getitem__(self, index: int) -> Dict[str, Any]:
return {"item": self.x[index], "label": self.y[index]}

def get_meta(self):
meta = super().get_meta()
meta[0]["dataset_name"] = self.name
meta[0]["split"] = self.split
meta[0]["labels"] = self.labels
return meta
5 changes: 5 additions & 0 deletions xaib/datasets/synthetic_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,8 @@ def __len__(self) -> int:

def __getitem__(self, index: int) -> Dict[str, Any]:
return {"item": self.x[index], "label": self.y[index]}

def get_meta(self):
meta = super().get_meta()
meta[0]["dataset_name"] = self.name
return meta
2 changes: 1 addition & 1 deletion xaib/docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"html_minify": True,
"css_minify": True,
"nav_title": "XAIB - Open and extensible benchmark for XAI methods",
"logo_icon": "<ruby>細部<rt>さいぶ</rt></ruby>", # "&#x8cea", #'&#x7d30&#x90e8'
"logo_icon": "細部", # "&#x8cea", #'&#x7d30&#x90e8'
}

html_sidebars = {
Expand Down
10 changes: 8 additions & 2 deletions xaib/evaluation/dataset_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def __init__(self) -> None:
super().__init__()
self._constructors["synthetic"] = lambda: generate_dataset(
SyntheticDataset,
n_samples=100,
n_samples=1000,
n_features=14,
random_state=0,
n_informative=14,
Expand All @@ -28,7 +28,7 @@ def __init__(self) -> None:
self._constructors["synthetic_noisy"] = lambda: generate_dataset(
SyntheticDataset,
name="synthetic_noisy",
n_samples=100,
n_samples=1000,
n_features=14,
random_state=0,
n_informative=7,
Expand All @@ -40,6 +40,12 @@ def __init__(self) -> None:
self._constructors["iris"] = lambda: generate_dataset(
SkDataset, "iris", frac=0.8
)
self._constructors["wine"] = lambda: generate_dataset(
SkDataset, "wine", frac=0.8
)
self._constructors["digits"] = lambda: generate_dataset(
SkDataset, "digits", frac=0.8
)
self._constructors["breast_cancer"] = lambda: generate_dataset(
SkDataset, "breast_cancer", frac=0.8
)
2 changes: 1 addition & 1 deletion xaib/evaluation/example_selection/case_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def correctness(test_ds, model):


class CaseFactory(Factory):
def __init__(self, test_ds: Dataset, model: Model) -> None:
def __init__(self, test_ds: Dataset = None, model: Model = None) -> None:
super().__init__()
self._constructors["continuity"] = lambda: continuity(test_ds, model)
self._constructors["contrastivity"] = lambda: ContrastivityCase(test_ds, model)
Expand Down
51 changes: 28 additions & 23 deletions xaib/evaluation/example_selection/example_selection.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import os
import sys

from cascade import data as cdd
from cascade.models import ModelRepo
from cascade.utils.sk_model import SkModel
from xaib.evaluation import DatasetFactory, ModelFactory
from xaib.evaluation.example_selection import ExperimentFactory, ExplainerFactory
from xaib.evaluation.example_selection import (
ExperimentFactory,
ExplainerFactory,
CaseFactory,
)

SCRIPT_DIR = os.path.dirname(__file__)
# xaib/results/...
Expand All @@ -14,35 +17,37 @@
)

sys.path.append(os.path.abspath(os.path.dirname(SCRIPT_DIR)))
from utils import WrapperModel, visualize_results


class SkWrapper(SkModel):
def __init__(self, *args, blocks=None, name=None, **kwargs) -> None:
super().__init__(*args, blocks=blocks, **kwargs)
self.name = name
from utils import Setup, visualize_results


BS = 5
BS = 100

# Overwrite previous run
ModelRepo(REPO_PATH, overwrite=True)

for dataset in ["synthetic_noisy", "synthetic"]:
for model in ["knn"]:
train_ds, test_ds = DatasetFactory().get(dataset)
print(train_ds.get_meta())
factories = (DatasetFactory(), ModelFactory(), ExplainerFactory(), CaseFactory())
setups = [Setup(*factories, models=["knn"])]

for setup in setups:
for dataset in setup.datasets:
for model in setup.models:
train_ds, test_ds = DatasetFactory().get(dataset)
print(train_ds.get_meta())

model = ModelFactory(train_ds, test_ds).get(model)
print(model.get_meta())

model = ModelFactory(train_ds, test_ds).get(model)
print(model.get_meta())
explainers = {
explainer: ExplainerFactory(train_ds, model).get(explainer)
for explainer in setup.explainers
}

explainers = ExplainerFactory(train_ds, model).get("all")
experiment_factory = ExperimentFactory(
REPO_PATH, explainers, test_ds, model, BS
)
experiment_factory = ExperimentFactory(
REPO_PATH, explainers, test_ds, model, BS
)

experiments = experiment_factory.get("all")
for name in experiments:
experiments[name]()
for case in setup.cases:
experiment = experiment_factory.get(case)
experiment()

visualize_results(REPO_PATH, REPO_PATH)
4 changes: 3 additions & 1 deletion xaib/evaluation/example_selection/experiment_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@


class ExperimentFactory(Factory):
def __init__(self, repo_path, explainers, test_ds, model, batch_size) -> None:
def __init__(
self, repo_path=None, explainers=None, test_ds=None, model=None, batch_size=None
) -> None:
super().__init__()

case_factory = CaseFactory(test_ds, model)
Expand Down
2 changes: 1 addition & 1 deletion xaib/evaluation/example_selection/explainer_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


class ExplainerFactory(Factory):
def __init__(self, train_ds: Dataset, model: Model) -> None:
def __init__(self, train_ds: Dataset = None, model: Model = None) -> None:
super().__init__()
self._constructors["const"] = lambda: ConstantExplainer(
train_ds, train_ds[0]["item"]
Expand Down
4 changes: 3 additions & 1 deletion xaib/evaluation/feature_importance/case_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ def continuity(test_ds, model):


class CaseFactory(Factory):
def __init__(self, test_ds: Dataset, model: Model, labels) -> None:
def __init__(
self, test_ds: Dataset = None, model: Model = None, labels=None
) -> None:
super().__init__()
self._constructors["correctness"] = lambda: correctness(
test_ds, model, labels=labels
Expand Down
8 changes: 7 additions & 1 deletion xaib/evaluation/feature_importance/experiment_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@

class ExperimentFactory(Factory):
def __init__(
self, repo_path, explainers, test_ds, model, labels, batch_size
self,
repo_path=None,
explainers=None,
test_ds=None,
model=None,
labels=None,
batch_size=None,
) -> None:
super().__init__()

Expand Down
4 changes: 3 additions & 1 deletion xaib/evaluation/feature_importance/explainer_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@


class ExplainerFactory(Factory):
def __init__(self, train_ds: Dataset, model: Model, labels=[0, 1]) -> None:
def __init__(
self, train_ds: Dataset = None, model: Model = None, labels=None
) -> None:
super().__init__()
self._constructors["const"] = lambda: ConstantExplainer(constant=1)
self._constructors["random"] = lambda: RandomExplainer(shift=-15, magnitude=10)
Expand Down
Loading

0 comments on commit 4a55a77

Please sign in to comment.