8000 [MRG] Fix LinearModelsCV for loky backend. (#14264) · viclafargue/scikit-learn@14c9b8c · GitHub
[go: up one dir, main page]

Skip to content

Commit 14c9b8c

Browse files
jeremiedbbviclafargue
authored andcommitted
[MRG] Fix LinearModelsCV for loky backend. (scikit-learn#14264)
1 parent bf87f87 commit 14c9b8c

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

doc/whats_new/v0.23.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,12 @@ Changelog
384384
of non-zero coefficients and in the predicted output. :pr:`16849` by
385385
`Nicolas Hug`_.
386386

387+
- |Fix| Fixed a bug in :class:`linear_model.ElasticNetCV`,
388+
:class:`linear_model.MultitaskElasticNetCV`, :class:`linear_model.LassoCV`
389+
and :class:`linear_model.MultitaskLassoCV` where fitting would fail when
390+
using joblib loky backend. :pr:`14264` by
391+
:user:`Jérémie du Boisberranger <jeremiedbb>`.
392+
387393
:mod:`sklearn.metrics`
388394
......................
389395

sklearn/linear_model/_coordinate_descent.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,6 +1068,15 @@ def _path_residuals(X, y, train, test, path, path_params, alphas=None,
10681068
y_train = y[train]
10691069
X_test = X[test]
10701070
y_test = y[test]
1071+
1072+
if not sparse.issparse(X):
1073+
for array, array_input in ((X_train, X), (y_train, y),
1074+
(X_test, X), (y_test, y)):
1075+
if array.base is not array_input and not array.flags['WRITEABLE']:
1076+
# fancy indexing should create a writable copy but it doesn't
1077+
# for read-only memmaps (cf. numpy#14132).
1078+
array.setflags(write=True)
1079+
10711080
fit_intercept = path_params['fit_intercept']
10721081
normalize = path_params['normalize']
10731082

sklearn/linear_model/tests/test_coordinate_descent.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77
import pytest
88
from scipy import interpolate, sparse
99
from copy import deepcopy
10+
import joblib
11+
from distutils.version import LooseVersion
1012

1113
from sklearn.datasets import load_boston
14+
from sklearn.datasets import make_regression
1215
from sklearn.exceptions import ConvergenceWarning
1316
from sklearn.utils._testing import assert_array_almost_equal
1417
from sklearn.utils._testing import assert_almost_equal
@@ -1020,3 +1023,23 @@ def test_enet_sample_weight_sparse():
10201023
with pytest.raises(ValueError, match="Sample weights do not.*support "
10211024
"sparse matrices"):
10221025
reg.fit(X, y, sample_weight=sw, check_input=True)
1026+
1027+
1028+
@pytest.mark.parametrize("backend", ["loky", "threading"])
1029+
@pytest.mark.parametrize("estimator",
1030+
[ElasticNetCV, MultiTaskElasticNetCV,
1031+
LassoCV, MultiTaskLassoCV])
1032+
def test_linear_models_cv_fit_for_all_backends(backend, estimator):
1033+
# LinearModelsCV.fit performs inplace operations on input data which is
1034+
# memmapped when using loky backend, causing an error due to unexpected
1035+
# behavior of fancy indexing of read-only memmaps (cf. numpy#14132).
1036+
1037+
if joblib.__version__ < LooseVersion('0.12') and backend == 'loky':
1038+
pytest.skip('loky backend does not exist in joblib <0.12')
1039+
1040+
# Create a problem sufficiently large to cause memmapping (1MB).
1041+
n_targets = 1 + (estimator in (MultiTaskElasticNetCV, MultiTaskLassoCV))
1042+
X, y = make_regression(20000, 10, n_targets=n_targets)
1043+
1044+
with joblib.parallel_backend(backend=backend):
1045+
estimator(n_jobs=2, cv=3).fit(X, y)

0 commit comments

Comments
 (0)
0