diff --git a/README.md b/README.md index 9ead9a10..ee1fb6f1 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,12 @@ +# [CapyMOA](https://capymoa.org) + ![Banner Image](https://github.com/adaptive-machine-learning/CapyMOA/raw/main/docs/images/CapyMOA.jpeg) -# [CapyMOA](https://capymoa.org) -[PyPi Version](https://pypi.org/project/capymoa/) -[Join the Discord](https://discord.gg/spd2gQJGAb) +[![PyPi Version](https://img.shields.io/pypi/v/capymoa)](https://pypi.org/project/capymoa/) +[![Join the Discord](https://img.shields.io/discord/1235780483845984367?label=Discord)](https://discord.gg/spd2gQJGAb) +[![Documentation](https://img.shields.io/badge/docs-latest-blue)](https://capymoa.org) +[![GitHub](https://img.shields.io/github/stars/adaptive-machine-learning/CapyMOA?style=social)](https://github.com/adaptive-machine-learning/CapyMOA) + Machine learning library tailored for data streams. Featuring a Python API tightly integrated with MOA (**Stream Learners**), PyTorch (**Neural @@ -10,10 +14,10 @@ Networks**), and scikit-learn (**Machine Learning**). CapyMOA provides a **fast** python interface to leverage the state-of-the-art algorithms in the field of data streams. -To setup CapyMOA, simply install it via pip. If you have any issues with the +To setup CapyMOA, simply install it via pip. If you have any issues with the installation (like not having Java installed) or if you want GPU support, please -refer to the [installation guide](docs/installation.md). Once installed take a -look at the [tutorials](capymoa.org/notebooks/index.html) to get started. +refer to the [installation guide](https://capymoa.org/installation). Once installed take a +look at the [tutorials](https://capymoa.org/notebooks/) to get started. ```bash # CapyMOA requires Java. This checks if you have it installed @@ -29,22 +33,11 @@ pip install capymoa python -c "import capymoa; print(capymoa.__version__)" ``` - - > **⚠️ WARNING** > -> CapyMOA is still in the early stages of development. The API is subject to -> change until version 1.0.0. If you encounter any issues, please report +> CapyMOA is still in the early stages of development. The API is subject to +> change until version 1.0.0. If you encounter any issues, please report > them in [GitHub Issues](https://github.com/adaptive-machine-learning/CapyMOA/issues) > or talk to us on [Discord](https://discord.gg/spd2gQJGAb). - -![Benchmark Image](https://github.com/adaptive-machine-learning/CapyMOA/raw/main/docs/images/benchmark_20240422_221824_performance_plot_wallclock.png) - -## 🏗️ Contributing - -* **[How to install CapyMOA.](docs/installation.md)** -* **[How to add documentation.](docs/contributing/docs.md)** -* **[How to add tests.](docs/contributing/tests.md)** -* **[How to add new algorithms or methods.](docs/contributing/learners.md)** -* **[How to format a commit message for CapyMOA.](docs/contributing/vcs.md)** +![Benchmark Image](https://github.com/adaptive-machine-learning/CapyMOA/raw/main/docs/images/arf100_cpu_time.png) diff --git a/docs/conf.py b/docs/conf.py index a2e6f09b..8eb6a1b3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -8,6 +8,7 @@ import os from pathlib import Path from capymoa.__about__ import __version__ +from docs.util.github_link import make_linkcode_resolve project = 'CapyMOA' copyright = '2024 CapyMOA Developers' @@ -19,6 +20,7 @@ # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration extensions = [ + "sphinx.ext.linkcode", "sphinx.ext.autodoc", "sphinx.ext.intersphinx", "nbsphinx", @@ -79,3 +81,42 @@ intersphinx_mapping = { 'sklearn': ('https://scikit-learn.org/stable/', None), } + +""" Options for linkcode extension ------------------------------------------ +The linkcode extension is used to provide links to the source code of functions +and classes in the documentation. +""" + +linkcode_resolve = make_linkcode_resolve( + "capymoa", + ( + "https://github.com/adaptive-machine-learning/" + "CapyMOA/blob/{revision}/src/" + "{package}/{path}#L{lineno}" + ), +) + +""" Options for the Theme --------------------------------------------------- +""" +html_theme_options = { + "icon_links": [ + { + "name": "GitHub", + "url": "https://github.com/adaptive-machine-learning/CapyMOA", # required + "icon": "fa-brands fa-github", + "type": "fontawesome", + }, + { + "name": "PyPI", + "url": "https://pypi.org/project/capymoa/", + "icon": "fa-solid fa-box", + "type": "fontawesome", + }, + { + "name": "Discord", + "url": "https://discord.gg/spd2gQJGAb", + "icon": "fa-brands fa-discord", + "type": "fontawesome", + } + ] +} diff --git a/docs/images/arf100_cpu_time.png b/docs/images/arf100_cpu_time.png new file mode 100644 index 00000000..1a410ce4 Binary files /dev/null and b/docs/images/arf100_cpu_time.png differ diff --git a/docs/images/arf100_cpu_time_dark.png b/docs/images/arf100_cpu_time_dark.png new file mode 100644 index 00000000..211bde3c Binary files /dev/null and b/docs/images/arf100_cpu_time_dark.png differ diff --git a/docs/index.rst b/docs/index.rst index 53139fd9..c6f4ec08 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,19 +3,24 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -.. image:: /images/CapyMOA.jpeg - :alt: CapyMOA CapyMOA ======= + +.. image:: /images/CapyMOA.jpeg + :alt: CapyMOA + .. image:: https://img.shields.io/pypi/v/capymoa :target: https://pypi.org/project/capymoa/ - :alt: PyPI version badge - -.. Discord: + :alt: Link to PyPI + .. image:: https://img.shields.io/discord/1235780483845984367?label=Discord - :target: https://discord.gg/spd2gQJGAb - :alt: discord badge https://discord.gg/spd2gQJGAb + :target: https://discord.gg/spd2gQJGAb + :alt: Link to Discord + +.. image:: https://img.shields.io/github/stars/adaptive-machine-learning/CapyMOA?style=flat + :target: https://github.com/adaptive-machine-learning/CapyMOA + :alt: Link to GitHub Machine learning library tailored for data streams. Featuring a Python API tightly integrated with MOA (**Stream Learners**), PyTorch (**Neural @@ -49,9 +54,15 @@ to get started. on the `GitHub Issues `_ or talk to us on `Discord `_. -.. image:: /images/benchmark_20240422_221824_performance_plot_wallclock.png +.. image:: /images/arf100_cpu_time.png + :alt: Performance plot + :align: center + :class: only-light + +.. image:: /images/arf100_cpu_time_dark.png :alt: Performance plot :align: center + :class: only-dark .. _installation: diff --git a/docs/util/github_link.py b/docs/util/github_link.py new file mode 100644 index 00000000..97893933 --- /dev/null +++ b/docs/util/github_link.py @@ -0,0 +1,90 @@ +"""Code taken from: +https://github.com/scikit-learn/scikit-learn/blob/8721245511de2f225ff5f9aa5f5fadce663cd4a3/doc/sphinxext/github_link.py +""" +import inspect +import os +import subprocess +import sys +from functools import partial +from operator import attrgetter + +REVISION_CMD = "git rev-parse --short HEAD" + + +def _get_git_revision(): + try: + revision = subprocess.check_output(REVISION_CMD.split()).strip() + except (subprocess.CalledProcessError, OSError): + print("Failed to execute git to get revision") + return None + return revision.decode("utf-8") + + +def _linkcode_resolve(domain, info, package, url_fmt, revision): + """Determine a link to online source for a class/method/function + + This is called by sphinx.ext.linkcode + + An example with a long-untouched module that everyone has + >>> _linkcode_resolve('py', {'module': 'tty', + ... 'fullname': 'setraw'}, + ... package='tty', + ... url_fmt='https://hg.python.org/cpython/file/' + ... '{revision}/Lib/{package}/{path}#L{lineno}', + ... revision='xxxx') + 'https://hg.python.org/cpython/file/xxxx/Lib/tty/tty.py#L18' + """ + if revision is None: + return + if domain not in ("py", "pyx"): + return + if not info.get("module") or not info.get("fullname"): + return + + class_name = info["fullname"].split(".")[0] + module = __import__(info["module"], fromlist=[class_name]) + + try: + obj = attrgetter(info["fullname"])(module) + except AttributeError: + return + + # Unwrap the object to get the correct source + # file in case that is wrapped by a decorator + obj = inspect.unwrap(obj) + + try: + fn = inspect.getsourcefile(obj) + except Exception: + fn = None + if not fn: + try: + fn = inspect.getsourcefile(sys.modules[obj.__module__]) + except Exception: + fn = None + if not fn: + return + + fn = os.path.relpath(fn, start=os.path.dirname(__import__(package).__file__)) + try: + lineno = inspect.getsourcelines(obj)[1] + except Exception: + lineno = "" + return url_fmt.format(revision=revision, package=package, path=fn, lineno=lineno) + + +def make_linkcode_resolve(package, url_fmt): + """Returns a linkcode_resolve function for the given URL format + + revision is a git commit reference (hash or name) + + package is the name of the root module of the package + + url_fmt is along the lines of ('https://github.com/USER/PROJECT/' + 'blob/{revision}/{package}/' + '{path}#L{lineno}') + """ + revision = _get_git_revision() + return partial( + _linkcode_resolve, revision=revision, package=package, url_fmt=url_fmt + ) diff --git a/experiments/experiments_20230913.csv b/experiments/experiments_20230913.csv deleted file mode 100644 index 3de74885..00000000 --- a/experiments/experiments_20230913.csv +++ /dev/null @@ -1,25 +0,0 @@ -,,accuracy,wallclock(s),cpu_time(s) -MOA,NaiveBayes,51.139,3.363631248,3.734511 -MOA,HoeffdingTree,53.819,4.708353043,6.055893 -MOA,EFDT,54.254,4.903990746,5.11434 -MOA,kNN,60.803,27.23430562,27.476316 -MOA,ARF5,82.537,23.39235616,25.049668 -MOA,ARF10,83.527,44.59485602,45.597566 -MOA,ARF30,83.666,131.1556952,135.52801 -MOA,ARF100,83.616,430.4460778,455.288466 -MOA,ARF100_j4,83.616,182.7559922,479.363561 -MOA,SRP5,77.77,43.20379019,44.026689 -MOA,SRP10,73.559,92.21778369,95.664852 -MOA,SRP30,79.869,253.2540581,268.322701 -MOA,SRP100,79.383,845.792577,936.854447 -River,NaiveBayes,51.138,13.48207521,13.479383 -River,HoeffdingTree,53.687,26.60836816,26.603663 -River,kNN,60.159,1437.030073,604.000725 -River,ARF5,78.585,166.636811,166.637308 -River,ARF10,79.093,4860.852145,368.664245 -River,ARF30,79.785,1093.956636,1092.985935 -River,ARF100,80.08,32790.39175,4121.367358 -River,SRP5,75.41,467.6464481,466.737587 -River,SRP10,76.591,985.7005198,981.391106 -River,SRP30,76.024,3570.390376,3145.303672 -River,SRP100,76.929,14216.34777,11654.60466 \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 1f5a79fb..4f1ed634 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,6 +79,10 @@ doc=[ "myst-parser" ] +[project.urls] +Documentation = "https://capymoa.org" +Source = "https://github.com/adaptive-machine-learning/CapyMOA" + [tool.pytest.ini_options] addopts = ["--import-mode=importlib"] pythonpath = ["src"]