From c3fd56c6f619287157a514898ddf715f5c9a3a1a Mon Sep 17 00:00:00 2001 From: Camen Piho <29082904+camenpihor@users.noreply.github.com> Date: Fri, 3 Jul 2020 13:29:31 -0700 Subject: [PATCH] Some linting while re-reading library (#219) --- README.md | 5 ++-- bambi/backends/__init__.py | 4 +--- bambi/backends/base.py | 4 +--- bambi/backends/pymc.py | 27 ++++++++-------------- bambi/external/patsy.py | 14 +++++++----- bambi/models.py | 47 ++++++++++++-------------------------- bambi/priors.py | 14 ++++++------ bambi/utils.py | 6 +++-- 8 files changed, 48 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index e5bbbf390..8d199c2b7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -Bambi ------- +# Bambi + BAyesian Model-Building Interface in Python [![Build Status](https://travis-ci.org/bambinos/bambi.svg?branch=master)](https://travis-ci.org/bambinos/bambi) @@ -26,7 +26,6 @@ Alternatively, if you want the bleeding edge version of the package you can inst Bambi requires working versions of numpy, pandas, matplotlib, patsy, pymc3, and theano. Dependencies are listed in `requirements.txt`, and should all be installed by the Bambi installer; no further action should be required. - ## Documentation The Bambi documentation can be found in the [official docs](https://bambinos.github.io/bambi/index.html) diff --git a/bambi/backends/__init__.py b/bambi/backends/__init__.py index 6dfcc67d0..7456771db 100644 --- a/bambi/backends/__init__.py +++ b/bambi/backends/__init__.py @@ -1,6 +1,4 @@ from .pymc import PyMC3BackEnd -__all__ = [ - 'PyMC3BackEnd' -] +__all__ = ["PyMC3BackEnd"] diff --git a/bambi/backends/base.py b/bambi/backends/base.py index 41299799a..1b66fa30c 100644 --- a/bambi/backends/base.py +++ b/bambi/backends/base.py @@ -2,10 +2,8 @@ class BackEnd: + """Base class for BackEnd hierarchy.""" - ''' - Base class for BackEnd hierarchy. - ''' __metaclass__ = ABCMeta @abstractmethod diff --git a/bambi/backends/pymc.py b/bambi/backends/pymc.py index 474b26a3f..ff984d879 100644 --- a/bambi/backends/pymc.py +++ b/bambi/backends/pymc.py @@ -1,17 +1,15 @@ import numpy as np +import pymc3 as pm import theano from arviz import from_pymc3 -import pymc3 as pm + from bambi.priors import Prior from .base import BackEnd class PyMC3BackEnd(BackEnd): - - """ - PyMC3 model-fitting back-end. - """ + """PyMC3 model-fitting back-end.""" # Available link functions links = { @@ -25,7 +23,6 @@ class PyMC3BackEnd(BackEnd): dists = {"HalfFlat": pm.Bound(pm.Flat, lower=0)} def __init__(self): - self.reset() # Attributes defined elsewhere @@ -35,15 +32,13 @@ def __init__(self): self.advi_params = None # build() def reset(self): - """ - Reset PyMC3 model and all tracked distributions and parameters. - """ + """Reset PyMC3 model and all tracked distributions and parameters.""" self.model = pm.Model() self.mu = None self.par_groups = {} def _build_dist(self, spec, label, dist, **kwargs): - """ Build and return a PyMC3 Distribution. """ + """Build and return a PyMC3 Distribution.""" if isinstance(dist, str): if hasattr(pm, dist): dist = getattr(pm, dist) @@ -77,8 +72,7 @@ def _expand_args(key, value, label): return dist(label, **kwargs) def build(self, spec, reset=True): # pylint: disable=arguments-differ - """ - Compile the PyMC3 model from an abstract model specification. + """Compile the PyMC3 model from an abstract model specification. Parameters ---------- @@ -122,8 +116,7 @@ def build(self, spec, reset=True): # pylint: disable=arguments-differ # pylint: disable=arguments-differ, inconsistent-return-statements def run(self, start=None, method="mcmc", init="auto", n_init=50000, **kwargs): - """ - Run the PyMC3 MCMC sampler. + """Run the PyMC3 MCMC sampler. Parameters ---------- @@ -168,9 +161,9 @@ def run(self, start=None, method="mcmc", init="auto", n_init=50000, **kwargs): def _laplace(model): - """ - Fit a model using a laplace approximation. Mainly for pedagogical use. ``mcmc`` and ``advi`` - are better approximations + """Fit a model using a laplace approximation. + + Mainly for pedagogical use. ``mcmc`` and ``advi`` are better approximations. Parameters ---------- diff --git a/bambi/external/patsy.py b/bambi/external/patsy.py index 4dbd6bf5d..8c966bea6 100644 --- a/bambi/external/patsy.py +++ b/bambi/external/patsy.py @@ -1,14 +1,16 @@ -import numpy as np import re -from patsy.util import safe_scalar_isnan + +import numpy as np + from patsy import PatsyError +from patsy.util import safe_scalar_isnan class Custom_NA: - """ - Custom patsy.missing.NAAction class. Similar to patsy drop/raise defaults, - but changes the raised message and logs which rows (if any) are dropped. - See Patsy code/API for NAAction documentation. + """Custom patsy.missing.NAAction class. + + Similar to patsy drop/raise defaults, but changes the raised message and logs which rows (if + any) are dropped. See Patsy code/API for NAAction documentation. """ def __init__(self, dropna=False, NA_types=["None", "NaN"]): diff --git a/bambi/models.py b/bambi/models.py index 0990f688d..2d6cdd8d8 100644 --- a/bambi/models.py +++ b/bambi/models.py @@ -4,23 +4,21 @@ from collections import OrderedDict from copy import deepcopy -import pandas as pd import numpy as np -from patsy import dmatrices, dmatrix +import pandas as pd +import pymc3 as pm import statsmodels.api as sm from arviz.plots import plot_posterior -import pymc3 as pm - +from patsy import dmatrices, dmatrix +from .backends import PyMC3BackEnd from .external.patsy import Custom_NA -from .priors import PriorFactory, PriorScaler, Prior +from .priors import Prior, PriorFactory, PriorScaler from .utils import listify -from .backends import PyMC3BackEnd class Model: - """ - Specification of model class + """Specification of model class. Parameters ---------- @@ -104,9 +102,7 @@ def __init__( self.built = False # build() def reset(self): - """ - Reset list of terms and y-variable. - """ + """Reset list of terms and y-variable.""" self.terms = OrderedDict() self.y = None self.backend = None @@ -116,7 +112,6 @@ def reset(self): self.clean_data = None def _set_backend(self, backend): - backend = backend.lower() if backend.startswith("pymc"): @@ -140,7 +135,6 @@ def build(self, backend=None): supported. If None, assume that `fit()` has already been called (possibly without building) and look in self._backend_name. """ - # retain only the complete cases n_total = len(self.data.index) if self.completes: @@ -316,7 +310,6 @@ def fit( backend : str The name of the BackEnd to use. Currently only 'pymc' backen is supported. """ - if fixed is not None or random is not None: self.add( fixed=fixed, @@ -332,7 +325,6 @@ def fit( if backend is None: backend = "pymc" if self._backend_name is None else self._backend_name - if run: if not self.built or backend != self._backend_name: self.build(backend) @@ -351,8 +343,7 @@ def add( categorical=None, append=True, ): - """ - Adds one or more terms to the model via an R-like formula syntax. + """Add one or more terms to the model via an R-like formula syntax. Parameters ---------- @@ -385,7 +376,6 @@ def add( If True, terms are appended to the existing model rather than replacing any existing terms. This allows formula-based specification of the model in stages. """ - data = self.data # Primitive values (floats, strs) can be overwritten with Prior objects @@ -446,7 +436,6 @@ def _add( Runs during Model.build() """ - # use cleaned data with NAs removed (if user requested) data = self.clean_data # alter this pandas flag to avoid false positive SettingWithCopyWarnings @@ -613,13 +602,11 @@ def _add_y(self, variable, prior=None, family="gaussian", link=None, *args, **kw self.built = False def _match_derived_terms(self, name): - """ - Returns all (random) terms whose named are derived from the - specified string. For example, 'condition|subject' should match the - terms with names '1|subject', 'condition[T.1]|subject', and so on. - Only works for strings with grouping operator ('|'). - """ + """Return all (random) terms whose named are derived from the specified string. + For example, 'condition|subject' should match the terms with names '1|subject', + 'condition[T.1]|subject', and so on. Only works for strings with grouping operator ('|'). + """ if "|" not in name: return None @@ -679,7 +666,6 @@ def _set_priors(self, priors=None, fixed=None, random=None, match_derived_names= Runs during Model.build(). """ - targets = {} if fixed is not None: @@ -705,16 +691,15 @@ def _set_priors(self, priors=None, fixed=None, random=None, match_derived_names= for name, prior in targets.items(): self.terms[name].prior = prior - # helper function to correctly set default priors, auto_scaling, etc. def _prepare_prior(self, prior, _type): - """ + """Helper function to correctly set default priors, auto_scaling, etc. + Parameters ---------- prior : Prior object, or float, or None. _type : string accepted values are: 'intercept, 'fixed', or 'random'. """ - if prior is None and not self.auto_scale: prior = self.default_priors.get(term=_type + "_flat") @@ -736,8 +721,7 @@ def plot_priors(self, var_names=None): raise ValueError("Cannot plot priors until model is built!") with pm.Model(): - # get priors for fixed fx, separately for each level of each - # predictor + # get priors for fixed fx, separately for each level of each predictor dists = [] for fixed_term in self.fixed_terms.values(): if var_names is not None and fixed_term.name not in var_names: @@ -811,7 +795,6 @@ class Term: random = False def __init__(self, name, data, categorical=False, prior=None, constant=None): - self.name = name self.categorical = categorical self._reduced_data = None diff --git a/bambi/priors.py b/bambi/priors.py index 3e503eeca..c2273c999 100644 --- a/bambi/priors.py +++ b/bambi/priors.py @@ -71,7 +71,6 @@ def update(self, **kwargs): kwargs : dict Optional keyword arguments to add to prior args. """ - # Backends expect numpy arrays, so make sure all numeric values are represented as such. kwargs = {k: (np.array(v) if isinstance(v, (int, float)) else v) for k, v in kwargs.items()} self.args.update(kwargs) @@ -114,7 +113,6 @@ class PriorFactory: """ def __init__(self, defaults=None, dists=None, terms=None, families=None): - if defaults is None: defaults = join(dirname(__file__), "config", "priors.json") @@ -138,7 +136,6 @@ def __init__(self, defaults=None, dists=None, terms=None, families=None): self.families = defaults["families"] def _get_prior(self, spec, **kwargs): - if isinstance(spec, str): spec = re.sub(r"^\#", "", spec) return self._get_prior(self.dists[spec]) @@ -217,10 +214,13 @@ def __init__(self, model, taylor): def _get_slope_stats(self, exog, predictor, sigma_corr, full_mod=None, points=4): """ - Args: - full_mod: statsmodels GLM to replace MLE model. For when 'predictor' - is not in the fixed part of the model. - points: number of points to use for LL approximation. + Parameters + ---------- + full_mod : statsmodels.genmod.generalized_linear_model.GLM + Statsmodels GLM to replace MLE model. For when 'predictor' is not in the fixed part + of the model. + points : int + Number of points to use for LL approximation. """ if full_mod is None: diff --git a/bambi/utils.py b/bambi/utils.py index 39dddfc0a..a5aeee825 100644 --- a/bambi/utils.py +++ b/bambi/utils.py @@ -1,6 +1,8 @@ def listify(obj): - """ Wraps all non-list or tuple objects in a list; provides a simple - way to accept flexible arguments. """ + """Wrap all non-list or tuple objects in a list. + + Provides a simple way to accept flexible arguments. + """ if obj is None: return [] else: