From 3e74f6d853278b2d0aa29ecef2860bf5b9b0dccd Mon Sep 17 00:00:00 2001 From: Guillaume Lemaitre Date: Wed, 22 Jun 2022 14:07:59 +0200 Subject: [PATCH 1/9] DEPR deprecate n_iter in MiniBatchSparsePCA --- doc/whats_new/v1.1.rst | 9 ++ sklearn/decomposition/_sparse_pca.py | 99 +++++++++++-------- .../decomposition/tests/test_sparse_pca.py | 45 +++++++++ 3 files changed, 112 insertions(+), 41 deletions(-) diff --git a/doc/whats_new/v1.1.rst b/doc/whats_new/v1.1.rst index 4c46c0d631f76..34f77f7d5734a 100644 --- a/doc/whats_new/v1.1.rst +++ b/doc/whats_new/v1.1.rst @@ -19,6 +19,15 @@ Changelog a node if there are duplicates in the dataset. :pr:`23395` by :user:`Jérémie du Boisberranger `. +:mod:`sklearn.decomposition` +............................ + +- |Fix| Fixed a bug in :class:`decomposition.MiniBatchSparsePCA` where `n_iter` + was not deprecated as for :class:`decomposition.MiniBatchDictionaryLearning`. + We also introduce the parameters `max_iter`, `tol`, and `max_no_improvement` + for consistency. `n_iter` will be removed in version 1.3. + :pr:`xxx` by :user:`Guillaume Lemaitre `. + .. _changes_1_1_1: Version 1.1.1 diff --git a/sklearn/decomposition/_sparse_pca.py b/sklearn/decomposition/_sparse_pca.py index a36bfbfd529d0..348b784c3d5d0 100644 --- a/sklearn/decomposition/_sparse_pca.py +++ b/sklearn/decomposition/_sparse_pca.py @@ -2,15 +2,13 @@ # Author: Vlad Niculae, Gael Varoquaux, Alexandre Gramfort # License: BSD 3 clause -import warnings - import numpy as np from ..utils import check_random_state from ..utils.validation import check_is_fitted from ..linear_model import ridge_regression from ..base import BaseEstimator, TransformerMixin, _ClassNamePrefixFeaturesOutMixin -from ._dict_learning import dict_learning, dict_learning_online +from ._dict_learning import dict_learning, MiniBatchDictionaryLearning class SparsePCA(_ClassNamePrefixFeaturesOutMixin, TransformerMixin, BaseEstimator): @@ -275,6 +273,17 @@ class MiniBatchSparsePCA(SparsePCA): n_iter : int, default=100 Number of iterations to perform for each mini batch. + .. deprecated:: 1.1 + `n_iter` is deprecated in 1.1 and will be removed in 1.3. Use + `max_iter` instead. + + max_iter : int, default=None + Maximum number of iterations over the complete dataset before + stopping independently of any early stopping criterion heuristics. + If `max_iter` is not `None`, `n_iter` is ignored. + + .. versionadded:: 1.1 + callback : callable, default=None Callable that gets invoked every five iterations. @@ -307,6 +316,25 @@ class MiniBatchSparsePCA(SparsePCA): across multiple function calls. See :term:`Glossary `. + tol : float, default=1e-3 + Control early stopping based on the norm of the differences in the + dictionary between 2 steps. Used only if `max_iter` is not None. + + To disable early stopping based on changes in the dictionary, set + `tol` to 0.0. + + .. versionadded:: 1.1 + + max_no_improvement : int, default=10 + Control early stopping based on the consecutive number of mini batches + that does not yield an improvement on the smoothed cost function. Used only if + `max_iter` is not None. + + To disable convergence detection based on cost function, set + `max_no_improvement` to `None`. + + .. versionadded:: 1.1 + Attributes ---------- components_ : ndarray of shape (n_components, n_features) @@ -367,7 +395,8 @@ def __init__( *, alpha=1, ridge_alpha=0.01, - n_iter=100, + n_iter="deprecated", + max_iter=None, callback=None, batch_size=3, verbose=False, @@ -375,6 +404,8 @@ def __init__( n_jobs=None, method="lars", random_state=None, + tol=1e-3, + max_no_improvement=10, ): super().__init__( n_components=n_components, @@ -386,9 +417,12 @@ def __init__( random_state=random_state, ) self.n_iter = n_iter + self.max_iter = max_iter self.callback = callback self.batch_size = batch_size self.shuffle = shuffle + self.tol = tol + self.max_no_improvement = max_no_improvement def fit(self, X, y=None): """Fit the model from data in X. @@ -418,44 +452,27 @@ def fit(self, X, y=None): else: n_components = self.n_components - with warnings.catch_warnings(): - # return_n_iter and n_iter are deprecated. TODO Remove in 1.3 - warnings.filterwarnings( - "ignore", - message=( - "'return_n_iter' is deprecated in version 1.1 and will be " - "removed in version 1.3. From 1.3 'n_iter' will never be " - "returned. Refer to the 'n_iter_' and 'n_steps_' attributes " - "of the MiniBatchDictionaryLearning object instead." - ), - category=FutureWarning, - ) - warnings.filterwarnings( - "ignore", - message=( - "'n_iter' is deprecated in version 1.1 and will be removed in " - "version 1.3. Use 'max_iter' instead." - ), - category=FutureWarning, - ) - Vt, _, self.n_iter_ = dict_learning_online( - X.T, - n_components, - alpha=self.alpha, - n_iter=self.n_iter, - return_code=True, - dict_init=None, - verbose=self.verbose, - callback=self.callback, - batch_size=self.batch_size, - shuffle=self.shuffle, - n_jobs=self.n_jobs, - method=self.method, - random_state=random_state, - return_n_iter=True, - ) + transform_algorithm = "lasso_" + self.method + est = MiniBatchDictionaryLearning( + n_components=n_components, + alpha=self.alpha, + n_iter=self.n_iter, + max_iter=self.max_iter, + dict_init=None, + batch_size=self.batch_size, + shuffle=self.shuffle, + n_jobs=self.n_jobs, + fit_algorithm=self.method, + random_state=random_state, + transform_algorithm=transform_algorithm, + transform_alpha=self.alpha, + verbose=self.verbose, + callback=self.callback, + tol=self.tol, + max_no_improvement=self.max_no_improvement, + ).fit(X.T) - self.components_ = Vt.T + self.components_, self.n_iter_ = est.transform(X.T).T, est.n_iter_ components_norm = np.linalg.norm(self.components_, axis=1)[:, np.newaxis] components_norm[components_norm == 0] = 1 diff --git a/sklearn/decomposition/tests/test_sparse_pca.py b/sklearn/decomposition/tests/test_sparse_pca.py index db92ec582abdd..1863232efde37 100644 --- a/sklearn/decomposition/tests/test_sparse_pca.py +++ b/sklearn/decomposition/tests/test_sparse_pca.py @@ -265,3 +265,48 @@ def test_spca_feature_names_out(SPCA): estimator_name = SPCA.__name__.lower() assert_array_equal([f"{estimator_name}{i}" for i in range(4)], names) + + +# TODO (1.3): remove this test +def test_spca_n_iter_deprecation(): + """Check that we raise a warning for the deprecation of `n_iter` and it is ignore + when `max_iter` is specified. + """ + rng = np.random.RandomState(0) + n_samples, n_features = 12, 10 + X = rng.randn(n_samples, n_features) + + warn_msg = "'n_iter' is deprecated in version 1.1 and will be removed" + with pytest.warns(FutureWarning, match=warn_msg): + MiniBatchSparsePCA(n_iter=2).fit(X) + + n_iter, max_iter = 1, 100 + model = MiniBatchSparsePCA(n_iter=n_iter, max_iter=max_iter, random_state=0).fit(X) + assert model.n_iter_ > 1 + assert model.n_iter_ <= max_iter + + +def test_spca_early_stopping(global_random_seed): + """Check that `tol` and `max_no_improvement` act as early stopping.""" + rng = np.random.RandomState(global_random_seed) + n_samples, n_features = 50, 10 + X = rng.randn(n_samples, n_features) + + # vary the tolerance to force the early stopping of one of the model + model_early_stopped = MiniBatchSparsePCA( + max_iter=100, tol=0.5, random_state=global_random_seed + ).fit(X) + model_not_early_stopped = MiniBatchSparsePCA( + max_iter=100, tol=1e-3, random_state=global_random_seed + ).fit(X) + assert model_early_stopped.n_iter_ < model_not_early_stopped.n_iter_ + + # force the max number of no improvement to a large value to check that + # it does help to early stopping + model_early_stopped = MiniBatchSparsePCA( + max_iter=100, tol=1e-6, max_no_improvement=2, random_state=global_random_seed + ).fit(X) + model_not_early_stopped = MiniBatchSparsePCA( + max_iter=100, tol=1e-6, max_no_improvement=100, random_state=global_random_seed + ).fit(X) + assert model_early_stopped.n_iter_ < model_not_early_stopped.n_iter_ From 5471a9ac770734ea2f8ef38b12126d35652adaea Mon Sep 17 00:00:00 2001 From: Guillaume Lemaitre Date: Wed, 22 Jun 2022 14:12:43 +0200 Subject: [PATCH 2/9] pr number --- doc/whats_new/v1.1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whats_new/v1.1.rst b/doc/whats_new/v1.1.rst index 34f77f7d5734a..1c0b2be09f19a 100644 --- a/doc/whats_new/v1.1.rst +++ b/doc/whats_new/v1.1.rst @@ -26,7 +26,7 @@ Changelog was not deprecated as for :class:`decomposition.MiniBatchDictionaryLearning`. We also introduce the parameters `max_iter`, `tol`, and `max_no_improvement` for consistency. `n_iter` will be removed in version 1.3. - :pr:`xxx` by :user:`Guillaume Lemaitre `. + :pr:`23726` by :user:`Guillaume Lemaitre `. .. _changes_1_1_1: From 7c7651fa0afced5d31bebb4b9aad065bfc1c1cb5 Mon Sep 17 00:00:00 2001 From: Guillaume Lemaitre Date: Wed, 22 Jun 2022 14:41:22 +0200 Subject: [PATCH 3/9] fix docstring --- sklearn/decomposition/_sparse_pca.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sklearn/decomposition/_sparse_pca.py b/sklearn/decomposition/_sparse_pca.py index 348b784c3d5d0..2c2725f75d2aa 100644 --- a/sklearn/decomposition/_sparse_pca.py +++ b/sklearn/decomposition/_sparse_pca.py @@ -378,7 +378,7 @@ class MiniBatchSparsePCA(SparsePCA): >>> from sklearn.decomposition import MiniBatchSparsePCA >>> X, _ = make_friedman1(n_samples=200, n_features=30, random_state=0) >>> transformer = MiniBatchSparsePCA(n_components=5, batch_size=50, - ... random_state=0) + ... max_iter=10, random_state=0) >>> transformer.fit(X) MiniBatchSparsePCA(...) >>> X_transformed = transformer.transform(X) @@ -386,7 +386,7 @@ class MiniBatchSparsePCA(SparsePCA): (200, 5) >>> # most values in the components_ are zero (sparsity) >>> np.mean(transformer.components_ == 0) - 0.94 + 0.9... """ def __init__( From 78270fe8b523dac7dd1fb7c9c72be3d08f55c409 Mon Sep 17 00:00:00 2001 From: Guillaume Lemaitre Date: Wed, 22 Jun 2022 14:45:13 +0200 Subject: [PATCH 4/9] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <34657725+jeremiedbb@users.noreply.github.com> --- sklearn/decomposition/tests/test_sparse_pca.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sklearn/decomposition/tests/test_sparse_pca.py b/sklearn/decomposition/tests/test_sparse_pca.py index 1863232efde37..ac4ebfc745897 100644 --- a/sklearn/decomposition/tests/test_sparse_pca.py +++ b/sklearn/decomposition/tests/test_sparse_pca.py @@ -269,7 +269,7 @@ def test_spca_feature_names_out(SPCA): # TODO (1.3): remove this test def test_spca_n_iter_deprecation(): - """Check that we raise a warning for the deprecation of `n_iter` and it is ignore + """Check that we raise a warning for the deprecation of `n_iter` and it is ignored when `max_iter` is specified. """ rng = np.random.RandomState(0) @@ -302,7 +302,7 @@ def test_spca_early_stopping(global_random_seed): assert model_early_stopped.n_iter_ < model_not_early_stopped.n_iter_ # force the max number of no improvement to a large value to check that - # it does help to early stopping + # it does help to early stop model_early_stopped = MiniBatchSparsePCA( max_iter=100, tol=1e-6, max_no_improvement=2, random_state=global_random_seed ).fit(X) From 4354a2a9717f10a7aa06fb27fd5821dea528be9a Mon Sep 17 00:00:00 2001 From: Guillaume Lemaitre Date: Wed, 22 Jun 2022 15:13:38 +0200 Subject: [PATCH 5/9] be sure to warn when was set --- sklearn/decomposition/_dict_learning.py | 19 ++++++++++--------- .../decomposition/tests/test_dict_learning.py | 10 ++++++++++ .../decomposition/tests/test_sparse_pca.py | 5 ++++- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/sklearn/decomposition/_dict_learning.py b/sklearn/decomposition/_dict_learning.py index ad3db76bfd4b5..d5ba83bc9f4f9 100644 --- a/sklearn/decomposition/_dict_learning.py +++ b/sklearn/decomposition/_dict_learning.py @@ -2251,6 +2251,15 @@ def fit(self, X, y=None): ) self._check_params(X) + + if self.n_iter != "deprecated": + warnings.warn( + "'n_iter' is deprecated in version 1.1 and will be removed" + " in version 1.3. Use 'max_iter' instead.", + FutureWarning, + ) + n_iter = self.n_iter + self._random_state = check_random_state(self.random_state) dictionary = self._initialize_dict(X, self._random_state) @@ -2310,15 +2319,7 @@ def fit(self, X, y=None): self.n_iter_ = np.ceil(self.n_steps_ / n_steps_per_iter) else: # TODO remove this branch in 1.3 - if self.n_iter != "deprecated": - warnings.warn( - "'n_iter' is deprecated in version 1.1 and will be removed" - " in version 1.3. Use 'max_iter' instead.", - FutureWarning, - ) - n_iter = self.n_iter - else: - n_iter = 1000 + n_iter = 1000 if self.n_iter == "deprecated" else self.n_iter batches = gen_batches(n_samples, self._batch_size) batches = itertools.cycle(batches) diff --git a/sklearn/decomposition/tests/test_dict_learning.py b/sklearn/decomposition/tests/test_dict_learning.py index b53148cddec57..43a17a0b4376d 100644 --- a/sklearn/decomposition/tests/test_dict_learning.py +++ b/sklearn/decomposition/tests/test_dict_learning.py @@ -1072,3 +1072,13 @@ def test_get_feature_names_out(estimator): feature_names_out, [f"{estimator_name}{i}" for i in range(n_components)], ) + + +def test_minibatch_dictionary_learning_warns_and_ignore_n_iter(): + """Check that we always raise a warning when `n_iter` is set even if it is + ignored if `max_iter` is set. + """ + warn_msg = "'n_iter' is deprecated in version 1.1" + with pytest.warns(FutureWarning, match=warn_msg): + model = MiniBatchDictionaryLearning(batch_size=256, n_iter=2, max_iter=2).fit(X) + assert model.n_iter_ == 2 diff --git a/sklearn/decomposition/tests/test_sparse_pca.py b/sklearn/decomposition/tests/test_sparse_pca.py index ac4ebfc745897..0d02fa5cfc78a 100644 --- a/sklearn/decomposition/tests/test_sparse_pca.py +++ b/sklearn/decomposition/tests/test_sparse_pca.py @@ -281,7 +281,10 @@ def test_spca_n_iter_deprecation(): MiniBatchSparsePCA(n_iter=2).fit(X) n_iter, max_iter = 1, 100 - model = MiniBatchSparsePCA(n_iter=n_iter, max_iter=max_iter, random_state=0).fit(X) + with pytest.warns(FutureWarning, match=warn_msg): + model = MiniBatchSparsePCA( + n_iter=n_iter, max_iter=max_iter, random_state=0 + ).fit(X) assert model.n_iter_ > 1 assert model.n_iter_ <= max_iter From 7dc6588eea29e9245b635bc1a0fa443a3db93557 Mon Sep 17 00:00:00 2001 From: jeremie du boisberranger Date: Wed, 22 Jun 2022 16:00:08 +0200 Subject: [PATCH 6/9] just to be sure :) [all random seeds] test_spca_early_stopping From 3378ffb6748c2f08b31922f56c4fb13993cdf7e6 Mon Sep 17 00:00:00 2001 From: Guillaume Lemaitre Date: Wed, 22 Jun 2022 16:54:53 +0200 Subject: [PATCH 7/9] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <34657725+jeremiedbb@users.noreply.github.com> --- sklearn/decomposition/_dict_learning.py | 2 +- sklearn/decomposition/tests/test_dict_learning.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sklearn/decomposition/_dict_learning.py b/sklearn/decomposition/_dict_learning.py index d5ba83bc9f4f9..98df01fd59b36 100644 --- a/sklearn/decomposition/_dict_learning.py +++ b/sklearn/decomposition/_dict_learning.py @@ -2255,7 +2255,7 @@ def fit(self, X, y=None): if self.n_iter != "deprecated": warnings.warn( "'n_iter' is deprecated in version 1.1 and will be removed" - " in version 1.3. Use 'max_iter' instead.", + " in version 1.3. Use 'max_iter' and let `n_iter` to its default value instead.", FutureWarning, ) n_iter = self.n_iter diff --git a/sklearn/decomposition/tests/test_dict_learning.py b/sklearn/decomposition/tests/test_dict_learning.py index 43a17a0b4376d..74749f37e907b 100644 --- a/sklearn/decomposition/tests/test_dict_learning.py +++ b/sklearn/decomposition/tests/test_dict_learning.py @@ -1074,6 +1074,7 @@ def test_get_feature_names_out(estimator): ) +# TODO(1.3) remove def test_minibatch_dictionary_learning_warns_and_ignore_n_iter(): """Check that we always raise a warning when `n_iter` is set even if it is ignored if `max_iter` is set. From 158c98e39488fcd9732309985559cc6df0606e4d Mon Sep 17 00:00:00 2001 From: Guillaume Lemaitre Date: Wed, 22 Jun 2022 17:04:22 +0200 Subject: [PATCH 8/9] Update _dict_learning.py --- sklearn/decomposition/_dict_learning.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sklearn/decomposition/_dict_learning.py b/sklearn/decomposition/_dict_learning.py index 98df01fd59b36..9bbf3e2a8d618 100644 --- a/sklearn/decomposition/_dict_learning.py +++ b/sklearn/decomposition/_dict_learning.py @@ -2254,8 +2254,10 @@ def fit(self, X, y=None): if self.n_iter != "deprecated": warnings.warn( - "'n_iter' is deprecated in version 1.1 and will be removed" - " in version 1.3. Use 'max_iter' and let `n_iter` to its default value instead.", + "'n_iter' is deprecated in version 1.1 and will be removed " + "in version 1.3. Use 'max_iter' and let 'n_iter' to its default " + "value instead. 'n_iter' is also ignored if 'max_iter' is " + "specified.", FutureWarning, ) n_iter = self.n_iter From 6ea3f396a99d728440b51ade44694a1db88b1c84 Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Fri, 24 Jun 2022 16:50:54 +0200 Subject: [PATCH 9/9] Move deprecation for sparse PCA to 1.2 and updated messages and tests accordingly --- doc/whats_new/v1.1.rst | 9 --------- doc/whats_new/v1.2.rst | 10 ++++++++++ sklearn/decomposition/_dict_learning.py | 6 +++--- sklearn/decomposition/_sparse_pca.py | 6 +++--- sklearn/decomposition/tests/test_dict_learning.py | 4 ++-- sklearn/decomposition/tests/test_sparse_pca.py | 2 +- 6 files changed, 19 insertions(+), 18 deletions(-) diff --git a/doc/whats_new/v1.1.rst b/doc/whats_new/v1.1.rst index 1c0b2be09f19a..4c46c0d631f76 100644 --- a/doc/whats_new/v1.1.rst +++ b/doc/whats_new/v1.1.rst @@ -19,15 +19,6 @@ Changelog a node if there are duplicates in the dataset. :pr:`23395` by :user:`Jérémie du Boisberranger `. -:mod:`sklearn.decomposition` -............................ - -- |Fix| Fixed a bug in :class:`decomposition.MiniBatchSparsePCA` where `n_iter` - was not deprecated as for :class:`decomposition.MiniBatchDictionaryLearning`. - We also introduce the parameters `max_iter`, `tol`, and `max_no_improvement` - for consistency. `n_iter` will be removed in version 1.3. - :pr:`23726` by :user:`Guillaume Lemaitre `. - .. _changes_1_1_1: Version 1.1.1 diff --git a/doc/whats_new/v1.2.rst b/doc/whats_new/v1.2.rst index efda80e75e04a..af346bf2f3698 100644 --- a/doc/whats_new/v1.2.rst +++ b/doc/whats_new/v1.2.rst @@ -110,6 +110,16 @@ Changelog its memory footprint and runtime. :pr:`22268` by :user:`MohamedBsh `. +:mod:`sklearn.decomposition` +............................ + +- |API| The `n_iter` parameter of :class:`decomposition.MiniBatchSparsePCA` is + deprecated and replaced by the parameters `max_iter`, `tol`, and + `max_no_improvement` to be consistent with + :class:`decomposition.MiniBatchDictionaryLearning`. `n_iter` will be removed + in version 1.3. :pr:`23726` by :user:`Guillaume Lemaitre `. + + :mod:`sklearn.ensemble` ....................... diff --git a/sklearn/decomposition/_dict_learning.py b/sklearn/decomposition/_dict_learning.py index 9bbf3e2a8d618..cd4d6e55897ad 100644 --- a/sklearn/decomposition/_dict_learning.py +++ b/sklearn/decomposition/_dict_learning.py @@ -794,7 +794,7 @@ def dict_learning_online( Number of mini-batch iterations to perform. .. deprecated:: 1.1 - `n_iter` is deprecated in 1.1 and will be removed in 1.3. Use + `n_iter` is deprecated in 1.1 and will be removed in 1.4. Use `max_iter` instead. max_iter : int, default=None @@ -1758,7 +1758,7 @@ class MiniBatchDictionaryLearning(_BaseSparseCoding, BaseEstimator): Total number of iterations over data batches to perform. .. deprecated:: 1.1 - ``n_iter`` is deprecated in 1.1 and will be removed in 1.3. Use + ``n_iter`` is deprecated in 1.1 and will be removed in 1.4. Use ``max_iter`` instead. max_iter : int, default=None @@ -2255,7 +2255,7 @@ def fit(self, X, y=None): if self.n_iter != "deprecated": warnings.warn( "'n_iter' is deprecated in version 1.1 and will be removed " - "in version 1.3. Use 'max_iter' and let 'n_iter' to its default " + "in version 1.4. Use 'max_iter' and let 'n_iter' to its default " "value instead. 'n_iter' is also ignored if 'max_iter' is " "specified.", FutureWarning, diff --git a/sklearn/decomposition/_sparse_pca.py b/sklearn/decomposition/_sparse_pca.py index 2c2725f75d2aa..3bbd27e99e0c6 100644 --- a/sklearn/decomposition/_sparse_pca.py +++ b/sklearn/decomposition/_sparse_pca.py @@ -273,8 +273,8 @@ class MiniBatchSparsePCA(SparsePCA): n_iter : int, default=100 Number of iterations to perform for each mini batch. - .. deprecated:: 1.1 - `n_iter` is deprecated in 1.1 and will be removed in 1.3. Use + .. deprecated:: 1.2 + `n_iter` is deprecated in 1.2 and will be removed in 1.4. Use `max_iter` instead. max_iter : int, default=None @@ -282,7 +282,7 @@ class MiniBatchSparsePCA(SparsePCA): stopping independently of any early stopping criterion heuristics. If `max_iter` is not `None`, `n_iter` is ignored. - .. versionadded:: 1.1 + .. versionadded:: 1.2 callback : callable, default=None Callable that gets invoked every five iterations. diff --git a/sklearn/decomposition/tests/test_dict_learning.py b/sklearn/decomposition/tests/test_dict_learning.py index 74749f37e907b..c3c74c37acbfc 100644 --- a/sklearn/decomposition/tests/test_dict_learning.py +++ b/sklearn/decomposition/tests/test_dict_learning.py @@ -721,7 +721,7 @@ def test_minibatch_dict_learning_n_iter_deprecated(): # check the deprecation warning of n_iter # FIXME: remove in 1.3 depr_msg = ( - "'n_iter' is deprecated in version 1.1 and will be removed in version 1.3" + "'n_iter' is deprecated in version 1.1 and will be removed in version 1.4" ) est = MiniBatchDictionaryLearning( n_components=2, batch_size=4, n_iter=5, random_state=0 @@ -1074,7 +1074,7 @@ def test_get_feature_names_out(estimator): ) -# TODO(1.3) remove +# TODO(1.4) remove def test_minibatch_dictionary_learning_warns_and_ignore_n_iter(): """Check that we always raise a warning when `n_iter` is set even if it is ignored if `max_iter` is set. diff --git a/sklearn/decomposition/tests/test_sparse_pca.py b/sklearn/decomposition/tests/test_sparse_pca.py index 0d02fa5cfc78a..b1d9e54d651ac 100644 --- a/sklearn/decomposition/tests/test_sparse_pca.py +++ b/sklearn/decomposition/tests/test_sparse_pca.py @@ -267,7 +267,7 @@ def test_spca_feature_names_out(SPCA): assert_array_equal([f"{estimator_name}{i}" for i in range(4)], names) -# TODO (1.3): remove this test +# TODO (1.4): remove this test def test_spca_n_iter_deprecation(): """Check that we raise a warning for the deprecation of `n_iter` and it is ignored when `max_iter` is specified.