From d9f58336fb15fa00e04587d49d1636968d47ebfb Mon Sep 17 00:00:00 2001 From: Scott Sievert Date: Sun, 16 Aug 2020 00:17:58 -0500 Subject: [PATCH] DOC: implement ReadTheDocs documentation (#58) --- .DS_Store | Bin 0 -> 6148 bytes .gitignore | 2 + .readthedocs.yaml | 9 ++ docs/Makefile | 20 ++++ docs/make.bat | 35 ++++++ docs/requirements.txt | 2 + docs/source/_templates/class.rst | 11 ++ docs/source/api.rst | 9 ++ docs/source/conf.py | 189 +++++++++++++++++++++++++++++++ docs/source/index.rst | 23 ++++ pyproject.toml | 8 +- scikeras/wrappers.py | 17 +-- 12 files changed, 312 insertions(+), 13 deletions(-) create mode 100644 .DS_Store create mode 100644 .readthedocs.yaml create mode 100644 docs/Makefile create mode 100644 docs/make.bat create mode 100644 docs/requirements.txt create mode 100644 docs/source/_templates/class.rst create mode 100644 docs/source/api.rst create mode 100644 docs/source/conf.py create mode 100644 docs/source/index.rst diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..a5c2315f7bb7cc4988bd116fdc15e67a4bdf779f GIT binary patch literal 6148 zcmeHKJ8DBg3>+nf7}B^*xmWNF7UP`27ce*w7ydvzHcagx&TK46P??6LdF zKfLCx*J;X10VyB_q<|EV0>4zidoOMJn5ZZPq<|FoR=~dxjqcbBhs5}FFvJKzoG=~6 zb<7gP<_Tgi91@wKSyG8fwHh%j>CCsP>xDyN(qT1xSUuTlLa}%{?{85K>xqg|Knh$c zaG%?m_y1@5jrsqQq@5Iy0{=<@n=Dt$1z)Lp>*(dY*Eaf^?lqruH?D)i5bc;4?U);H e$4^m|bNUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 000000000..0aa5c0ed4 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +# Pins sphinx version, probably won't need updating for a while +sphinx>=3.2.1 \ No newline at end of file diff --git a/docs/source/_templates/class.rst b/docs/source/_templates/class.rst new file mode 100644 index 000000000..d787bea50 --- /dev/null +++ b/docs/source/_templates/class.rst @@ -0,0 +1,11 @@ +:mod:`{{module}}`.{{objname}} +{{ underline }}============== + +.. currentmodule:: {{ module }} + +.. autoclass:: {{ objname }} + :members: + +.. raw:: html + +
diff --git a/docs/source/api.rst b/docs/source/api.rst new file mode 100644 index 000000000..d09b2ecf4 --- /dev/null +++ b/docs/source/api.rst @@ -0,0 +1,9 @@ +API +=== + +.. autosummary:: + :template: class.rst + :toctree: generated/ + + scikeras.wrappers.KerasClassifier + scikeras.wrappers.KerasRegressor diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 000000000..a311bf209 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,189 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys + + +sys.path.insert(0, os.path.abspath("..")) + +# -- Project information ----------------------------------------------------- + +from scikeras import __version__ + + +project = "SciKeras" +copyright = "2020, SciKeras Developers" +author = "SciKeras Developers" +release = __version__ + + +# -- General configuration --------------------------------------------------- + +# on_rtd is whether we are on readthedocs.org, this line of code grabbed +# from docs.readthedocs.org +on_rtd = os.environ.get("READTHEDOCS", None) == "True" + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.napoleon", + "sphinx.ext.linkcode", + "sphinx.ext.autosummary", + "sphinx.ext.autosectionlabel", + "sphinx.ext.intersphinx", +] +autosummary_generate = True +autodoc_default_options = { + "members": True, + "member-order": "alphabetical", + "special-members": "__init__", + "undoc-members": True, + "exclude-members": "__weakref__", + "inherited-members": True, +} +intersphinx_mapping = { + "sklearn": ("https://scikit-learn.org/stable/", None), + "numpy": ("https://numpy.org/doc/stable/", None), + "python": ("https://docs.python.org/3", None), +} + + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "default" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_context = { + "display_github": True, + "github_user": "adriangb", + "github_repo": "scikeras", + "github_version": "master", + "conf_py_path": "/source/", +} + +if not on_rtd: # only import and set the theme if we're building docs locally + import sphinx_rtd_theme + + html_theme = "sphinx_rtd_theme" + html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + +# -- GitHub source code link ---------------------------------------------- + +# Functionality to build github source URI, taken from sklearn. + +import inspect +import subprocess + +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='http://hg.python.org/cpython/file/' + ... '{revision}/Lib/{package}/{path}#L{lineno}', + ... revision='xxxx') + 'http://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] + if type(class_name) != str: + # Python 2 only + class_name = class_name.encode("utf-8") + module = __import__(info["module"], fromlist=[class_name]) + obj = attrgetter(info["fullname"])(module) + + 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 project_linkcode_resolve(domain, info): + global _linkcode_git_revision + return _linkcode_resolve( + domain, + info, + package="scikeras", + revision=_linkcode_git_revision, + url_fmt="https://github.com/adriangb/scikeras/" + "blob/{revision}/" + "{package}/{path}#L{lineno}", + ) + + +_linkcode_git_revision = _get_git_revision() + +# The following is used by sphinx.ext.linkcode to provide links to github +linkcode_resolve = project_linkcode_resolve diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 000000000..edc66d3bc --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,23 @@ +.. SciKeras documentation master file, created by + sphinx-quickstart on Sat Aug 15 16:47:22 2020. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to SciKeras's documentation! +==================================== + +SciKeras provides a Scikit-Learn style API for Keras. + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + api + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/pyproject.toml b/pyproject.toml index 1bb928a4a..4a0cc4a24 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,6 +38,13 @@ pytest-cov = "*" pre-commit = "*" pytest-xdist = "*" +# docs +sphinx = { version=">=3.2.1", optional = true } +sphinx_rtd_theme = { version=">=0.5.0", optional = true } + +[tool.poetry.extras] +docs = ["sphinx", "sphinx_rtd_theme"] + [tool.isort] line_length = 79 force_single_line = true @@ -67,4 +74,3 @@ show_missing = true [build-system] requires = ["poetry>=1.0.10"] build-backend = "poetry.masonry.api" - diff --git a/scikeras/wrappers.py b/scikeras/wrappers.py index ad7bd54ff..f7d0e77d9 100644 --- a/scikeras/wrappers.py +++ b/scikeras/wrappers.py @@ -354,8 +354,6 @@ def preprocess_y(y): Returns: y : numpy array of shape (n_samples, n_ouputs) extra_args : dictionary of output attributes, ex: n_outputs_ - These parameters are added to `self` by `fit` and - consumed (but not reset) by `score`. """ extra_args = dict() @@ -377,8 +375,7 @@ def postprocess_y(y): Returns: y : 2D numpy array with singular dimensions stripped or 1D numpy array - extra_args : attributes of output `y` such as probabilites. - Currently unused by KerasRegressor but kept for flexibility. + extra_args : attributes of output `y`. """ y = np.column_stack(y) @@ -397,9 +394,7 @@ def preprocess_X(X): Returns: X : unchanged 2D numpy array - extra_args : attributes of output `y` such as probabilites. - Currently unused by KerasRegressor but kept for - flexibility. + extra_args : attributes of output `y`. """ extra_args = dict() return X, extra_args @@ -573,7 +568,7 @@ def score(self, X, y, sample_weight=None, **kwargs): sample_weight : array-like of shape (n_samples,), default=None Sample weights. The Keras Model must support this. **kwargs: dictionary arguments - Legal arguments are those of self.model_.evaluate. + Legal arguments are those of `self.model_.evaluate`. Returns: score: float @@ -667,16 +662,14 @@ class KerasClassifier(BaseWrapper): def preprocess_y(y): """Handles manipulation of y inputs to fit or score. - For KerasClassifier, this handles interpreting classes from `y`. + For KerasClassifier, this handles interpreting classes from `y`. Arguments: y : 1D or 2D numpy array Returns: y : modified 2D numpy array with 0 indexed integer class labels. - classes_ : list of original class labels. - n_classes_ : number of classes. - one_hot_encoded : True if input y was one-hot-encoded. + extra_args : dictionary of output attributes, ex `n_outputs_` """ y, _ = super(KerasClassifier, KerasClassifier).preprocess_y(y)