10000 Fix mixin inheritance order, allow overwriting tags (#14884) · scikit-learn/scikit-learn@03ea20d · GitHub
[go: up one dir, main page]

Skip to content

Commit 03ea20d

Browse files
amuellerrth
authored andcommitted
Fix mixin inheritance order, allow overwriting tags (#14884)
1 parent 96bfae6 commit 03ea20d

File tree

90 files changed

+170
-176
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+170
-176
lines changed

examples/compose/plot_column_transformer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
from sklearn.svm import LinearSVC
4343

4444

45-
class TextStats(BaseEstimator, TransformerMixin):
45+
class TextStats(TransformerMixin, BaseEstimator):
4646
"""Extract features from each document for DictVectorizer"""
4747

4848
def fit(self, x, y=None):
@@ -54,7 +54,7 @@ def transform(self, posts):
5454
for text in posts]
5555

5656

57-
class SubjectBodyExtractor(BaseEstimator, TransformerMixin):
57+
class SubjectBodyExtractor(TransformerMixin, BaseEstimator):
5858
"""Extract the subject & body from a usenet post in a single pass.
5959
6060
Takes a sequence of strings and produces a dict of sequences. Keys are

sklearn/base.py

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -129,17 +129,6 @@ def _pprint(params, offset=0, printer=repr):
129129
return lines
130130

131131

132-
def _update_if_consistent(dict1, dict2):
133-
common_keys = set(dict1.keys()).intersection(dict2.keys())
134-
for key in common_keys:
135-
if dict1[key] != dict2[key]:
136-
raise TypeError("Inconsistent values for tag {}: {} != {}".format(
137-
key, dict1[key], dict2[key]
138-
))
139-
dict1.update(dict2)
140-
return dict1
141-
142-
143132
class BaseEstimator:
144133
"""Base class for all estimators in scikit-learn
145134
@@ -320,20 +309,19 @@ def __setstate__(self, state):
320309
except AttributeError:
321310
self.__dict__.update(state)
322311

312+
def _more_tags(self):
313+
return _DEFAULT_TAGS
314+
323315
def _get_tags(self):
324316
collected_tags = {}
325-
for base_class in inspect.getmro(self.__class__):
326-
if (hasattr(base_class, '_more_tags')
327-
and base_class != self.__class__):
317+
for base_class in reversed(inspect.getmro(self.__class__)):
318+
if hasattr(base_class, '_more_tags'):
319+
# need the if because mixins might not have _more_tags
320+
# but might do redundant work in estimators
321+
# (i.e. calling more tags on BaseEstimator multiple times)
328322
more_tags = base_class._more_tags(self)
329-
collected_tags = _update_if_consistent(collected_tags,
330-
more_tags)
331-
if hasattr(self, '_more_tags'):
332-
more_tags = self._more_tags()
333-
collected_tags = _update_if_consistent(collected_tags, more_tags)
334-
tags = _DEFAULT_TAGS.copy()
335-
tags.update(collected_tags)
336-
return tags
323+
collected_tags.update(more_tags)
324+
return collected_tags
337325

338326

339327
class ClassifierMixin:

sklearn/calibration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ def grad(AB):
465465
return AB_[0], AB_[1]
466466

467467

468-
class _SigmoidCalibration(BaseEstimator, RegressorMixin):
468+
class _SigmoidCalibration(RegressorMixin, BaseEstimator):
469469
"""Sigmoid regression model.
470470
471471
Attributes

sklearn/cluster/affinity_propagation_.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ def affinity_propagation(S, preference=None, convergence_iter=15, max_iter=200,
233233

234234
###############################################################################
235235

236-
class AffinityPropagation(BaseEstimator, ClusterMixin):
236+
class AffinityPropagat 10000 ion(ClusterMixin, BaseEstimator):
237237
"""Perform Affinity Propagation Clustering of data.
238238
239239
Read more in the :ref:`User Guide <affinity_propagation>`.

sklearn/cluster/bicluster.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def _log_normalize(X):
8484
return L - row_avg - col_avg + avg
8585

8686

87-
class BaseSpectral(BaseEstimator, BiclusterMixin, metaclass=ABCMeta):
87+
class BaseSpectral(BiclusterMixin, BaseEstimator, metaclass=ABCMeta):
8888
"""Base class for spectral biclustering."""
8989

9090
@abstractmethod

sklearn/cluster/birch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ def radius(self):
319319
self.sq_norm_)
320320

321321

322-
class Birch(BaseEstimator, TransformerMixin, ClusterMixin):
322+
class Birch(ClusterMixin, TransformerMixin, BaseEstimator):
323323
"""Implements the Birch clustering algorithm.
324324
325325
It is a memory-efficient, online-learning algorithm provided as an

sklearn/cluster/dbscan_.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ def dbscan(X, eps=0.5, min_samples=5, metric='minkowski', metric_params=None,
190190
return np.where(core_samples)[0], labels
191191

192192

193-
class DBSCAN(BaseEstimator, ClusterMixin):
193+
class DBSCAN(ClusterMixin, BaseEstimator):
194194
"""Perform DBSCAN clustering from vector array or distance matrix.
195195
196196
DBSCAN - Density-Based Spatial Clustering of Applications with Noise.

sklearn/cluster/hierarchical.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ def _hc_cut(n_clusters, children, n_leaves):
652652

653653
###############################################################################
654654

655-
class AgglomerativeClustering(BaseEstimator, ClusterMixin):
655+
class AgglomerativeClustering(ClusterMixin, BaseEstimator):
656656
"""
657657
Agglomerative Clustering
658658

sklearn/cluster/k_means_.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,7 @@ def _init_centroids(X, k, init, random_state=None, x_squared_norms=None,
761761
return centers
762762

763763

764-
class KMeans(BaseEstimator, ClusterMixin, TransformerMixin):
764+
class KMeans(TransformerMixin, ClusterMixin, BaseEstimator):
765765
"""K-Means clustering
766766
767767
Read more in the :ref:`User Guide <k_means>`.

sklearn/cluster/mean_shift_.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ def get_bin_seeds(X, bin_size, min_bin_freq=1):
293293
return bin_seeds
294294

295295

296-
class MeanShift(BaseEstimator, ClusterMixin):
296+
class MeanShift(ClusterMixin, BaseEstimator):
297297
"""Mean shift clustering using a flat kernel.
298298
299299
Mean shift clustering aims to discover "blobs" in a smooth density of

sklearn/cluster/optics_.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from ..metrics import pairwise_distances
2222

2323

24-
class OPTICS(BaseEstimator, ClusterMixin):
24+
class OPTICS(ClusterMixin, BaseEstimator):
2525
"""Estimate clustering structure from vector array
2626
2727
OPTICS (Ordering Points To Identify the Clustering Structure), closely

sklearn/cluster/spectral.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ def spectral_clustering(affinity, n_clusters=8, n_components=None,
272272
return labels
273273

274274

275-
class SpectralClustering(BaseEstimator, ClusterMixin):
275+
class SpectralClustering(ClusterMixin, BaseEstimator):
276276
"""Apply clustering to a projection of the normalized Laplacian.
277277
278278
In practice Spectral Clustering is very useful when the structure of

sklearn/cluster/tests/test_bicluster.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from sklearn.datasets import make_biclusters, make_checkerboard
2525

2626

27-
class MockBiclustering(BaseEstimator, BiclusterMixin):
27+
class MockBiclustering(BiclusterMixin, BaseEstimator):
2828
# Mock object for testing get_submatrix.
2929
def __init__(self):
3030
pass

sklearn/compose/_column_transformer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"item instead of a scalar.")
3434

3535

36-
class ColumnTransformer(_BaseComposition, TransformerMixin):
36+
class ColumnTransformer(TransformerMixin, _BaseComposition):
3737
"""Applies transformers to columns of an array or pandas DataFrame.
3838
3939
This estimator allows different columns or column subsets of the input

sklearn/compose/_target.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
__all__ = ['TransformedTargetRegressor']
1515

1616

17-
class TransformedTargetRegressor(BaseEstimator, RegressorMixin):
17+
class TransformedTargetRegressor(RegressorMixin, BaseEstimator):
1818
"""Meta-estimator to regress on a transformed target.
1919
2020
Useful for applying a non-linear transformation in regression

sklearn/compose/tests/test_target.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ def func(y):
226226
assert_allclose(y_pred_1d_func, y_pred_2d_func)
227227

228228

229-
class DummyCheckerArrayTransformer(BaseEstimator, TransformerMixin):
229+
class DummyCheckerArrayTransformer(TransformerMixin, BaseEstimator):
230230

231231
def fit(self, X, y=None):
232232
assert isinstance(X, np.ndarray)
@@ -268,7 +268,7 @@ def test_transform_target_regressor_ensure_y_array():
268268
tt.predict(X)
269269

270270

271-
class DummyTransformer(BaseEstimator, TransformerMixin):
271+
class DummyTransformer(TransformerMixin, BaseEstimator):
272272
"""Dummy transformer which count how many time fit was called."""
273273
def __init__(self, fit_counter=0):
274274
self.fit_counter = fit_counter

sklearn/covariance/elliptic_envelope.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from ..base import OutlierMixin
1010

1111

12-
class EllipticEnvelope(MinCovDet, OutlierMixin):
12+
class EllipticEnvelope(OutlierMixin, MinCovDet):
1313
"""An object for detecting outliers in a Gaussian distributed dataset.
1414
1515
Read more in the :ref:`User Guide <outlier_detection>`.

sklearn/cross_decomposition/cca_.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
__all__ = ['CCA']
55

66

7-
class CCA(_PLS, _UnstableArchMixin):
7+
class CCA(_UnstableArchMixin, _PLS):
88
"""CCA Canonical Correlation Analysis.
99
1010
CCA inherits from PLS with mode="B" and deflation_mode="canonical".

sklearn/cross_decomposition/pls_.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def _center_scale_xy(X, Y, scale=True):
121121
return X, Y, x_mean, y_mean, x_std, y_std
122122

123123

124-
class _PLS(BaseEstimator, TransformerMixin, RegressorMixin, MultiOutputMixin,
124+
class _PLS(TransformerMixin, RegressorMixin, MultiOutputMixin, BaseEstimator,
125125
metaclass=ABCMeta):
126126
"""Partial Least Squares (PLS)
127127
@@ -750,7 +750,7 @@ def __init__(self, n_components=2, scale=True, algorithm="nipals",
750750
max_iter=max_iter, tol=tol, copy=copy)
751751

752752

753-
class PLSSVD(BaseEstimator, TransformerMixin):
753+
class PLSSVD(TransformerMixin, BaseEstimator):
754754
"""Partial Least Square SVD
755755
756756
Simply perform a svd on the crosscovariance matrix: X'Y

sklearn/decomposition/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from abc import ABCMeta, abstractmethod
1818

1919

20-
class _BasePCA(BaseEstimator, TransformerMixin, metaclass=ABCMeta):
20+
class _BasePCA(TransformerMixin, BaseEstimator, metaclass=ABCMeta):
2121
"""Base class for PCA methods.
2222
2323
Warning: This class should not be used directly.

sklearn/decomposition/dict_learning.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,7 @@ def transform(self, X):
932932
return code
933933

934934

935-
class SparseCoder(BaseEstimator, SparseCodingMixin):
935+
class SparseCoder(SparseCodingMixin, BaseEstimator):
936936
"""Sparse coding
937937
938938
Finds a sparse representation of data against a fixed, precomputed
@@ -1045,7 +1045,7 @@ def fit(self, X, y=None):
10451045
return self
10461046

10471047

1048-
class DictionaryLearning(BaseEstimator, SparseCodingMixin):
1048+
class DictionaryLearning(SparseCodingMixin, BaseEstimator):
10491049
"""Dictionary learning
10501050
10511051
Finds a dictionary (a set of atoms) that can best be used to represent data
@@ -1241,7 +1241,7 @@ def fit(self, X, y=None):
12411241
return self
12421242

12431243

1244-
class MiniBatchDictionaryLearning(BaseEstimator, SparseCodingMixin):
1244+
class MiniBatchDictionaryLearning(SparseCodingMixin, BaseEstimator):
12451245
"""Mini-batch dictionary learning
12461246
12471247
Finds a dictionary (a set of atoms) that can best be used to represent data

sklearn/decomposition/factor_analysis.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
from ..exceptions import ConvergenceWarning
3333

3434

35-
class FactorAnalysis(BaseEstimator, TransformerMixin):
35+
class FactorAnalysis(TransformerMixin, BaseEstimator):
3636
"""Factor Analysis (FA)
3737
3838
A simple linear generative model with Gaussian latent variables.

sklearn/decomposition/fastica_.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ def g(x, fun_args):
380380
return None, W, S
381381

382382

383-
class FastICA(BaseEstimator, TransformerMixin):
383+
class FastICA(TransformerMixin, BaseEstimator):
384384
"""FastICA: a fast algorithm for Independent Component Analysis.
385385
386386
Read more in the :ref:`User Guide <ICA>`.

sklearn/decomposition/kernel_pca.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from ..metrics.pairwise import pairwise_kernels
1717

1818

19-
class KernelPCA(BaseEstimator, TransformerMixin):
19+
class KernelPCA(TransformerMixin, BaseEstimator):
2020
"""Kernel Principal component analysis (KPCA)
2121
2222
Non-linear dimensionality reduction through the use of kernels (see

sklearn/decomposition/nmf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,7 @@ def non_negative_factorization(X, W=None, H=None, n_components=None,
10681068
return W, H, n_iter
10691069

10701070

1071-
class NMF(BaseEstimator, TransformerMixin):
1071+
class NMF(TransformerMixin, BaseEstimator):
10721072
r"""Non-Negative Matrix Factorization (NMF)
10731073
10741074
Find two non-negative matrices (W, H) whose product approximates the non-

sklearn/decomposition/online_lda.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def _update_doc_distribution(X, exp_topic_word_distr, doc_topic_prior,
132132
return (doc_topic_distr, suff_stats)
133133

134134

135-
class LatentDirichletAllocation(BaseEstimator, TransformerMixin):
135+
class LatentDirichletAllocation(TransformerMixin, BaseEstimator):
136136
"""Latent Dirichlet Allocation with online variational Bayes algorithm
137137
138138
.. versionadded:: 0.17

sklearn/decomposition/sparse_pca.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def _check_normalize_components(normalize_components, estimator_name):
2929
)
3030

3131

32-
class SparsePCA(BaseEstimator, TransformerMixin):
32+
class SparsePCA(TransformerMixin, BaseEstimator):
3333
"""Sparse Principal Components Analysis (SparsePCA)
3434
3535
Finds the set of sparse components that can optimally reconstruct

sklearn/decomposition/truncated_svd.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
__all__ = ["TruncatedSVD"]
1919

2020

21-
class TruncatedSVD(BaseEstimator, TransformerMixin):
21+
class TruncatedSVD(TransformerMixin, BaseEstimator):
2222
"""Dimensionality reduction using truncated SVD (aka LSA).
2323
2424
This transformer performs linear dimensionality reduction by means of

sklearn/discriminant_analysis.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ def predict_log_proba(self, X):
553553
return np.log(self.predict_proba(X))
554554

555555

556-
class QuadraticDiscriminantAnalysis(BaseEstimator, ClassifierMixin):
556+
class QuadraticDiscriminantAnalysis(ClassifierMixin, BaseEstimator):
557557
"""Quadratic Discriminant Analysis
558558
559559
A classifier with a quadratic decision boundary, generated

sklearn/dummy.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from .utils.multiclass import class_distribution
2020

2121

22-
class DummyClassifier(BaseEstimator, ClassifierMixin, MultiOutputMixin):
22+
class DummyClassifier(MultiOutputMixin, ClassifierMixin, BaseEstimator):
2323
"""
2424
DummyClassifier is a classifier that makes predictions using simple rules.
2525
@@ -353,7 +353,7 @@ def score(self, X, y, sample_weight=None):
353353
return super().score(X, y, sample_weight)
354354

355355

356-
class DummyRegressor(BaseEstimator, RegressorMixin, MultiOutputMixin):
356+
class DummyRegressor(MultiOutputMixin, RegressorMixin, BaseEstimator):
357357
"""
358358
DummyRegressor is a regressor that makes predictions using
359359
simple rules.

sklearn/ensemble/_hist_gradient_boosting/binning.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def _find_binning_thresholds(data, max_bins, subsample, random_state):
8383
return binning_thresholds
8484

8585

86-
class _BinMapper(BaseEstimator, TransformerMixin):
86+
class _BinMapper(TransformerMixin, BaseEstimator):
8787
"""Transformer that maps a dataset into integer-valued bins.
8888
8989
The bins are created in a feature-wise fashion, using quantiles so that

sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ def n_iter_(self):
639639
return len(self._predictors)
640640

641641

642-
class HistGradientBoostingRegressor(BaseHistGradientBoosting, RegressorMixin):
642+
class HistGradientBoostingRegressor(RegressorMixin, BaseHistGradientBoosting):
643643
"""Histogram-based Gradient Boosting Regression Tree.
644644
645645
This estimator is much faster than

sklearn/ensemble/bagging.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ def estimators_samples_(self):
429429
for _, sample_indices in self._get_estimators_indices()]
430430

431431

432-
class BaggingClassifier(BaseBagging, ClassifierMixin):
432+
class BaggingClassifier(ClassifierMixin, BaseBagging):
433433
"""A Bagging classifier.
434434
435435
A Bagging classifier is an ensemble meta-estimator that fits base
@@ -816,7 +816,7 @@ def decision_function(self, X):
816816
return decisions
817817

818818

819-
class BaggingRegressor(BaseBagging, RegressorMixin):
819+
class BaggingRegressor(RegressorMixin, BaseBagging):
820820
"""A Bagging regressor.
821821
822822
A Bagging regressor is an ensemble meta-estimator that fits base

0 commit comments

Comments
 (0)
0