From 1c9a06d2261fcf340e4937ea766d0c0d0c76d496 Mon Sep 17 00:00:00 2001 From: jeremie du boisberranger Date: Wed, 2 Jun 2021 14:44:12 +0200 Subject: [PATCH 1/4] include properties into fitted attributes --- sklearn/tests/test_docstring_parameters.py | 27 ++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/sklearn/tests/test_docstring_parameters.py b/sklearn/tests/test_docstring_parameters.py index cc10f11fcd574..e105d88a65c9e 100644 --- a/sklearn/tests/test_docstring_parameters.py +++ b/sklearn/tests/test_docstring_parameters.py @@ -228,9 +228,19 @@ def test_fit_docstring_attributes(name, Estimator): 'StackingRegressor', 'TfidfVectorizer', 'VotingClassifier', 'VotingRegressor', 'SequentialFeatureSelector', 'HalvingGridSearchCV', 'HalvingRandomSearchCV'} + + # TODO remove in 1.1 or 1.2 when the deprecated attributes are + # removed + HAS_DEPRECATED_ATTRS = {'Birch', 'CCA', 'CategoricalNB', 'GridSearchCV', + 'MiniBatchKMeans', 'PLSCanonical', 'PLSRegression', + 'PLSSVD', 'RandomizedSearchCV', + 'SpectralCoclustering'} if Estimator.__name__ in IGNORED or Estimator.__name__.startswith('_'): pytest.skip("Estimator cannot be fit easily to test fit attributes") + if Estimator.__name__ in HAS_DEPRECATED_ATTRS: + pytest.skip("Estimator has undocumented deprecated attributes") + if Estimator.__name__ in ("RandomizedSearchCV", "GridSearchCV"): est = _construct_searchcv_instance(Estimator) else: @@ -288,10 +298,23 @@ def test_fit_docstring_attributes(name, Estimator): with ignore_warnings(category=FutureWarning): assert hasattr(est, attr.name) - fit_attr = [k for k in est.__dict__.keys() if k.endswith('_') - and not k.startswith('_')] + fit_attr = _get_all_fitted_attributes(est) fit_attr_names = [attr.name for attr in attributes] undocumented_attrs = set(fit_attr).difference(fit_attr_names) undocumented_attrs = set(undocumented_attrs).difference(skipped_attributes) assert not undocumented_attrs,\ "Undocumented attributes: {}".format(undocumented_attrs) + + +def _get_all_fitted_attributes(estimator): + "Get all the fitted attributes of an estimator including properties" + # attributes + fit_attr = list(estimator.__dict__.keys()) + + # properties + for name in dir(estimator.__class__): + obj = getattr(estimator.__class__, name) + if isinstance(obj, property): + fit_attr.append(name) + + return [k for k in fit_attr if k.endswith('_') and not k.startswith('_')] From c288616fee9560dc4f57cc64d4cec490d9bf8714 Mon Sep 17 00:00:00 2001 From: jeremie du boisberranger Date: Wed, 2 Jun 2021 14:53:52 +0200 Subject: [PATCH 2/4] cln --- sklearn/tests/test_docstring_parameters.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sklearn/tests/test_docstring_parameters.py b/sklearn/tests/test_docstring_parameters.py index e105d88a65c9e..12272c96107bf 100644 --- a/sklearn/tests/test_docstring_parameters.py +++ b/sklearn/tests/test_docstring_parameters.py @@ -231,10 +231,10 @@ def test_fit_docstring_attributes(name, Estimator): # TODO remove in 1.1 or 1.2 when the deprecated attributes are # removed - HAS_DEPRECATED_ATTRS = {'Birch', 'CCA', 'CategoricalNB', 'GridSearchCV', - 'MiniBatchKMeans', 'PLSCanonical', 'PLSRegression', - 'PLSSVD', 'RandomizedSearchCV', + HAS_DEPRECATED_ATTRS = {'Birch', 'CCA', 'CategoricalNB', 'MiniBatchKMeans', + 'PLSCanonical', 'PLSRegression', 'PLSSVD', 'SpectralCoclustering'} + if Estimator.__name__ in IGNORED or Estimator.__name__.startswith('_'): pytest.skip("Estimator cannot be fit easily to test fit attributes") From 56f70f59992045623d6da8ce339c09b6b449e97e Mon Sep 17 00:00:00 2001 From: jeremie du boisberranger Date: Thu, 3 Jun 2021 11:04:09 +0200 Subject: [PATCH 3/4] document classes_ for gridsearch and randomizedsearch --- sklearn/model_selection/_search.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sklearn/model_selection/_search.py b/sklearn/model_selection/_search.py index 07ad3d7dbafe5..3ee0bcc4ec153 100644 --- a/sklearn/model_selection/_search.py +++ b/sklearn/model_selection/_search.py @@ -1177,6 +1177,10 @@ class GridSearchCV(BaseSearchCV): multimetric_ : bool Whether or not the scorers compute several metrics. + classes_ : ndarray of shape (n_classes,) + The classes labels. This is present only if ``refit`` is specified and + the underlying estimator is a classifier. + Notes ----- The parameters selected are those that maximize the score of the left out @@ -1499,6 +1503,10 @@ class RandomizedSearchCV(BaseSearchCV): multimetric_ : bool Whether or not the scorers compute several metrics. + classes_ : ndarray of shape (n_classes,) + The classes labels. This is present only if ``refit`` is specified and + the underlying estimator is a classifier. + Notes ----- The parameters selected are those that maximize the score of the held-out From 9785096203c516cba62879f3c296dd3d7e3d8ff1 Mon Sep 17 00:00:00 2001 From: jeremie du boisberranger Date: Mon, 7 Jun 2021 16:14:26 +0200 Subject: [PATCH 4/4] keep all estimators but discard deprecated properties --- sklearn/cluster/_bicluster.py | 3 +++ sklearn/tests/test_docstring_parameters.py | 26 ++++++++++++---------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/sklearn/cluster/_bicluster.py b/sklearn/cluster/_bicluster.py index c8ff1bb036662..9267052b48f75 100644 --- a/sklearn/cluster/_bicluster.py +++ b/sklearn/cluster/_bicluster.py @@ -255,6 +255,9 @@ class SpectralCoclustering(BaseSpectral): column_labels_ : array-like of shape (n_cols,) The bicluster label of each column. + biclusters_ : tuple of two ndarrays + The tuple contains the `rows_` and `columns_` arrays. + Examples -------- >>> from sklearn.cluster import SpectralCoclustering diff --git a/sklearn/tests/test_docstring_parameters.py b/sklearn/tests/test_docstring_parameters.py index 12272c96107bf..f54ce1ba6cffe 100644 --- a/sklearn/tests/test_docstring_parameters.py +++ b/sklearn/tests/test_docstring_parameters.py @@ -229,18 +229,9 @@ def test_fit_docstring_attributes(name, Estimator): 'VotingRegressor', 'SequentialFeatureSelector', 'HalvingGridSearchCV', 'HalvingRandomSearchCV'} - # TODO remove in 1.1 or 1.2 when the deprecated attributes are - # removed - HAS_DEPRECATED_ATTRS = {'Birch', 'CCA', 'CategoricalNB', 'MiniBatchKMeans', - 'PLSCanonical', 'PLSRegression', 'PLSSVD', - 'SpectralCoclustering'} - if Estimator.__name__ in IGNORED or Estimator.__name__.startswith('_'): pytest.skip("Estimator cannot be fit easily to test fit attributes") - if Estimator.__name__ in HAS_DEPRECATED_ATTRS: - pytest.skip("Estimator has undocumented deprecated attributes") - if Estimator.__name__ in ("RandomizedSearchCV", "GridSearchCV"): est = _construct_searchcv_instance(Estimator) else: @@ -312,9 +303,20 @@ def _get_all_fitted_attributes(estimator): fit_attr = list(estimator.__dict__.keys()) # properties - for name in dir(estimator.__class__): - obj = getattr(estimator.__class__, name) - if isinstance(obj, property): + with warnings.catch_warnings(): + warnings.filterwarnings("error", category=FutureWarning) + + for name in dir(estimator.__class__): + obj = getattr(estimator.__class__, name) + if not isinstance(obj, property): + continue + + # ignore properties that raises an AttributeError and deprecated + # properties + try: + getattr(estimator, name) + except (AttributeError, FutureWarning): + continue fit_attr.append(name) return [k for k in fit_attr if k.endswith('_') and not k.startswith('_')]