Skip to content

Commit

Permalink
docs: add numpy docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
JasperHG90 committed Jan 16, 2021
1 parent f67d7c2 commit a1ec1cc
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 20 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ class MyPivenModel(PivenBaseModel):

@classmethod
def load(cls, path: str):
model_config = MyPivenModel.load_model_config(path)
model = MyPivenModel.load_model_from_disk(build_fn=piven_model, path)
model_config = MyPivenModel._load_model_config(path)
model = MyPivenModel._load_model_from_disk(build_fn=piven_model, path)
run = cls(**model_config)
run.model = model
return run
Expand Down
2 changes: 1 addition & 1 deletion src/piven/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from piven.models.mlp_regressor import PivenMlpModel # noqa: F401
from piven.models.mlp_regressor import PivenMlpModel, piven_mlp_model # noqa: F401
126 changes: 109 additions & 17 deletions src/piven/models/base.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
import json
import abc
from pathlib import Path
from typing import Callable, Dict
from typing import Callable, Dict, Union
import pandas as pd
import numpy as np
from sklearn.metrics import mean_absolute_error as mae, mean_squared_error as mse
from sklearn.exceptions import NotFittedError
from sklearn.pipeline import Pipeline
from piven.metrics.numpy import coverage, pi_width, piven_loss as piven_loss_numpy
from piven.utils import save_piven_model, load_piven_model
from piven.scikit_learn.compose import PivenTransformedTargetRegressor
from piven.scikit_learn.wrappers import PivenKerasRegressor


# Helper
def _ifelse(condition, val_if_true, val_if_false):
if condition:
return val_if_true
else:
return val_if_false


class PivenBaseModel(metaclass=abc.ABCMeta):
Expand All @@ -22,15 +33,52 @@ def __repr__(self):
return str(self.model)

def fit(self, x: np.ndarray, y: np.ndarray, **kwargs):
"""
Fit the piven model to data
Parameters
----------
x input data
y targets
kwargs any arguments passed to keras 'fit()' method
Returns python class of model
-------
"""
self.model.fit(x, y, **kwargs)
return self

def predict(self, x: np.ndarray, return_prediction_intervals: bool = True):
"""
Predict on (unseen) data
Parameters
----------
x input data
return_prediction_intervals flag indicating whether to return lower & upper prediction intervals
Returns either a numpy array with model predictions or a 3-dimensional array containing lower & upper
PI and point estimates.
-------
"""
if self.model is None:
raise NotFittedError("Model has not yet been fitted.")
return self.model.predict(x, return_prediction_intervals)

def save(self, path: str):
"""
Persist the model to disk
Parameters
----------
path directory in which the model should be saved.
Returns class instance
-------
"""
if self.model is None:
raise NotFittedError("Model has not yet been fitted.")
with (Path(path) / "experiment_params.json").open("w") as outfile:
Expand All @@ -42,12 +90,19 @@ def log(
self, x: np.ndarray, y: np.ndarray, path: str, model=True, predictions=True
):
"""
Log the results of an experiment to disk
:param x:
:param y:
:param path: directory in which to save results.
:param model: save model to disk if True.
:param predictions: save predictions to disk if True.
Log the results of the model and optionally the model and predictions to disk.
Parameters
----------
x input data
y targets
path directory in which to save the model, predictions and metrics.
model flag indicating whether to persist the model on disk.
predictions flag indicating whether to persist the predictions on disk.
Returns class instance
-------
"""
ppath = Path(path)
if not ppath.is_dir():
Expand Down Expand Up @@ -75,15 +130,35 @@ def score(
y_pi_low: np.ndarray,
y_pi_high: np.ndarray,
) -> Dict:
"""
Score the model on MAE, RMSE, % coverage and PI width.
Parameters
----------
y_true true target vaules
y_pred predicted target values
y_pi_low lower pi
y_pi_high upper pi
Returns dict containing metrics
-------
"""
return {
"loss": piven_loss_numpy(
y_true,
y_pred,
y_pi_low,
y_pi_high,
self.params.get("lambda_"),
160.0,
0.05,
_ifelse(
self.params.get("lambda_") is None, 25.0, self.params.get("lambda_")
),
_ifelse(
self.params.get("soften") is None, 160.0, self.params.get("soften")
),
_ifelse(
self.params.get("alpha") is None, 0.05, self.params.get("alpha")
),
),
"mae": mae(y_true, y_pred),
"rmse": np.sqrt(mse(y_true, y_pred)),
Expand All @@ -92,22 +167,39 @@ def score(
}

@staticmethod
def load_model_config(path: str):
def _load_model_config(path: str) -> Dict:
if not (Path(path) / "experiment_params.json").is_file():
raise FileNotFoundError(f"No experiment file found in {path}.")
with (Path(path) / "experiment_params.json").open("r") as infile:
params = json.load(infile)
return params

@staticmethod
def load_model_from_disk(build_fn: Callable, path: str):
def _load_model_from_disk(
build_fn: Callable, path: str
) -> Union[PivenTransformedTargetRegressor, PivenKerasRegressor, Pipeline]:
return load_piven_model(build_fn, path)

@abc.abstractmethod
def build(self, **build_params):
pass

@classmethod
def load(cls, path: str, build_fn: Callable):
"""
Load a piven-based model from disk
Parameters
----------
path directory in which the model files were saved
build_fn build function used to construct and compile the model
Returns piven-based model
-------
"""
model_config = cls._load_model_config(path)
model = cls._load_model_from_disk(build_fn, path)
run = cls(**model_config)
run.model = model
return model

@abc.abstractmethod
def load(cls, path: str):
def build(self, **build_params):
pass

0 comments on commit a1ec1cc

Please sign in to comment.