Skip to content
Merged
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ matrix:
- python: 3.9
name: "Py39-024+"
env:
- sklver=">=0.24.0"
- sklver=">=0.24.2"
- jlver=">=1.0"
- python: 3.8
name: "Py38-023"
Expand Down
7 changes: 4 additions & 3 deletions _doc/sphinxdoc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import sys
import os
import alabaster
from pyquickhelper.helpgen.default_conf import set_sphinx_variables, get_default_stylesheet
from pyquickhelper.helpgen.default_conf import set_sphinx_variables


sys.path.insert(0, os.path.abspath(os.path.join(os.path.split(__file__)[0])))
Expand All @@ -20,8 +20,9 @@
title="mlinsights", book=True)

blog_root = "http://www.xavierdupre.fr/app/mlinsights/helpsphinx/"
html_context = {'css_files': get_default_stylesheet() +
['_static/my-styles.css']}

html_css_files = ['my-styles.css']

html_logo = "phdoc_static/project_ico.png"
html_sidebars = {}
language = "en"
Expand Down
File renamed without changes
9 changes: 5 additions & 4 deletions _unittests/ut_mlmodel/test_categories_to_integers.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,11 @@ def test_categories_to_integers_grid_search(self):
LogisticRegression())
self.assertRaise(lambda: test_sklearn_grid_search_cv(
lambda: pipe, df), ValueError)
self.assertRaise(
lambda: test_sklearn_grid_search_cv(
lambda: pipe, X, y, categoriestointegers__single=[True, False]),
ValueError, "Unable to find category value")
if compare_module_version(sklver, "0.24") >= 0:
self.assertRaise(
lambda: test_sklearn_grid_search_cv(
lambda: pipe, X, y, categoriestointegers__single=[True, False]),
ValueError, "Unable to find category value")
pipe = make_pipeline(CategoriesToIntegers(),
Imputer(strategy='most_frequent'),
LogisticRegression(n_jobs=1))
Expand Down
7 changes: 6 additions & 1 deletion _unittests/ut_mlmodel/test_classification_kmeans.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@ def test_classification_kmeans_intercept_weights(self):
def test_classification_kmeans_pickle(self):
iris = datasets.load_iris()
X, y = iris.data, iris.target
test_sklearn_pickle(lambda: ClassifierAfterKMeans(), X, y)
try:
test_sklearn_pickle(lambda: ClassifierAfterKMeans(), X, y)
except AttributeError as e:
if compare_module_version(sklver, "0.24") < 0:
return
raise e

def test_classification_kmeans_clone(self):
self.maxDiff = None
Expand Down
19 changes: 19 additions & 0 deletions _unittests/ut_mlmodel/test_piecewise_regressor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from numpy.random import random
import pandas
from sklearn.linear_model import LinearRegression
from sklearn.datasets import make_regression
from sklearn.tree import DecisionTreeRegressor
from pyquickhelper.pycode import ExtTestCase, ignore_warnings
from mlinsights.mlmodel import test_sklearn_pickle, test_sklearn_clone, test_sklearn_grid_search_cv
from mlinsights.mlmodel.piecewise_estimator import PiecewiseRegressor
Expand Down Expand Up @@ -148,6 +150,23 @@ def test_piecewise_regressor_grid_search(self):
self.assertGreater(res['score'], 0)
self.assertLesser(res['score'], 1)

def test_piecewise_regressor_issue(self):
X, y = make_regression(10000, n_features=1, n_informative=1, # pylint: disable=W0632
n_targets=1)
y = y.reshape((-1, 1))
model = PiecewiseRegressor(
binner=DecisionTreeRegressor(min_samples_leaf=300))
model.fit(X, y)
vvc = model.predict(X)
self.assertEqual(vvc.shape, (X.shape[0], ))

def test_piecewise_regressor_raise(self):
X, y = make_regression(10000, n_features=2, n_informative=2, # pylint: disable=W0632
n_targets=2)
model = PiecewiseRegressor(
binner=DecisionTreeRegressor(min_samples_leaf=300))
self.assertRaise(lambda: model.fit(X, y), RuntimeError)


if __name__ == "__main__":
unittest.main()
2 changes: 1 addition & 1 deletion mlinsights/mlmodel/_kmeans_022.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from sklearn.utils.sparsefuncs_fast import assign_rows_csr # pylint: disable=W0611,E0611
try:
from sklearn.cluster._kmeans import _check_sample_weight
except ImportError:
except ImportError: # pragma: no cover
from sklearn.cluster._kmeans import (
_check_normalize_sample_weight as _check_sample_weight)
from sklearn.metrics.pairwise import pairwise_distances_argmin_min
Expand Down
3 changes: 2 additions & 1 deletion mlinsights/mlmodel/_kmeans_constraint_.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ def _compute_strategy_coefficient(distances, strategy, labels):
ar = numpy.arange(distances.shape[0])
dist = distances[ar, labels]
return distances - dist[:, numpy.newaxis]
raise ValueError("Unknwon strategy '{0}'.".format(strategy))
raise ValueError( # pragma: no cover
"Unknwon strategy '{0}'.".format(strategy))


def _randomize_index(index, weights):
Expand Down
2 changes: 1 addition & 1 deletion mlinsights/mlmodel/decision_tree_logreg.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ def _fit_parallel(self, X, y, sample_weight):

def _fit_perpendicular(self, X, y, sample_weight):
"Implements the perpendicular strategy."
raise NotImplementedError()
raise NotImplementedError() # pragma: no cover

def predict(self, X):
"""
Expand Down
7 changes: 4 additions & 3 deletions mlinsights/mlmodel/extended_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def _get_feature_names_poly(self, input_features=None):
input_features = ["x%d" %
i for i in range(0, self.n_input_features_)]
elif len(input_features) != self.n_input_features_:
raise ValueError(
raise ValueError( # pragma: no cover
"input_features should contain {} strings.".format(
self.n_input_features_))

Expand Down Expand Up @@ -125,7 +125,7 @@ def fit(self, X, y=None):
return self._fit_poly(X, y)
elif self.kind == 'poly-slow':
return self._fit_poly(X, y)
raise ValueError(
raise ValueError( # pragma: no cover
"Unknown extended features '{}'.".format(self.kind))

def _fit_poly(self, X, y=None):
Expand All @@ -148,7 +148,8 @@ def transform(self, X):
"""
n_features = X.shape[1]
if n_features != self.n_input_features_:
raise ValueError("X shape does not match training shape")
raise ValueError( # pragma: no cover
"X shape does not match training shape")
if self.kind == 'poly':
return self._transform_poly(X)
if self.kind == 'poly-slow':
Expand Down
8 changes: 7 additions & 1 deletion mlinsights/mlmodel/piecewise_estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from sklearn.utils.fixes import _joblib_parallel_args
try:
from tqdm import tqdm
except ImportError:
except ImportError: # pragma: no cover
pass


Expand Down Expand Up @@ -223,6 +223,12 @@ def fit(self, X, y, sample_weight=None):
* `dim_`: dimension of the output
* `mean_`: average targets
"""
if len(y.shape) == 2:
if y.shape[-1] == 1:
y = y.ravel()
else:
raise RuntimeError(
"This regressor only works with single dimension targets.")
if isinstance(X, pandas.DataFrame):
X = X.values
if isinstance(X, list):
Expand Down
2 changes: 2 additions & 0 deletions mlinsights/mlmodel/sklearn_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,8 @@ def test_sklearn_grid_search_cv(fct_model, X, y=None, sample_weight=None, **grid
clf = GridSearchCV(pipe, parameters)
if y_train is None and w_train is None:
clf.fit(X_train)
elif w_train is None:
clf.fit(X_train, y_train) # pylint: disable=E1121
else:
clf.fit(X_train, y_train, w_train) # pylint: disable=E1121
score = clf.score(X_test, y_test)
Expand Down
17 changes: 10 additions & 7 deletions mlinsights/mlmodel/sklearn_transform_inv_fct.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,13 @@ def __init__(self, fct, fct_inv=None):
BaseReciprocalTransformer.__init__(self)
if isinstance(fct, str):
if fct_inv is not None:
raise ValueError(
raise ValueError( # pragma: no cover
"If fct is a function name, fct_inv must not be specified.")
opts = self.__class__.available_fcts()
if fct not in opts:
raise ValueError("Unknown fct '{}', it should in {}.".format(
fct, list(sorted(opts))))
raise ValueError( # pragma: no cover
"Unknown fct '{}', it should in {}.".format(
fct, list(sorted(opts))))
else:
if fct_inv is None:
raise ValueError(
Expand Down Expand Up @@ -117,7 +118,8 @@ def fit(self, X=None, y=None, sample_weight=None):
Defines a random permutation over the targets.
"""
if y is None:
raise RuntimeError("targets cannot be empty.")
raise RuntimeError( # pragma: no cover
"targets cannot be empty.")
num = numpy.issubdtype(y.dtype, numpy.floating)
perm = {}
for u in y.ravel():
Expand All @@ -141,7 +143,7 @@ def fit(self, X=None, y=None, sample_weight=None):

def _check_is_fitted(self):
if not hasattr(self, 'permutation_'):
raise NotFittedError(
raise NotFittedError( # pragma: no cover
"This instance {} is not fitted yet. Call 'fit' with "
"appropriate arguments before using this method.".format(
type(self)))
Expand Down Expand Up @@ -169,8 +171,9 @@ def _find_closest(self, cl):
return float(res)
if self.knn_perm_.dtype in (numpy.int32, numpy.int64):
return int(res)
raise NotImplementedError("The function does not work for type {}.".format(
self.knn_perm_.dtype))
raise NotImplementedError( # pragma: no cover
"The function does not work for type {}.".format(
self.knn_perm_.dtype))

def transform(self, X, y):
"""
Expand Down
2 changes: 1 addition & 1 deletion mlinsights/mlmodel/target_predictors.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def predict(self, X):
Predicted values.
"""
if not hasattr(self, 'regressor_'):
raise NotFittedError(
raise NotFittedError( # pragma: no cover
"This instance {} is not fitted yet. Call 'fit' with "
"appropriate arguments before using this method.".format(
type(self)))
Expand Down
3 changes: 2 additions & 1 deletion mlinsights/mltree/tree_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ def _get_tree(obj):
return obj
if hasattr(obj, "tree_"):
return obj.tree_
raise AttributeError("obj is no tree: {}".format(type(obj)))
raise AttributeError( # pragma: no cover
"obj is no tree: {}".format(type(obj)))


def tree_leave_index(model):
Expand Down