From e915fcc3aba418c3d0fd1984e6378bd12b6e9f9e Mon Sep 17 00:00:00 2001 From: Manoj-Kumar-S Date: Sat, 31 May 2014 12:50:11 +0530 Subject: [PATCH 1/2] Changed default argument of precompute in ElasticNet and Lasso Setting precompute to "auto" was found to be slower when n_samples > n_features since the computation of the Gram matrix is computationally expensive and outweighs the benefit of fitting the Gram for just one alpha. --- doc/modules/linear_model.rst | 2 +- .../supervised_learning.rst | 2 +- doc/whats_new.rst | 7 +++++ sklearn/linear_model/coordinate_descent.py | 26 +++++++++++++------ 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/doc/modules/linear_model.rst b/doc/modules/linear_model.rst index 19cd0ebed40c1..62a414d86e7da 100644 --- a/doc/modules/linear_model.rst +++ b/doc/modules/linear_model.rst @@ -184,7 +184,7 @@ for another implementation:: >>> clf = linear_model.Lasso(alpha = 0.1) >>> clf.fit([[0, 0], [1, 1]], [0, 1]) Lasso(alpha=0.1, copy_X=True, fit_intercept=True, max_iter=1000, - normalize=False, positive=False, precompute='auto', random_state=None, + normalize=False, positive=False, precompute=False, random_state=None, selection='cyclic', tol=0.0001, warm_start=False) >>> clf.predict([[1, 1]]) array([ 0.8]) diff --git a/doc/tutorial/statistical_inference/supervised_learning.rst b/doc/tutorial/statistical_inference/supervised_learning.rst index 43a436869ad9c..901d0409fa6b9 100644 --- a/doc/tutorial/statistical_inference/supervised_learning.rst +++ b/doc/tutorial/statistical_inference/supervised_learning.rst @@ -327,7 +327,7 @@ application of Occam's razor: *prefer simpler models*. >>> regr.alpha = best_alpha >>> regr.fit(diabetes_X_train, diabetes_y_train) Lasso(alpha=0.025118864315095794, copy_X=True, fit_intercept=True, - max_iter=1000, normalize=False, positive=False, precompute='auto', + max_iter=1000, normalize=False, positive=False, precompute=False, random_state=None, selection='cyclic', tol=0.0001, warm_start=False) >>> print(regr.coef_) [ 0. -212.43764548 517.19478111 313.77959962 -160.8303982 -0. diff --git a/doc/whats_new.rst b/doc/whats_new.rst index 834fa76f5fe00..257bdb4f6cc1b 100644 --- a/doc/whats_new.rst +++ b/doc/whats_new.rst @@ -132,6 +132,13 @@ API changes summary but previous versions accidentally returned only the positive probability. Fixed by Will Lamond and `Lars Buitinck`_. + - Change default value of precompute in :class:`ElasticNet` and :class:`Lasso` + to False. Setting precompute to "auto" was found to be slower when + n_samples > n_features since the computation of the Gram matrix is + computationally expensive and outweighs the benefit of fitting the Gram + for just one alpha. + ``precompute="auto"`` is now deprecated and will be removed in 0.18 + By `Manoj Kumar`_. .. _changes_0_15_2: diff --git a/sklearn/linear_model/coordinate_descent.py b/sklearn/linear_model/coordinate_descent.py index 32766f99d0e14..1d12c21795d92 100644 --- a/sklearn/linear_model/coordinate_descent.py +++ b/sklearn/linear_model/coordinate_descent.py @@ -15,7 +15,7 @@ from .base import LinearModel, _pre_fit from ..base import RegressorMixin from .base import center_data, sparse_center_data -from ..utils import check_array +from ..utils import check_array, check_X_y from ..utils.validation import check_random_state from ..cross_validation import _check_cv as check_cv from ..externals.joblib import Parallel, delayed @@ -604,6 +604,8 @@ class ElasticNet(LinearModel, RegressorMixin): calculations. If set to ``'auto'`` let us decide. The Gram matrix can also be passed as argument. For sparse input this option is always ``True`` to preserve sparsity. + WARNING : The ``'auto'`` option is deprecated and will + be removed in 0.18. max_iter : int, optional The maximum number of iterations @@ -665,7 +667,7 @@ class ElasticNet(LinearModel, RegressorMixin): path = staticmethod(enet_path) def __init__(self, alpha=1.0, l1_ratio=0.5, fit_intercept=True, - normalize=False, precompute='auto', max_iter=1000, + normalize=False, precompute=False, max_iter=1000, copy_X=True, tol=1e-4, warm_start=False, positive=False, random_state=None, selection='cyclic'): self.alpha = alpha @@ -708,10 +710,16 @@ def fit(self, X, y): warnings.warn("With alpha=0, this algorithm does not converge " "well. You are advised to use the LinearRegression " "estimator", stacklevel=2) - X = check_array(X, 'csc', dtype=np.float64, order='F', copy=self.copy_X - and self.fit_intercept) - # From now on X can be touched inplace - y = np.asarray(y, dtype=np.float64) + + if self.precompute == 'auto': + warnings.warn("Setting precompute to 'auto', has found to be " + "slower even when n_samples > n_features. Hence " + "it will be removed in 0.18.", + DeprecationWarning, stacklevel=2) + + X, y = check_X_y(X, y, accept_sparse='csc', dtype=np.float64, + order='F', copy=self.copy_X and self.fit_intercept, + multi_output=True) X, y, X_mean, y_mean, X_std, precompute, Xy = \ _pre_fit(X, y, None, self.precompute, self.normalize, @@ -830,6 +838,8 @@ class Lasso(ElasticNet): calculations. If set to ``'auto'`` let us decide. The Gram matrix can also be passed as argument. For sparse input this option is always ``True`` to preserve sparsity. + WARNING : The ``'auto'`` option is deprecated and will + be removed in 0.18. max_iter : int, optional The maximum number of iterations @@ -880,7 +890,7 @@ class Lasso(ElasticNet): >>> clf = linear_model.Lasso(alpha=0.1) >>> clf.fit([[0,0], [1, 1], [2, 2]], [0, 1, 2]) Lasso(alpha=0.1, copy_X=True, fit_intercept=True, max_iter=1000, - normalize=False, positive=False, precompute='auto', random_state=None, + normalize=False, positive=False, precompute=False, random_state=None, selection='cyclic', tol=0.0001, warm_start=False) >>> print(clf.coef_) [ 0.85 0. ] @@ -906,7 +916,7 @@ class Lasso(ElasticNet): path = staticmethod(enet_path) def __init__(self, alpha=1.0, fit_intercept=True, normalize=False, - precompute='auto', copy_X=True, max_iter=1000, + precompute=False, copy_X=True, max_iter=1000, tol=1e-4, warm_start=False, positive=False, random_state=None, selection='cyclic'): super(Lasso, self).__init__( From 7cb3ba180246c639f21d061812bc703bbc75d137 Mon Sep 17 00:00:00 2001 From: MechCoder Date: Sat, 4 Oct 2014 03:25:28 +0200 Subject: [PATCH 2/2] TST: Added tests to test Deprecation warning --- sklearn/linear_model/coordinate_descent.py | 3 ++- .../linear_model/tests/test_coordinate_descent.py | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/sklearn/linear_model/coordinate_descent.py b/sklearn/linear_model/coordinate_descent.py index 1d12c21795d92..abd5dc782c6ed 100644 --- a/sklearn/linear_model/coordinate_descent.py +++ b/sklearn/linear_model/coordinate_descent.py @@ -712,7 +712,7 @@ def fit(self, X, y): "estimator", stacklevel=2) if self.precompute == 'auto': - warnings.warn("Setting precompute to 'auto', has found to be " + warnings.warn("Setting precompute to 'auto', was found to be " "slower even when n_samples > n_features. Hence " "it will be removed in 0.18.", DeprecationWarning, stacklevel=2) @@ -1217,6 +1217,7 @@ def fit(self, X, y): model.alpha = best_alpha model.l1_ratio = best_l1_ratio model.copy_X = copy_X + model.precompute = False model.fit(X, y) if not hasattr(self, 'l1_ratio'): del self.l1_ratio_ diff --git a/sklearn/linear_model/tests/test_coordinate_descent.py b/sklearn/linear_model/tests/test_coordinate_descent.py index 7f3f72f0920ff..216ddaf0c04e2 100644 --- a/sklearn/linear_model/tests/test_coordinate_descent.py +++ b/sklearn/linear_model/tests/test_coordinate_descent.py @@ -562,6 +562,18 @@ def test_random_descent(): assert_raises(ValueError, clf_random.fit, X, y) +def test_deprection_precompute_enet(): + """ + Test that setting precompute="auto" gives a Deprecation Warning. + """ + + X, y, _, _ = build_dataset(n_samples=20, n_features=10) + clf = ElasticNet(precompute="auto") + assert_warns(DeprecationWarning, clf.fit, X, y) + clf = Lasso(precompute="auto") + assert_warns(DeprecationWarning, clf.fit, X, y) + + if __name__ == '__main__': import nose nose.runmodule()