From aaf215c15af0ae7f28ec925bc9e42edf3f72cad9 Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Sat, 17 Feb 2024 23:00:33 +1100 Subject: [PATCH] FIX Allow alpha 0 when not using LOO in `RidgeCV` (#28425) --- doc/modules/linear_model.rst | 24 +++++++++++++----------- sklearn/linear_model/_ridge.py | 24 +++++++++++++++++------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/doc/modules/linear_model.rst b/doc/modules/linear_model.rst index bd074f5b326d3..ed7ea069e58b6 100644 --- a/doc/modules/linear_model.rst +++ b/doc/modules/linear_model.rst @@ -193,9 +193,14 @@ This method has the same order of complexity as Setting the regularization parameter: leave-one-out Cross-Validation -------------------------------------------------------------------- -:class:`RidgeCV` implements ridge regression with built-in -cross-validation of the alpha parameter. The object works in the same way -as GridSearchCV except that it defaults to Leave-One-Out Cross-Validation:: +:class:`RidgeCV` and :class:`RidgeClassifierCV` implement ridge +regression/classification with built-in cross-validation of the alpha parameter. +They work in the same way as :class:`~sklearn.model_selection.GridSearchCV` except +that it defaults to efficient Leave-One-Out :term:`cross-validation`. +When using the default :term:`cross-validation`, alpha cannot be 0 due to the +formulation used to calculate Leave-One-Out error. See [RL2007]_ for details. + +Usage example:: >>> import numpy as np >>> from sklearn import linear_model @@ -211,16 +216,13 @@ cross-validation with :class:`~sklearn.model_selection.GridSearchCV`, for example `cv=10` for 10-fold cross-validation, rather than Leave-One-Out Cross-Validation. -|details-start| -**References** -|details-split| +.. topic:: References: -* "Notes on Regularized Least Squares", Rifkin & Lippert (`technical report - `_, - `course slides - `_). -|details-end| + .. [RL2007] "Notes on Regularized Least Squares", Rifkin & Lippert (`technical report + `_, + `course slides + `_). .. _lasso: diff --git a/sklearn/linear_model/_ridge.py b/sklearn/linear_model/_ridge.py index 84646f5aaf130..6c561859fdf9f 100644 --- a/sklearn/linear_model/_ridge.py +++ b/sklearn/linear_model/_ridge.py @@ -2188,12 +2188,21 @@ def fit(self, X, y, sample_weight=None): """ cv = self.cv - check_scalar_alpha = partial( - check_scalar, - target_type=numbers.Real, - min_val=0.0, - include_boundaries="neither", - ) + # `_RidgeGCV` does not work for alpha = 0 + if cv is None: + check_scalar_alpha = partial( + check_scalar, + target_type=numbers.Real, + min_val=0.0, + include_boundaries="neither", + ) + else: + check_scalar_alpha = partial( + check_scalar, + target_type=numbers.Real, + min_val=0.0, + include_boundaries="left", + ) if isinstance(self.alphas, (np.ndarray, list, tuple)): n_alphas = 1 if np.ndim(self.alphas) == 0 else len(self.alphas) @@ -2272,7 +2281,7 @@ class RidgeCV( Alpha corresponds to ``1 / (2C)`` in other linear models such as :class:`~sklearn.linear_model.LogisticRegression` or :class:`~sklearn.svm.LinearSVC`. - If using Leave-One-Out cross-validation, alphas must be positive. + If using Leave-One-Out cross-validation, alphas must be strictly positive. fit_intercept : bool, default=True Whether to calculate the intercept for this model. If set @@ -2439,6 +2448,7 @@ class RidgeClassifierCV(_RoutingNotSupportedMixin, _RidgeClassifierMixin, _BaseR Alpha corresponds to ``1 / (2C)`` in other linear models such as :class:`~sklearn.linear_model.LogisticRegression` or :class:`~sklearn.svm.LinearSVC`. + If using Leave-One-Out cross-validation, alphas must be strictly positive. fit_intercept : bool, default=True Whether to calculate the intercept for this model. If set