Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
pyodide
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
pyodide
Commits
edda6eef
Commit
edda6eef
authored
Nov 06, 2018
by
Roman Yurchak
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More fixes for joblib
parent
b93fcc47
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
513 additions
and
65 deletions
+513
-65
.circleci/config.yml
.circleci/config.yml
+2
-2
packages/scikit-learn/meta.yaml
packages/scikit-learn/meta.yaml
+31
-1
packages/scikit-learn/patches/support-joblib-011.patch
packages/scikit-learn/patches/support-joblib-011.patch
+360
-0
packages/scikit-learn/patches/use-site-joblib.patch
packages/scikit-learn/patches/use-site-joblib.patch
+114
-4
test/packages/test_scikit-learn.py
test/packages/test_scikit-learn.py
+6
-58
No files found.
.circleci/config.yml
View file @
edda6eef
...
@@ -27,8 +27,8 @@ jobs:
...
@@ -27,8 +27,8 @@ jobs:
# download scipy package from https://github.com/iodide-project/pyodide/pull/211
# download scipy package from https://github.com/iodide-project/pyodide/pull/211
mkdir -p build
mkdir -p build
wget -q -O build/scipy.js https://1
463
-122663163-gh.circle-artifacts.com/0/home/circleci/repo/build/scipy.js
wget -q -O build/scipy.js https://1
535
-122663163-gh.circle-artifacts.com/0/home/circleci/repo/build/scipy.js
wget -q -O build/scipy.data https://1
463
-122663163-gh.circle-artifacts.com/0/home/circleci/repo/build/scipy.data
wget -q -O build/scipy.data https://1
535
-122663163-gh.circle-artifacts.com/0/home/circleci/repo/build/scipy.data
ccache -z
ccache -z
make
make
...
...
packages/scikit-learn/meta.yaml
View file @
edda6eef
...
@@ -7,8 +7,8 @@ source:
...
@@ -7,8 +7,8 @@ source:
sha256
:
97d1d971f8ec257011e64b7d655df68081dd3097322690afa1a71a1d755f8c18
sha256
:
97d1d971f8ec257011e64b7d655df68081dd3097322690afa1a71a1d755f8c18
patches
:
patches
:
#- patches/unvendor-joblib.patch
-
patches/use-site-joblib.patch
-
patches/use-site-joblib.patch
-
patches/support-joblib-011.patch
build
:
build
:
cflags
:
-Wno-implicit-function-declaration
cflags
:
-Wno-implicit-function-declaration
...
@@ -21,9 +21,39 @@ requirements:
...
@@ -21,9 +21,39 @@ requirements:
test
:
test
:
imports
:
imports
:
-
sklearn
-
sklearn
-
sklearn.calibration
-
sklearn.cluster
-
sklearn.cluster
-
sklearn.compose
-
sklearn.compose
-
sklearn.covariance
-
sklearn.covariance
-
sklearn.cross_decomposition
-
sklearn.cross_decomposition
-
sklearn.datasets
-
sklearn.datasets
-
sklearn.decomposition
-
sklearn.decomposition
-
sklearn.discriminant_analysis
-
sklearn.dummy
-
sklearn.ensemble
-
sklearn.exceptions
-
sklearn.externals
-
sklearn.feature_extraction
-
sklearn.feature_selection
-
sklearn.gaussian_process
-
sklearn.impute
-
sklearn.isotonic
-
sklearn.kernel_approximation
-
sklearn.kernel_ridge
-
sklearn.linear_model
-
sklearn.manifold
-
sklearn.metrics
-
sklearn.mixture
-
sklearn.model_selection
-
sklearn.multiclass
-
sklearn.multioutput
-
sklearn.naive_bayes
-
sklearn.neighbors
-
sklearn.neural_network
-
sklearn.pipeline
-
sklearn.preprocessing
-
sklearn.random_projection
-
sklearn.semi_supervised
-
sklearn.svm
-
sklearn.tree
-
sklearn.utils
packages/scikit-learn/patches/support-joblib-011.patch
0 → 100644
View file @
edda6eef
commit 09954a12bdcef544e940a9b4f661dd7210e2357d
Author: Joel Nothman <joel.nothman@gmail.com>
Date: Wed Nov 7 08:10:23 2018 +1100
BLD we should ensure continued support for joblib 0.11 (#12350)
diff --git a/sklearn/ensemble/forest.py b/sklearn/ensemble/forest.py
index 542f7ca80..e54f131a4 100644
--- a/sklearn/ensemble/forest.py
+++ b/sklearn/ensemble/forest.py
@@ -50,7 +50,6 @@
import numpy as np
from scipy.sparse import issparse
from scipy.sparse import hstack as sparse_hstack
-
from ..base import ClassifierMixin, RegressorMixin
from ..utils import Parallel, delayed
from ..externals import six
@@ -62,7 +61,7 @@
from ..tree._tree import DTYPE, DOUBLE
from ..utils import check_random_state, check_array, compute_sample_weight
from ..exceptions import DataConversionWarning, NotFittedError
from .base import BaseEnsemble, _partition_estimators
-from ..utils.fixes import parallel_helper
+from ..utils.fixes import parallel_helper, _joblib_parallel_args
from ..utils.multiclass import check_classification_targets
from ..utils.validation import check_is_fitted
@@ -175,7 +174,7 @@
class BaseForest(six.with_metaclass(ABCMeta, BaseEnsemble)):
"""
X = self._validate_X_predict(X)
results = Parallel(n_jobs=self.n_jobs, verbose=self.verbose,
- prefer="threads")(
+ **_joblib_parallel_args(prefer="threads"))(
delayed(parallel_helper)(tree, 'apply', X, check_input=False)
for tree in self.estimators_)
@@ -206,7 +205,7 @@
class BaseForest(six.with_metaclass(ABCMeta, BaseEnsemble)):
"""
X = self._validate_X_predict(X)
indicators = Parallel(n_jobs=self.n_jobs, verbose=self.verbose,
- prefer="threads")(
+ **_joblib_parallel_args(prefer='threads'))(
delayed(parallel_helper)(tree, 'decision_path', X,
check_input=False)
for tree in self.estimators_)
@@ -324,11 +323,11 @@
class BaseForest(six.with_metaclass(ABCMeta, BaseEnsemble)):
# Parallel loop: we prefer the threading backend as the Cython code
# for fitting the trees is internally releasing the Python GIL
# making threading more efficient than multiprocessing in
- # that case. However, we respect any parallel_backend contexts set
- # at a higher level, since correctness does not rely on using
- # threads.
+ # that case. However, for joblib 0.12+ we respect any
+ # parallel_backend contexts set at a higher level,
+ # since correctness does not rely on using threads.
trees = Parallel(n_jobs=self.n_jobs, verbose=self.verbose,
- prefer="threads")(
+ **_joblib_parallel_args(prefer='threads'))(
delayed(_parallel_build_trees)(
t, self, X, y, sample_weight, i, len(trees),
verbose=self.verbose, class_weight=self.class_weight)
@@ -375,7 +374,7 @@
class BaseForest(six.with_metaclass(ABCMeta, BaseEnsemble)):
check_is_fitted(self, 'estimators_')
all_importances = Parallel(n_jobs=self.n_jobs,
- prefer="threads")(
+ **_joblib_parallel_args(prefer='threads'))(
delayed(getattr)(tree, 'feature_importances_')
for tree in self.estimators_)
@@ -591,7 +590,8 @@
class ForestClassifier(six.with_metaclass(ABCMeta, BaseForest,
all_proba = [np.zeros((X.shape[0], j), dtype=np.float64)
for j in np.atleast_1d(self.n_classes_)]
lock = threading.Lock()
- Parallel(n_jobs=n_jobs, verbose=self.verbose, require="sharedmem")(
+ Parallel(n_jobs=n_jobs, verbose=self.verbose,
+ **_joblib_parallel_args(require="sharedmem"))(
delayed(_accumulate_prediction)(e.predict_proba, X, all_proba,
lock)
for e in self.estimators_)
@@ -699,7 +699,8 @@
class ForestRegressor(six.with_metaclass(ABCMeta, BaseForest, RegressorMixin)):
# Parallel loop
lock = threading.Lock()
- Parallel(n_jobs=n_jobs, verbose=self.verbose, require="sharedmem")(
+ Parallel(n_jobs=n_jobs, verbose=self.verbose,
+ **_joblib_parallel_args(require="sharedmem"))(
delayed(_accumulate_prediction)(e.predict, X, [y_hat], lock)
for e in self.estimators_)
diff --git a/sklearn/ensemble/tests/test_forest.py b/sklearn/ensemble/tests/test_forest.py
index f12f6f886..c08e5cc32 100644
--- a/sklearn/ensemble/tests/test_forest.py
+++ b/sklearn/ensemble/tests/test_forest.py
@@ -10,6 +10,7 @@
Testing for the forest module (sklearn.ensemble.forest).
import pickle
from collections import defaultdict
+from distutils.version import LooseVersion
import itertools
from itertools import combinations
from itertools import product
@@ -21,6 +22,7 @@
from scipy.sparse import coo_matrix
import pytest
+from sklearn.utils import _joblib
from sklearn.utils import parallel_backend
from sklearn.utils import register_parallel_backend
try:
@@ -1287,6 +1289,8 @@
class MyBackend(LokyBackend):
register_parallel_backend('testing', MyBackend)
+@pytest.mark.skipif(_joblib.__version__ < LooseVersion('0.12'),
+ reason='tests not yet supported in joblib <0.12')
def test_backend_respected():
clf = RandomForestClassifier(n_estimators=10, n_jobs=2)
diff --git a/sklearn/linear_model/coordinate_descent.py b/sklearn/linear_model/coordinate_descent.py
index 2d0723944..4d0ded532 100644
--- a/sklearn/linear_model/coordinate_descent.py
+++ b/sklearn/linear_model/coordinate_descent.py
@@ -22,6 +22,7 @@
from ..utils import Parallel, delayed, effective_n_jobs
from ..externals import six
from ..externals.six.moves import xrange
from ..utils.extmath import safe_sparse_dot
+from ..utils.fixes import _joblib_parallel_args
from ..utils.validation import check_is_fitted
from ..utils.validation import column_or_1d
from ..exceptions import ConvergenceWarning
@@ -1203,7 +1204,7 @@
class LinearModelCV(six.with_metaclass(ABCMeta, LinearModel)):
for this_l1_ratio, this_alphas in zip(l1_ratios, alphas)
for train, test in folds)
mse_paths = Parallel(n_jobs=self.n_jobs, verbose=self.verbose,
- prefer="threads")(jobs)
+ **_joblib_parallel_args(prefer="threads"))(jobs)
mse_paths = np.reshape(mse_paths, (n_l1_ratio, len(folds), -1))
mean_mse = np.mean(mse_paths, axis=1)
self.mse_path_ = np.squeeze(np.rollaxis(mse_paths, 2, 1))
diff --git a/sklearn/linear_model/logistic.py b/sklearn/linear_model/logistic.py
index 01a4f78ab..091c13c1f 100644
--- a/sklearn/linear_model/logistic.py
+++ b/sklearn/linear_model/logistic.py
@@ -33,6 +33,7 @@
from ..exceptions import (NotFittedError, ConvergenceWarning,
ChangedBehaviorWarning)
from ..utils.multiclass import check_classification_targets
from ..utils import Parallel, delayed, effective_n_jobs
+from ..utils.fixes import _joblib_parallel_args
from ..model_selection import check_cv
from ..externals import six
from ..metrics import get_scorer
@@ -1346,7 +1347,7 @@
class LogisticRegression(BaseEstimator, LinearClassifierMixin,
else:
prefer = 'processes'
fold_coefs_ = Parallel(n_jobs=self.n_jobs, verbose=self.verbose,
- prefer=prefer)(
+ **_joblib_parallel_args(prefer=prefer))(
path_func(X, y, pos_class=class_, Cs=[self.C],
fit_intercept=self.fit_intercept, tol=self.tol,
verbose=self.verbose, solver=solver,
@@ -1775,7 +1776,7 @@
class LogisticRegressionCV(LogisticRegression, BaseEstimator,
else:
prefer = 'processes'
fold_coefs_ = Parallel(n_jobs=self.n_jobs, verbose=self.verbose,
- prefer=prefer)(
+ **_joblib_parallel_args(prefer=prefer))(
path_func(X, y, train, test, pos_class=label, Cs=self.Cs,
fit_intercept=self.fit_intercept, penalty=self.penalty,
dual=self.dual, solver=solver, tol=self.tol,
diff --git a/sklearn/linear_model/stochastic_gradient.py b/sklearn/linear_model/stochastic_gradient.py
index 5e253003a..236bc10a9 100644
--- a/sklearn/linear_model/stochastic_gradient.py
+++ b/sklearn/linear_model/stochastic_gradient.py
@@ -33,6 +33,7 @@
from .sgd_fast import SquaredLoss
from .sgd_fast import Huber
from .sgd_fast import EpsilonInsensitive
from .sgd_fast import SquaredEpsilonInsensitive
+from ..utils.fixes import _joblib_parallel_args
LEARNING_RATE_TYPES = {"constant": 1, "optimal": 2, "invscaling": 3,
"adaptive": 4, "pa1": 5, "pa2": 6}
@@ -613,8 +614,8 @@
class BaseSGDClassifier(six.with_metaclass(ABCMeta, BaseSGD,
strategy is called OVA: One Versus All.
"""
# Use joblib to fit OvA in parallel.
- result = Parallel(n_jobs=self.n_jobs, prefer="threads",
- verbose=self.verbose)(
+ result = Parallel(n_jobs=self.n_jobs, verbose=self.verbose,
+ **_joblib_parallel_args(require="sharedmem"))(
delayed(fit_binary)(self, i, X, y, alpha, C, learning_rate,
max_iter, self._expanded_class_weight[i],
1., sample_weight)
diff --git a/sklearn/linear_model/tests/test_sgd.py b/sklearn/linear_model/tests/test_sgd.py
index 15e29ce4d..7ad29e2c0 100644
--- a/sklearn/linear_model/tests/test_sgd.py
+++ b/sklearn/linear_model/tests/test_sgd.py
@@ -1,4 +1,5 @@
+from distutils.version import LooseVersion
import pickle
import unittest
import pytest
@@ -28,6 +29,13 @@
from sklearn.preprocessing import StandardScaler
from sklearn.exceptions import ConvergenceWarning
from sklearn.model_selection import train_test_split
from sklearn.linear_model import sgd_fast
+from sklearn.model_selection import RandomizedSearchCV
+from sklearn.utils import _joblib
+
+
+# 0.23. warning about tol not having its correct default value.
+pytestmark = pytest.mark.filterwarnings(
+ "ignore:max_iter and tol parameters have been")
class SparseSGDClassifier(SGDClassifier):
@@ -1471,3 +1479,31 @@
def test_gradient_squared_epsilon_insensitive():
(2.0, 2.2, -0.2), (-2.0, 1.0, -5.8)
]
_test_gradient_common(loss, cases)
+
+
+def test_multi_thread_multi_class_and_early_stopping():
+ # This is a non-regression test for a bad interaction between
+ # early stopping internal attribute and thread-based parallelism.
+ clf = SGDClassifier(alpha=1e-3, tol=1e-3, max_iter=1000,
+ early_stopping=True, n_iter_no_change=100,
+ random_state=0, n_jobs=2)
+ clf.fit(iris.data, iris.target)
+ assert clf.n_iter_ > clf.n_iter_no_change
+ assert clf.n_iter_ < clf.n_iter_no_change + 20
+ assert clf.score(iris.data, iris.target) > 0.8
+
+
+def test_multi_core_gridsearch_and_early_stopping():
+ # This is a non-regression test for a bad interaction between
+ # early stopping internal attribute and process-based multi-core
+ # parallelism.
+ param_grid = {
+ 'alpha': np.logspace(-4, 4, 9),
+ 'n_iter_no_change': [5, 10, 50],
+ }
+ clf = SGDClassifier(tol=1e-3, max_iter=1000, early_stopping=True,
+ random_state=0)
+ search = RandomizedSearchCV(clf, param_grid, n_iter=10, cv=5, n_jobs=2,
+ random_state=0)
+ search.fit(iris.data, iris.target)
+ assert search.best_score_ > 0.8
diff --git a/sklearn/utils/fixes.py b/sklearn/utils/fixes.py
index 070afbdbb..24554fe68 100644
--- a/sklearn/utils/fixes.py
+++ b/sklearn/utils/fixes.py
@@ -14,6 +14,8 @@
import os
import errno
import sys
+from distutils.version import LooseVersion
+
import numpy as np
import scipy.sparse as sp
import scipy
@@ -332,3 +334,51 @@
except ImportError: # python <3.3
from collections import Iterable as _Iterable # noqa
from collections import Mapping as _Mapping # noqa
from collections import Sized as _Sized # noqa
+
+
+def _joblib_parallel_args(**kwargs):
+ """Set joblib.Parallel arguments in a compatible way for 0.11 and 0.12+
+
+ For joblib 0.11 this maps both ``prefer`` and ``require`` parameters to
+ a specific ``backend``.
+
+ Parameters
+ ----------
+
+ prefer : str in {'processes', 'threads'} or None
+ Soft hint to choose the default backend if no specific backend
+ was selected with the parallel_backend context manager.
+
+ require : 'sharedmem' or None
+ Hard condstraint to select the backend. If set to 'sharedmem',
+ the selected backend will be single-host and thread-based even
+ if the user asked for a non-thread based backend with
+ parallel_backend.
+
+ See joblib.Parallel documentation for more details
+ """
+ from . import _joblib
+
+ if _joblib.__version__ >= LooseVersion('0.12'):
+ return kwargs
+
+ extra_args = set(kwargs.keys()).difference({'prefer', 'require'})
+ if extra_args:
+ raise NotImplementedError('unhandled arguments %s with joblib %s'
+ % (list(extra_args), _joblib.__version__))
+ args = {}
+ if 'prefer' in kwargs:
+ prefer = kwargs['prefer']
+ if prefer not in ['threads', 'processes', None]:
+ raise ValueError('prefer=%s is not supported' % prefer)
+ args['backend'] = {'threads': 'threading',
+ 'processes': 'multiprocessing',
+ None: None}[prefer]
+
+ if 'require' in kwargs:
+ require = kwargs['require']
+ if require not in [None, 'sharedmem']:
+ raise ValueError('require=%s is not supported' % require)
+ if require == 'sharedmem':
+ args['backend'] = 'threading'
+ return args
diff --git a/sklearn/utils/tests/test_fixes.py b/sklearn/utils/tests/test_fixes.py
index 92f954439..5b7b960fa 100644
--- a/sklearn/utils/tests/test_fixes.py
+++ b/sklearn/utils/tests/test_fixes.py
@@ -16,6 +16,7 @@
from sklearn.utils.fixes import divide
from sklearn.utils.fixes import MaskedArray
from sklearn.utils.fixes import nanmedian
from sklearn.utils.fixes import nanpercentile
+from sklearn.utils.fixes import _joblib_parallel_args
def test_divide():
@@ -57,3 +58,33 @@
def test_nanmedian(axis, expected_median):
def test_nanpercentile(a, q, expected_percentile):
percentile = nanpercentile(a, q)
assert_allclose(percentile, expected_percentile)
+
+
+@pytest.mark.parametrize('joblib_version', ('0.11', '0.12.0'))
+def test_joblib_parallel_args(monkeypatch, joblib_version):
+ import sklearn.utils._joblib
+ monkeypatch.setattr(sklearn.utils._joblib, '__version__', joblib_version)
+
+ if joblib_version == '0.12.0':
+ # arguments are simply passed through
+ assert _joblib_parallel_args(prefer='threads') == {'prefer': 'threads'}
+ assert _joblib_parallel_args(prefer='processes', require=None) == {
+ 'prefer': 'processes', 'require': None}
+ assert _joblib_parallel_args(non_existing=1) == {'non_existing': 1}
+ elif joblib_version == '0.11':
+ # arguments are mapped to the corresponding backend
+ assert _joblib_parallel_args(prefer='threads') == {
+ 'backend': 'threading'}
+ assert _joblib_parallel_args(prefer='processes') == {
+ 'backend': 'multiprocessing'}
+ with pytest.raises(ValueError):
+ _joblib_parallel_args(prefer='invalid')
+ assert _joblib_parallel_args(
+ prefer='processes', require='sharedmem') == {
+ 'backend': 'threading'}
+ with pytest.raises(ValueError):
+ _joblib_parallel_args(require='invalid')
+ with pytest.raises(NotImplementedError):
+ _joblib_parallel_args(verbose=True)
+ else:
+ raise ValueError
packages/scikit-learn/patches/use-site-joblib.patch
View file @
edda6eef
commit
16cf9dc5f79533a121a421b095b6e7ef9ee76e9c
commit
8778fe57c37a275fc36959e9bade234bd9bbe88f
Author: Roman Yurchak <rth.yurchak@pm.me>
Author: Roman Yurchak <rth.yurchak@pm.me>
Date: Thu Oct 25 16:56:54 2018 +0200
Date: Thu Oct 25 16:56:54 2018 +0200
Use site joblib
Use site joblib
diff --git a/sklearn/datasets/california_housing.py b/sklearn/datasets/california_housing.py
index 76cb27dad..98cb34f6e 100644
--- a/sklearn/datasets/california_housing.py
+++ b/sklearn/datasets/california_housing.py
@@ -33,7 +33,7 @@
from .base import _fetch_remote
from .base import _pkl_filepath
from .base import RemoteFileMetadata
from ..utils import Bunch
-from ..externals import joblib
+from ..utils import _joblib as _joblib
# The original data can be found at:
# http://www.dcc.fc.up.pt/~ltorgo/Regression/cal_housing.tgz
diff --git a/sklearn/datasets/covtype.py b/sklearn/datasets/covtype.py
index a08f61f02..4ac93f93f 100644
--- a/sklearn/datasets/covtype.py
+++ b/sklearn/datasets/covtype.py
@@ -27,7 +27,7 @@
from .base import RemoteFileMetadata
from ..utils import Bunch
from .base import _pkl_filepath
from ..utils.fixes import makedirs
-from ..externals import joblib
+from ..utils import _joblib as joblib
from ..utils import check_random_state
# The original data can be found in:
diff --git a/sklearn/datasets/kddcup99.py b/sklearn/datasets/kddcup99.py
index c8ed0e308..3aa6ebb35 100644
--- a/sklearn/datasets/kddcup99.py
+++ b/sklearn/datasets/kddcup99.py
@@ -22,7 +22,8 @@
from .base import _fetch_remote
from .base import get_data_home
from .base import RemoteFileMetadata
from ..utils import Bunch
-from ..externals import joblib, six
+from ..externals import six
+from ..utils import _joblib as joblib
from ..utils import check_random_state
from ..utils import shuffle as shuffle_method
diff --git a/sklearn/datasets/olivetti_faces.py b/sklearn/datasets/olivetti_faces.py
index 74915c6c6..ba5bfecfb 100644
--- a/sklearn/datasets/olivetti_faces.py
+++ b/sklearn/datasets/olivetti_faces.py
@@ -24,7 +24,7 @@
from .base import _fetch_remote
from .base import RemoteFileMetadata
from .base import _pkl_filepath
from ..utils import check_random_state, Bunch
-from ..externals import joblib
+from ..utils import _joblib as joblib
# The original data can be found at:
# http://cs.nyu.edu/~roweis/data/olivettifaces.mat
diff --git a/sklearn/datasets/rcv1.py b/sklearn/datasets/rcv1.py
index 7890d7e18..ea22fb076 100644
--- a/sklearn/datasets/rcv1.py
+++ b/sklearn/datasets/rcv1.py
@@ -22,7 +22,7 @@
from .base import _pkl_filepath
from .base import _fetch_remote
from .base import RemoteFileMetadata
from ..utils.fixes import makedirs
-from ..externals import joblib
+from ..utils import _joblib as joblib
from .svmlight_format import load_svmlight_files
from ..utils import shuffle as shuffle_
from ..utils import Bunch
diff --git a/sklearn/datasets/species_distributions.py b/sklearn/datasets/species_distributions.py
diff --git a/sklearn/datasets/species_distributions.py b/sklearn/datasets/species_distributions.py
index 6d8acddcc..8191048d7 100644
index 6d8acddcc..8191048d7 100644
--- a/sklearn/datasets/species_distributions.py
--- a/sklearn/datasets/species_distributions.py
...
@@ -17,17 +83,48 @@ index 6d8acddcc..8191048d7 100644
...
@@ -17,17 +83,48 @@ index 6d8acddcc..8191048d7 100644
PY3_OR_LATER = sys.version_info[0] >= 3
PY3_OR_LATER = sys.version_info[0] >= 3
diff --git a/sklearn/datasets/twenty_newsgroups.py b/sklearn/datasets/twenty_newsgroups.py
index 8df908a2e..a2440222a 100644
--- a/sklearn/datasets/twenty_newsgroups.py
+++ b/sklearn/datasets/twenty_newsgroups.py
@@ -45,7 +45,7 @@
from ..utils import check_random_state, Bunch
from ..utils import deprecated
from ..feature_extraction.text import CountVectorizer
from ..preprocessing import normalize
-from ..externals import joblib
+from ..utils import _joblib as joblib
logger = logging.getLogger(__name__)
diff --git a/sklearn/ensemble/base.py b/sklearn/ensemble/base.py
index 321031892..2a516619b 100644
--- a/sklearn/ensemble/base.py
+++ b/sklearn/ensemble/base.py
@@ -13,9 +13,11 @@
from ..base import BaseEstimator
from ..base import MetaEstimatorMixin
from ..utils import check_random_state
from ..externals import six
-from ..externals.joblib import effective_n_jobs
+from ..utils import _joblib
from abc import ABCMeta, abstractmethod
+effective_n_jobs = _joblib.effective_n_jobs
+
MAX_RAND_SEED = np.iinfo(np.int32).max
diff --git a/sklearn/ensemble/tests/test_forest.py b/sklearn/ensemble/tests/test_forest.py
diff --git a/sklearn/ensemble/tests/test_forest.py b/sklearn/ensemble/tests/test_forest.py
index d7586c286..
d1168cdcf
100644
index d7586c286..
f12f6f886
100644
--- a/sklearn/ensemble/tests/test_forest.py
--- a/sklearn/ensemble/tests/test_forest.py
+++ b/sklearn/ensemble/tests/test_forest.py
+++ b/sklearn/ensemble/tests/test_forest.py
@@ -23,7 +23,1
1
@@
import pytest
@@ -23,7 +23,1
2
@@
import pytest
from sklearn.utils import parallel_backend
from sklearn.utils import parallel_backend
from sklearn.utils import register_parallel_backend
from sklearn.utils import register_parallel_backend
-from sklearn.externals.joblib.parallel import LokyBackend
-from sklearn.externals.joblib.parallel import LokyBackend
+try:
+try:
+ from sklearn.externals.joblib.parallel import LokyBackend
+ from sklearn.utils import _joblib
+ LokyBackend = _joblib.parallel.LokyBackend
+except ImportError:
+except ImportError:
+ LokyBackend = object
+ LokyBackend = object
+
+
...
@@ -76,6 +173,19 @@ index bffd43cc1..df4c96893 100644
...
@@ -76,6 +173,19 @@ index bffd43cc1..df4c96893 100644
from sklearn.utils import Parallel, delayed, Memory, parallel_backend
from sklearn.utils import Parallel, delayed, Memory, parallel_backend
if os.environ.get('SKLEARN_SITE_JOBLIB', False):
if os.environ.get('SKLEARN_SITE_JOBLIB', False):
diff --git a/sklearn/utils/_joblib.py b/sklearn/utils/_joblib.py
index e1c39a401..9c4e815f7 100644
--- a/sklearn/utils/_joblib.py
+++ b/sklearn/utils/_joblib.py
@@ -5,7 +5,7 @@
import os as _os
import warnings as _warnings
# An environment variable to use the site joblib
-if _os.environ.get('SKLEARN_SITE_JOBLIB', False):
+if True:
with _warnings.catch_warnings():
_warnings.simplefilter("ignore")
# joblib imports may raise DeprecationWarning on certain Python
diff --git a/sklearn/utils/testing.py b/sklearn/utils/testing.py
diff --git a/sklearn/utils/testing.py b/sklearn/utils/testing.py
index 75b378961..b81b9ab58 100644
index 75b378961..b81b9ab58 100644
--- a/sklearn/utils/testing.py
--- a/sklearn/utils/testing.py
...
...
test/packages/test_scikit-learn.py
View file @
edda6eef
from
textwrap
import
deden
t
import
pytes
t
def
test_scikit_learn
(
selenium_standalone
):
def
test_scikit_learn
(
selenium_standalone
,
request
):
selenium
=
selenium_standalone
selenium
=
selenium_standalone
if
selenium
.
browser
==
'chrome'
:
request
.
applymarker
(
pytest
.
mark
.
xfail
(
run
=
False
,
reason
=
'chrome not supported'
))
# no automatic depedency resolution for now
# no automatic depedency resolution for now
selenium
.
load_package
([
"numpy"
,
"joblib"
])
selenium
.
load_package
([
"numpy"
,
"joblib"
])
selenium
.
load_package
(
"scipy"
)
selenium
.
load_package
(
"scipy"
)
...
@@ -20,59 +24,3 @@ def test_scikit_learn(selenium_standalone):
...
@@ -20,59 +24,3 @@ def test_scikit_learn(selenium_standalone):
print(estimator.predict(X))
print(estimator.predict(X))
estimator.score(X, y)
estimator.score(X, y)
"""
)
>
0
"""
)
>
0
print
(
selenium
.
logs
)
def
test_import
(
selenium_standalone
):
selenium
=
selenium_standalone
# no automatic depedency resolution for now
selenium
.
load_package
([
"numpy"
,
"joblib"
])
selenium
.
load_package
(
"scipy"
)
selenium
.
load_package
(
"scikit-learn"
)
cmd
=
dedent
(
"""
import sklearn
import sklearn.calibration
import sklearn.calibration
import sklearn.cluster
import sklearn.compose
import sklearn.covariance
import sklearn.cross_decomposition
import sklearn.datasets
import sklearn.decomposition
import sklearn.discriminant_analysis
import sklearn.dummy
import sklearn.ensemble
import sklearn.exceptions
import sklearn.externals
import sklearn.feature_extraction
import sklearn.feature_selection
import sklearn.gaussian_process
import sklearn.impute
import sklearn.isotonic
import sklearn.kernel_approximation
import sklearn.kernel_ridge
import sklearn.linear_model
import sklearn.manifold
import sklearn.metrics
import sklearn.mixture
import sklearn.model_selection
import sklearn.multiclass
import sklearn.multioutput
import sklearn.naive_bayes
import sklearn.neighbors
import sklearn.neural_network
import sklearn.pipeline
import sklearn.preprocessing
import sklearn.random_projection
import sklearn.semi_supervised
import sklearn.svm
import sklearn.tree
import sklearn.utils
"""
).
splitlines
()
for
line
in
cmd
:
try
:
selenium
.
run
(
line
)
print
(
f'
{
line
}
-- OK'
)
except
:
print
(
f'Error:
{
line
}
failed'
)
print
(
selenium
.
logs
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment