diff --git a/.github/workflows/python-pytest.yml b/.github/workflows/python-pytest.yml index 463ffc9..c7f0e89 100644 --- a/.github/workflows/python-pytest.yml +++ b/.github/workflows/python-pytest.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10"] + python-version: ["3.8", "3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v2 diff --git a/CITATIONS.bib b/CITATIONS.bib index d720f71..c88200d 100644 --- a/CITATIONS.bib +++ b/CITATIONS.bib @@ -1,13 +1,27 @@ @article{bjorklund2022slisemap, - title = {{SLISEMAP}: Supervised dimensionality reduction through local explanations}, + title = {SLISEMAP: supervised dimensionality reduction through local explanations}, shorttitle = {{SLISEMAP}}, - author = {Bj{\"o}rklund, Anton and M{\"a}kel{\"a}, Jarmo and Puolam{\"a}ki, Kai}, - year = {2022}, - journal = {arXiv:2201.04455 [cs]}, - eprint = {2201.04455}, - eprinttype = {arxiv}, + issn = {1573-0565}, + url = {https://doi.org/10.1007/s10994-022-06261-1}, + doi = {10.1007/s10994-022-06261-1}, + number = {arXiv:2201.04455}, + journal = {Machine Learning}, + author = {Bj{\"o}rklund, Anton and M{\"a}kel{\"a}, Jarmo and Puolam{\"a}ki, Kai}, + year = {2022}, + month = {Nov}, + language = {en} +} + +@article{bjorklund2022slisemaparxiv, + title = {{SLISEMAP}: Supervised dimensionality reduction through local explanations}, + shorttitle = {{SLISEMAP}}, + author = {Bj{\"o}rklund, Anton and M{\"a}kel{\"a}, Jarmo and Puolam{\"a}ki, Kai}, + year = {2022}, + journal = {arXiv:2201.04455 [cs]}, + eprint = {2201.04455}, + eprinttype = {arxiv}, primaryclass = {cs}, - url = {http://arxiv.org/abs/2201.04455}, - doi = {10.48550/ARXIV.2201.04455}, - publisher = {arXiv} + url = {http://arxiv.org/abs/2201.04455}, + doi = {10.48550/ARXIV.2201.04455}, + publisher = {arXiv} } diff --git a/README.md b/README.md index a64d53e..1c7780c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![PyPI](https://img.shields.io/pypi/v/slise)](https://pypi.org/project/slisemap/) +[![PyPI](https://img.shields.io/pypi/v/slisemap)](https://pypi.org/project/slisemap/) [![Documentation](https://github.com/edahelsinki/slisemap/actions/workflows/python-docs.yml/badge.svg)](https://edahelsinki.github.io/slisemap/slisemap/) [![Tests](https://github.com/edahelsinki/slisemap/actions/workflows/python-pytest.yml/badge.svg)](https://github.com/edahelsinki/slisemap/actions/workflows/python-pytest.yml) [![Licence: MIT](https://img.shields.io/github/license/edahelsinki/slisemap)](https://github.com/edahelsinki/slisemap/blob/master/LICENSE) @@ -8,14 +8,14 @@ SLISEMAP is a supervised dimensionality reduction method, that takes data, in the form of vectors, and predictions from a *black box* regression or classification model as input. SLISEMAP then simultaneously finds local explanations for all data items and builds a (typically) two-dimensional global visualisation of the black box model such that data items with similar local explanations are projected nearby. The explanations consist of *white box* models that locally approximate the *black box* model. -SLISEMAP is implemented in *Python* using *PyTorch* for efficient optimisation, and optional GPU-acceleration. For more information see the [full paper](https://arxiv.org/abs/2201.04455), the [demo paper](https://github.com/edahelsinki/slisemap/blob/main/examples/demo_paper.pdf), the [demonstration video](https://youtu.be/zvcFYItwRlQ) ([slides](https://github.com/edahelsinki/slisemap/blob/main/examples/demo_presentation.pdf)), the [examples](https://github.com/edahelsinki/slisemap/tree/main/examples), or the [documentation](https://edahelsinki.github.io/slisemap/slisemap). +SLISEMAP is implemented in *Python* using *PyTorch* for efficient optimisation, and optional GPU-acceleration. For more information see the [full paper](https://doi.org/10.1007/s10994-022-06261-1) ([arXiv](https://arxiv.org/abs/2201.04455)), the [demo paper](https://github.com/edahelsinki/slisemap/blob/main/examples/demo_paper.pdf), the [demo video](https://youtu.be/zvcFYItwRlQ) ([slides](https://github.com/edahelsinki/slisemap/blob/main/examples/demo_presentation.pdf)), the [examples](https://github.com/edahelsinki/slisemap/tree/main/examples), or the [documentation](https://edahelsinki.github.io/slisemap/slisemap). ## Citation > *Björklund, A., Mäkelä, J. & Puolamäki, K. (2022).* > **SLISEMAP: Supervised dimensionality reduction through local explanations**. -> arXiv:2201.04455 [cs], [https://arxiv.org/abs/2201.04455](https://arxiv.org/abs/2201.04455). +> Machine Learning, [DOI 10.1007/s10994-022-06261-1](https://doi.org/10.1007/s10994-022-06261-1) ## Installation diff --git a/examples/demo_paper.pdf b/examples/demo_paper.pdf index 0ecf110..6ce9da3 100644 Binary files a/examples/demo_paper.pdf and b/examples/demo_paper.pdf differ diff --git a/examples/demo_presentation.pdf b/examples/demo_presentation.pdf index 1d2a8b4..a24e9ac 100644 Binary files a/examples/demo_presentation.pdf and b/examples/demo_presentation.pdf differ diff --git a/experiments/README.md b/experiments/README.md index d1feaa8..bc32034 100644 --- a/experiments/README.md +++ b/experiments/README.md @@ -3,4 +3,4 @@ This directory contains the experiments for the paper. The scripts are also used to produce the plots and tables in the paper. Running all experiments sequentially would take hundreds of hours, but cached results from the experiments can be found [here](https://github.com/edahelsinki/slisemap/tree/data/results). -The results can also be seen in [the paper](https://arxiv.org/abs/2201.04455). +The results can also be seen in [the paper](https://doi.org/10.1007/s10994-022-06261-1). diff --git a/mkdocs.yml b/mkdocs.yml index 5613066..91e7892 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -43,7 +43,9 @@ nav: - Links: - GitHub: https://github.com/edahelsinki/slisemap - PyPI: https://pypi.org/project/slisemap/ - - Paper: https://arxiv.org/abs/2201.04455 + - Paper: https://doi.org/10.1007/s10994-022-06261-1 + - arXiv: https://arxiv.org/abs/2201.04455 + - Demo Video: https://youtu.be/zvcFYItwRlQ - Demo Paper: https://github.com/edahelsinki/slisemap/blob/main/examples/demo_paper.pdf - Presentation: https://github.com/edahelsinki/slisemap/blob/main/examples/demo_presentation.pdf - Examples: https://github.com/edahelsinki/slisemap/tree/main/examples diff --git a/setup.cfg b/setup.cfg index b398afc..33e042c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = slisemap -version = 1.2.0 +version = 1.2.1 author = Anton Björklund, Jarmo Mäkelä, and Kai Puolamäki author_email = anton.bjorklund@helsinki.fi, jarmo.makela@helsinki.fi, kai.puolamaki@helsinki.fi description = SLISEMAP: Combine local explanations with supervised dimensionality reduction diff --git a/slisemap/__init__.py b/slisemap/__init__.py index 014ede9..863a4ce 100644 --- a/slisemap/__init__.py +++ b/slisemap/__init__.py @@ -9,15 +9,16 @@ items with similar local explanations are projected nearby. The explanations consists of "white box" models that locally approximate the "black box" model. -SLISEMAP uses *PyTorch* for efficient optimisation, and optional GPU-acceleration. For -more information see the the [repository](https://github.com/edahelsinki/slisemap) or -the [paper](https://arxiv.org/abs/2201.04455). +SLISEMAP uses *PyTorch* for efficient optimisation, and optional GPU-acceleration. +For more information see the the [repository](https://github.com/edahelsinki/slisemap), +the [documentation](https://edahelsinki.github.io/slisemap/slisemap), or the +[paper](https://doi.org/10.1007/s10994-022-06261-1). Citation -------- > Björklund, A., Mäkelä, J. & Puolamäki, K. (2022). > SLISEMAP: Supervised dimensionality reduction through local explanations. -> arXiv:2201.04455 [cs], https://arxiv.org/abs/2201.04455. +> Machine Learning, DOI 10.1007/s10994-022-06261-1. Example Usage diff --git a/slisemap/slisemap.py b/slisemap/slisemap.py index 8d796c1..da57119 100644 --- a/slisemap/slisemap.py +++ b/slisemap/slisemap.py @@ -364,13 +364,16 @@ def local_model(self, value: Callable[[torch.Tensor, torch.Tensor], torch.Tensor @property def local_loss( self, - ) -> Callable[[torch.Tensor, torch.Tensor, torch.Tensor], torch.Tensor]: + ) -> Callable[[torch.Tensor, torch.Tensor, Optional[torch.Tensor]], torch.Tensor]: # Local model loss function. Takes in Ytilde[n, n, o], Y[n, o], and B[n, q], and returns L[n, n] return self._local_loss @local_loss.setter def local_loss( - self, value: Callable[[torch.Tensor, torch.Tensor, torch.Tensor], torch.Tensor] + self, + value: Callable[ + [torch.Tensor, torch.Tensor, Optional[torch.Tensor]], torch.Tensor + ], ): if self._local_loss != value: _assert(callable(value), "local_loss must be callable", Slisemap.local_loss) @@ -1381,8 +1384,11 @@ def plot_position( loc="lower center" if inside else "upper right", bbox_to_anchor=(1 - w, h * 0.35, w * 0.9, h * 0.6) if inside else None, ) + marker = Line2D( + [], [], linestyle="None", color="#fd8431", marker="X", markersize=5 + ) g.add_legend( - {"": Line2D([], [], None, "None", "#fd8431", "X", 5)}, + {"": marker}, "Selected", loc="upper center" if inside else "lower right", bbox_to_anchor=(1 - w, h * 0.05, w * 0.9, h * 0.3) if inside else None, diff --git a/tests/test_slisemap.py b/tests/test_slisemap.py index 08ba94e..a72a370 100644 --- a/tests/test_slisemap.py +++ b/tests/test_slisemap.py @@ -36,6 +36,24 @@ def test_lbfgs(): assert l1 >= l2 +def test_only_B(): + set_seed(653274) + sm = get_slisemap(30, 4) + sm.optimise(1, 3) + sm2 = Slisemap( + X=sm.get_X(intercept=False, numpy=False), + y=sm.get_Y(numpy=False), + radius=sm.radius, + lasso=sm.lasso, + intercept=sm.intercept, + Z0=sm.get_Z(numpy=False), + ) + sm2.optimise(1, 3, only_B=True) + assert_allclose(sm.get_Z(), sm2.get_Z()) + assert_approx_ge(sm.value(), sm2.value()) + sm.lbfgs(only_B=True) + + def test_fit_new(): sm, _ = get_slisemap2(60, 5, cheat=True, seed=239177) sm.lbfgs()