Skip to content

Commit d8095e6

Browse files
API Deprecate n_alphas in LinearModelCV in favor of alphas (scikit-learn#30616)
Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai>
1 parent af7df5c commit d8095e6

File tree

3 files changed

+284
-58
lines changed

3 files changed

+284
-58
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
The parameter `n_alphas` has been deprecated in the following classes:
2+
:class:`linear_model.ElasticNetCV` and :class:`linear_model.LassoCV`
3+
and :class:`linear_model.MultiTaskElasticNetCV`
4+
and :class:`linear_model.MultiTaskLassoCV`, and will be removed in 1.9. The parameter
5+
`alphas` now supports both integers and array-likes, removing the need for `n_alphas`.
6+
From now on, only `alphas` should be set to either indicate the number of alphas to
7+
automatically generate (int) or to provide a list of alphas (array-like) to test along
8+
the regularization path.
9+
By :user:`Siddharth Bansal <KANNAHWORLD >`.

sklearn/linear_model/_coordinate_descent.py

Lines changed: 125 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
_raise_for_params,
2424
get_routing_for_object,
2525
)
26-
from ..utils._param_validation import Interval, StrOptions, validate_params
26+
from ..utils._param_validation import Hidden, Interval, StrOptions, validate_params
2727
from ..utils.extmath import safe_sparse_dot
2828
from ..utils.metadata_routing import (
2929
_routing_enabled,
@@ -1493,8 +1493,17 @@ class LinearModelCV(MultiOutputMixin, LinearModel, ABC):
14931493

14941494
_parameter_constraints: dict = {
14951495
"eps": [Interval(Real, 0, None, closed="neither")],
1496-
"n_alphas": [Interval(Integral, 1, None, closed="left")],
1497-
"alphas": ["array-like", None],
1496+
"n_alphas": [
1497+
Interval(Integral, 1, None, closed="left"),
1498+
Hidden(StrOptions({"deprecated"})),
1499+
],
1500+
# TODO(1.9): remove "warn" and None options.
1501+
"alphas": [
1502+
Interval(Integral, 1, None, closed="left"),
1503+
"array-like",
1504+
None,
1505+
Hidden(StrOptions({"warn"})),
1506+
],
14981507
"fit_intercept": ["boolean"],
14991508
"precompute": [StrOptions({"auto"}), "array-like", "boolean"],
15001509
"max_iter": [Interval(Integral, 1, None, closed="left")],
@@ -1512,8 +1521,8 @@ class LinearModelCV(MultiOutputMixin, LinearModel, ABC):
15121521
def __init__(
15131522
self,
15141523
eps=1e-3,
1515-
n_alphas=100,
1516-
alphas=None,
1524+
n_alphas="deprecated",
1525+
alphas="warn",
15171526
fit_intercept=True,
15181527
precompute="auto",
15191528
max_iter=1000,
@@ -1595,6 +1604,40 @@ def fit(self, X, y, sample_weight=None, **params):
15951604
"""
15961605
_raise_for_params(params, self, "fit")
15971606

1607+
# TODO(1.9): remove n_alphas and alphas={"warn", None}; set alphas=100 by
1608+
# default. Remove these deprecations messages and use self.alphas directly
1609+
# instead of self._alphas.
1610+
if self.n_alphas == "deprecated":
1611+
self._alphas = 100
1612+
else:
1613+
warnings.warn(
1614+
"'n_alphas' was deprecated in 1.7 and will be removed in 1.9. "
1615+
"'alphas' now accepts an integer value which removes the need to pass "
1616+
"'n_alphas'. The default value of 'alphas' will change from None to "
1617+
"100 in 1.9. Pass an explicit value to 'alphas' and leave 'n_alphas' "
1618+
"to its default value to silence this warning.",
1619+
FutureWarning,
1620+
)
1621+
self._alphas = self.n_alphas
1622+
1623+
if isinstance(self.alphas, str) and self.alphas == "warn":
1624+
# - If self.n_alphas == "deprecated", both are left to their default values
1625+
# so we don't warn since the future default behavior will be the same as
1626+
# the current default behavior.
1627+
# - If self.n_alphas != "deprecated", then we already warned about it
1628+
# and the warning message mentions the future self.alphas default, so
1629+
# no need to warn a second time.
1630+
pass
1631+
elif self.alphas is None:
1632+
warnings.warn(
1633+
"'alphas=None' is deprecated and will be removed in 1.9, at which "
1634+
"point the default value will be set to 100. Set 'alphas=100' "
1635+
"to silence this warning.",
1636+
FutureWarning,
1637+
)
1638+
else:
1639+
self._alphas = self.alphas
1640+
15981641
# This makes sure that there is no duplication in memory.
15991642
# Dealing right with copy_X is important in the following:
16001643
# Multiple functions touch X and subsamples of X and can induce a
@@ -1692,7 +1735,6 @@ def fit(self, X, y, sample_weight=None, **params):
16921735
path_params.pop("cv", None)
16931736
path_params.pop("n_jobs", None)
16941737

1695-
alphas = self.alphas
16961738
n_l1_ratio = len(l1_ratios)
16971739

16981740
check_scalar_alpha = partial(
@@ -1702,26 +1744,26 @@ def fit(self, X, y, sample_weight=None, **params):
17021744
include_boundaries="left",
17031745
)
17041746

1705-
if alphas is None:
1747+
if isinstance(self._alphas, Integral):
17061748
alphas = [
17071749
_alpha_grid(
17081750
X,
17091751
y,
17101752
l1_ratio=l1_ratio,
17111753
fit_intercept=self.fit_intercept,
17121754
eps=self.eps,
1713-
n_alphas=self.n_alphas,
1755+
n_alphas=self._alphas,
17141756
copy_X=self.copy_X,
17151757
sample_weight=sample_weight,
17161758
)
17171759
for l1_ratio in l1_ratios
17181760
]
17191761
else:
17201762
# Making sure alphas entries are scalars.
1721-
for index, alpha in enumerate(alphas):
1763+
for index, alpha in enumerate(self._alphas):
17221764
check_scalar_alpha(alpha, f"alphas[{index}]")
17231765
# Making sure alphas is properly ordered.
1724-
alphas = np.tile(np.sort(alphas)[::-1], (n_l1_ratio, 1))
1766+
alphas = np.tile(np.sort(self._alphas)[::-1], (n_l1_ratio, 1))
17251767

17261768
# We want n_alphas to be the number of alphas used for each l1_ratio.
17271769
n_alphas = len(alphas[0])
@@ -1807,7 +1849,7 @@ def fit(self, X, y, sample_weight=None, **params):
18071849

18081850
self.l1_ratio_ = best_l1_ratio
18091851
self.alpha_ = best_alpha
1810-
if self.alphas is None:
1852+
if isinstance(self._alphas, Integral):
18111853
self.alphas_ = np.asarray(alphas)
18121854
if n_l1_ratio == 1:
18131855
self.alphas_ = self.alphas_[0]
@@ -1897,9 +1939,22 @@ class LassoCV(RegressorMixin, LinearModelCV):
18971939
n_alphas : int, default=100
18981940
Number of alphas along the regularization path.
18991941
1900-
alphas : array-like, default=None
1901-
List of alphas where to compute the models.
1902-
If ``None`` alphas are set automatically.
1942+
.. deprecated:: 1.7
1943+
`n_alphas` was deprecated in 1.7 and will be removed in 1.9. Use `alphas`
1944+
instead.
1945+
1946+
alphas : array-like or int, default=None
1947+
Values of alphas to test along the regularization path.
1948+
If int, `alphas` values are generated automatically.
1949+
If array-like, list of alpha values to use.
1950+
1951+
.. versionchanged:: 1.7
1952+
`alphas` accepts an integer value which removes the need to pass
1953+
`n_alphas`.
1954+
1955+
.. deprecated:: 1.7
1956+
`alphas=None` was deprecated in 1.7 and will be removed in 1.9, at which
1957+
point the default value will be set to 100.
19031958
19041959
fit_intercept : bool, default=True
19051960
Whether to calculate the intercept for this model. If set
@@ -2049,8 +2104,8 @@ def __init__(
20492104
self,
20502105
*,
20512106
eps=1e-3,
2052-
n_alphas=100,
2053-
alphas=None,
2107+
n_alphas="deprecated",
2108+
alphas="warn",
20542109
fit_intercept=True,
20552110
precompute="auto",
20562111
max_iter=1000,
@@ -2155,9 +2210,22 @@ class ElasticNetCV(RegressorMixin, LinearModelCV):
21552210
n_alphas : int, default=100
21562211
Number of alphas along the regularization path, used for each l1_ratio.
21572212
2158-
alphas : array-like, default=None
2159-
List of alphas where to compute the models.
2160-
If None alphas are set automatically.
2213+
.. deprecated:: 1.7
2214+
`n_alphas` was deprecated in 1.7 and will be removed in 1.9. Use `alphas`
2215+
instead.
2216+
2217+
alphas : array-like or int, default=None
2218+
Values of alphas to test along the regularization path, used for each l1_ratio.
2219+
If int, `alphas` values are generated automatically.
2220+
If array-like, list of alpha values to use.
2221+
2222+
.. versionchanged:: 1.7
2223+
`alphas` accepts an integer value which removes the need to pass
2224+
`n_alphas`.
2225+
2226+
.. deprecated:: 1.7
2227+
`alphas=None` was deprecated in 1.7 and will be removed in 1.9, at which
2228+
point the default value will be set to 100.
21612229
21622230
fit_intercept : bool, default=True
21632231
Whether to calculate the intercept for this model. If set
@@ -2326,8 +2394,8 @@ def __init__(
23262394
*,
23272395
l1_ratio=0.5,
23282396
eps=1e-3,
2329-
n_alphas=100,
2330-
alphas=None,
2397+
n_alphas="deprecated",
2398+
alphas="warn",
23312399
fit_intercept=True,
23322400
precompute="auto",
23332401
max_iter=1000,
@@ -2845,9 +2913,22 @@ class MultiTaskElasticNetCV(RegressorMixin, LinearModelCV):
28452913
n_alphas : int, default=100
28462914
Number of alphas along the regularization path.
28472915
2848-
alphas : array-like, default=None
2849-
List of alphas where to compute the models.
2850-
If not provided, set automatically.
2916+
.. deprecated:: 1.7
2917+
`n_alphas` was deprecated in 1.7 and will be removed in 1.9. Use `alphas`
2918+
instead.
2919+
2920+
alphas : array-like or int, default=None
2921+
Values of alphas to test along the regularization path, used for each l1_ratio.
2922+
If int, `alphas` values are generated automatically.
2923+
If array-like, list of alpha values to use.
2924+
2925+
.. versionchanged:: 1.7
2926+
`alphas` accepts an integer value which removes the need to pass
2927+
`n_alphas`.
2928+
2929+
.. deprecated:: 1.7
2930+
`alphas=None` was deprecated in 1.7 and will be removed in 1.9, at which
2931+
point the default value will be set to 100.
28512932
28522933
fit_intercept : bool, default=True
28532934
Whether to calculate the intercept for this model. If set
@@ -2991,8 +3072,8 @@ def __init__(
29913072
*,
29923073
l1_ratio=0.5,
29933074
eps=1e-3,
2994-
n_alphas=100,
2995-
alphas=None,
3075+
n_alphas="deprecated",
3076+
alphas="warn",
29963077
fit_intercept=True,
29973078
max_iter=1000,
29983079
tol=1e-4,
@@ -3088,9 +3169,22 @@ class MultiTaskLassoCV(RegressorMixin, LinearModelCV):
30883169
n_alphas : int, default=100
30893170
Number of alphas along the regularization path.
30903171
3091-
alphas : array-like, default=None
3092-
List of alphas where to compute the models.
3093-
If not provided, set automatically.
3172+
.. deprecated:: 1.7
3173+
`n_alphas` was deprecated in 1.7 and will be removed in 1.9. Use `alphas`
3174+
instead.
3175+
3176+
alphas : array-like or int, default=None
3177+
Values of alphas to test along the regularization path.
3178+
If int, `alphas` values are generated automatically.
3179+
If array-like, list of alpha values to use.
3180+
3181+
.. versionchanged:: 1.7
3182+
`alphas` accepts an integer value which removes the need to pass
3183+
`n_alphas`.
3184+
3185+
.. deprecated:: 1.7
3186+
`alphas=None` was deprecated in 1.7 and will be removed in 1.9, at which
3187+
point the default value will be set to 100.
30943188
30953189
fit_intercept : bool, default=True
30963190
Whether to calculate the intercept for this model. If set
@@ -3230,8 +3324,8 @@ def __init__(
32303324
self,
32313325
*,
32323326
eps=1e-3,
3233-
n_alphas=100,
3234-
alphas=None,
3327+
n_alphas="deprecated",
3328+
alphas="warn",
32353329
fit_intercept=True,
32363330
max_iter=1000,
32373331
tol=1e-4,

0 commit comments

Comments
 (0)