Skip to content

Commit

Permalink
Add py311, remove py37 (#320)
Browse files Browse the repository at this point in the history
* Add py311, remove py37

* Fix minor linting errors on new pylint

* Fix types; remove comment

* Set seed for deterministic tests

* Fix types in test file

* Fix unused import; Use specific noqa codes; Fix typo in pre-commit config

* Fix type in tests

* Fix feature importance base case

* xfail test per #320

---------

Co-authored-by: Jack McIvor <j.mcivor@draftkings.com>
  • Loading branch information
jack-mcivor and Jack McIvor committed Jan 29, 2024
1 parent 07734dd commit c482aab
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10']
python-version: ['3.8', '3.9', '3.10', '3.11']

steps:
- uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ repos:
types: [file, python]
language: system
files: ^ngboost
entry: pylint --disable=invalid-name,no-member,missing-docstring,no-self-argument,arguments-differ,R0801
entry: pylint --disable=invalid-name,no-member,missing-docstring,no-self-argument,arguments-differ
- id: pylint-tests
name: pylint on tests*
language: system
Expand Down
6 changes: 4 additions & 2 deletions ngboost/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
# before python 3.8
from importlib_metadata import version

from .api import NGBClassifier, NGBRegressor, NGBSurvival # NOQA
from .ngboost import NGBoost # NOQA
from .api import NGBClassifier, NGBRegressor, NGBSurvival
from .ngboost import NGBoost

__all__ = ["NGBClassifier", "NGBRegressor", "NGBSurvival", "NGBoost"]

__version__ = version(__name__)
42 changes: 31 additions & 11 deletions ngboost/distns/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,32 @@
"""NGBoost distributions"""
from .categorical import Bernoulli, k_categorical # NOQA
from .cauchy import Cauchy # NOQA
from .distn import ClassificationDistn, Distn, RegressionDistn # NOQA
from .exponential import Exponential # NOQA
from .gamma import Gamma # NOQA
from .laplace import Laplace # NOQA
from .lognormal import LogNormal # NOQA
from .multivariate_normal import MultivariateNormal # NOQA
from .normal import Normal, NormalFixedVar # NOQA
from .poisson import Poisson # NOQA
from .t import T, TFixedDf, TFixedDfFixedVar # NOQA
from .categorical import Bernoulli, k_categorical
from .cauchy import Cauchy
from .distn import ClassificationDistn, Distn, RegressionDistn
from .exponential import Exponential
from .gamma import Gamma
from .laplace import Laplace
from .lognormal import LogNormal
from .multivariate_normal import MultivariateNormal
from .normal import Normal, NormalFixedVar
from .poisson import Poisson
from .t import T, TFixedDf, TFixedDfFixedVar

__all__ = [
"Bernoulli",
"k_categorical",
"Cauchy",
"ClassificationDistn",
"Distn",
"RegressionDistn",
"Exponential",
"Gamma",
"Laplace",
"LogNormal",
"MultivariateNormal",
"Normal",
"NormalFixedVar",
"Poisson",
"T",
"TFixedDf",
"TFixedDfFixedVar",
]
2 changes: 1 addition & 1 deletion ngboost/distns/categorical.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""The NGBoost categorial distribution and scores"""
# pylint: disable=invalid-unary-operand-type, unused-argument, no-self-use
# pylint: disable=invalid-unary-operand-type, unused-argument
import numpy as np
import scipy as sp

Expand Down
15 changes: 8 additions & 7 deletions ngboost/ngboost.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# pylint: disable=line-too-long,too-many-instance-attributes,too-many-arguments
# pylint: disable=unused-argument,too-many-locals,too-many-branches,too-many-statements
# pylint: disable=unused-variable,invalid-unary-operand-type,attribute-defined-outside-init
# pylint: disable=redundant-keyword-arg,protected-access
# pylint: disable=redundant-keyword-arg,protected-access,unnecessary-lambda-assignment
import numpy as np
from sklearn.base import clone
from sklearn.model_selection import train_test_split
Expand Down Expand Up @@ -362,14 +362,14 @@ def partial_fit(
best_val_loss = np.inf

if not train_loss_monitor:
train_loss_monitor = lambda D, Y, W: D.total_score( # NOQA
train_loss_monitor = lambda D, Y, W: D.total_score( # noqa: E731
Y, sample_weight=W
)

if not val_loss_monitor:
val_loss_monitor = lambda D, Y: D.total_score( # NOQA
val_loss_monitor = lambda D, Y: D.total_score( # noqa: E731
Y, sample_weight=val_sample_weight
) # NOQA
)

for itr in range(len(self.col_idxs), self.n_estimators + len(self.col_idxs)):
_, col_idx, X_batch, Y_batch, weight_batch, P_batch = self.sample(
Expand All @@ -386,7 +386,6 @@ def partial_fit(
proj_grad = self.fit_base(X_batch, grads, weight_batch)
scale = self.line_search(proj_grad, P_batch, Y_batch, weight_batch)

# pdb.set_trace()
params -= (
self.learning_rate
* scale
Expand Down Expand Up @@ -587,8 +586,10 @@ def feature_importances_(self):

if not all_params_importances:
return np.zeros(
len(self.base_models[0]),
self.base_models[0][0].n_features_,
(
len(self.base_models[0]),
self.base_models[0][0].n_features_,
),
dtype=np.float64,
)

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ classifiers = [
license = "Apache License 2.0"

[tool.poetry.dependencies]
python = ">=3.7.1, <3.11"
python = ">=3.8, <3.12"
scikit-learn = ">=1.0.2"
numpy = ">=1.21.2"
scipy = ">=1.7.2"
Expand Down
9 changes: 7 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from sklearn.datasets import fetch_california_housing, load_breast_cancer
from sklearn.model_selection import train_test_split

Tuple4Array = Tuple[np.array, np.array, np.array, np.array]
Tuple5Array = Tuple[np.array, np.array, np.array, np.array, np.array]
Tuple4Array = Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]
Tuple5Array = Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]


def pytest_addoption(parser):
Expand All @@ -22,6 +22,11 @@ def pytest_configure(config):
config.addinivalue_line("markers", "slow: ")


@pytest.fixture(scope="session", autouse=True)
def set_seed():
np.random.seed(0)


@pytest.fixture(scope="session")
def california_housing_data() -> Tuple4Array:
X, Y = fetch_california_housing(return_X_y=True)
Expand Down
9 changes: 9 additions & 0 deletions tests/test_distns.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ def classification_data():
return X_train, X_test, y_train, y_test


def is_t_distribution(
dist, learner, regression_data
): # pylint: disable=unused-argument
return dist == T


@pytest.mark.slow
@pytest.mark.parametrize(
"dist",
Expand All @@ -64,6 +70,9 @@ def classification_data():
DecisionTreeRegressor(criterion="friedman_mse", max_depth=5),
],
)
@pytest.mark.xfail(
condition=is_t_distribution, reason="Known to fail with T distribution"
)
def test_dists_runs_on_examples_logscore(dist: Distn, learner, regression_data):
X_train, X_test, y_train, y_test = regression_data
# TODO: test early stopping features
Expand Down
1 change: 1 addition & 0 deletions tests/test_score.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# pylint: disable=unnecessary-lambda-assignment
from typing import List, Tuple

import numpy as np
Expand Down

0 comments on commit c482aab

Please sign in to comment.