# This should remained pinned to version 1.2 and not updated like other# externals."""Copyright (c) 2001-2002 Enthought, Inc.  2003-2019, SciPy Developers.All rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditionsare met:1. Redistributions of source code must retain the above copyright   notice, this list of conditions and the following disclaimer.2. Redistributions in binary form must reproduce the above   copyright notice, this list of conditions and the following   disclaimer in the documentation and/or other materials provided   with the distribution.3. Neither the name of the copyright holder nor the names of its   contributors may be used to endorse or promote products derived   from this software without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOTLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHTOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOTLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANYTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USEOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."""import numpy as npimport scipy.linalg.decomp as decompdef pinvh(a, cond=None, rcond=None, lower=True, return_rank=False,          check_finite=True):    """    Compute the (Moore-Penrose) pseudo-inverse of a Hermitian matrix.    Copied in from scipy==1.2.2, in order to preserve the default choice of the    `cond` and `above_cutoff` values which determine which values of the matrix    inversion lie below threshold and are so set to zero. Changes in scipy 1.3    resulted in a smaller default threshold and thus slower convergence of    dependent algorithms in some cases (see Sklearn github issue #14055).    Calculate a generalized inverse of a Hermitian or real symmetric matrix    using its eigenvalue decomposition and including all eigenvalues with    'large' absolute value.    Parameters    ----------    a : (N, N) array_like        Real symmetric or complex hermetian matrix to be pseudo-inverted    cond, rcond : float or None        Cutoff for 'small' eigenvalues.        Singular values smaller than rcond * largest_eigenvalue are considered        zero.        If None or -1, suitable machine precision is used.    lower : bool, optional        Whether the pertinent array data is taken from the lower or upper        triangle of a. (Default: lower)    return_rank : bool, optional        if True, return the effective rank of the matrix    check_finite : bool, optional        Whether to check that the input matrix contains only finite numbers.        Disabling may give a performance gain, but may result in problems        (crashes, non-termination) if the inputs do contain infinities or NaNs.    Returns    -------    B : (N, N) ndarray        The pseudo-inverse of matrix `a`.    rank : int        The effective rank of the matrix.  Returned if return_rank == True    Raises    ------    LinAlgError        If eigenvalue does not converge    Examples    --------    >>> from scipy.linalg import pinvh    >>> a = np.random.randn(9, 6)    >>> a = np.dot(a, a.T)    >>> B = pinvh(a)    >>> np.allclose(a, np.dot(a, np.dot(B, a)))    True    >>> np.allclose(B, np.dot(B, np.dot(a, B)))    True    """    a = decomp._asarray_validated(a, check_finite=check_finite)    s, u = decomp.eigh(a, lower=lower, check_finite=False)    if rcond is not None:        cond = rcond    if cond in [None, -1]:        t = u.dtype.char.lower()        factor = {'f': 1E3, 'd': 1E6}        cond = factor[t] * np.finfo(t).eps    # For Hermitian matrices, singular values equal abs(eigenvalues)    above_cutoff = (abs(s) > cond * np.max(abs(s)))    psigma_diag = 1.0 / s[above_cutoff]    u = u[:, above_cutoff]    B = np.dot(u * psigma_diag, np.conjugate(u).T)    if return_rank:        return B, len(psigma_diag)    else:        return Bdiff --git a/sklearn/linear_model/bayes.py b/sklearn/linear_model/bayes.py-- a/sklearn/linear_model/bayes.py++ b/sklearn/linear_model/bayes.py


from math import log import numpy as np from scipy import linalgfrom scipy.linalg import pinvh  from .base import LinearModel, _rescale_data from ..base import RegressorMixin from ..utils.extmath import fast_logdet from ..utils import check_X_yfrom ..utils.fixes import pinvh   ###############################################################################diff --git a/sklearn/utils/fixes.py b/sklearn/utils/fixes.py-- a/sklearn/utils/fixes.py++ b/sklearn/utils/fixes.py


# once support for sp_version < (1, 3) is dropped     from ..externals._lobpcg import lobpcg  # noqa <ins>if sp_version >= (1, 3):    # Preserves earlier default choice of pinvh cutoff `cond` value.    # Can be removed once issue #14055 is fully addressed.    from ..externals._scipy_linalg import pinvhelse:    from scipy.linalg import pinvh # noqa</ins> if sp_version >= (0, 19):     def _argmax(arr_or_spmatrix, axis=None):         return arr_or_spmatrix.argmax(axis=axis)


# Take the best scores across every fold and the average of                 # all coefficients corresponding to the best scores.                 best_indices = np.argmax(scores, axis=1)                if self.multi_class == 'ovr':                if multi_class == 'ovr':                     w = np.mean([coefs_paths[i, best_indices[i], :]                                  for i in range(len(folds))], axis=0)                 else:


best_indices_C = best_indices % len(self.Cs_)                 self.C_.append(np.mean(self.Cs_[best_indices_C]))                 best_indices_l1 = best_indices // len(self.Cs_)                self.l1_ratio_.append(np.mean(l1_ratios_[best_indices_l1]))                if self.penalty == 'elasticnet':                    best_indices_l1 = best_indices // len(self.Cs_)                    self.l1_ratio_.append(np.mean(l1_ratios_[best_indices_l1]))                else:                    self.l1_ratio_.append(None)              if multi_class == 'multinomial':                 self.C_ = np.tile(self.C_, n_classes)


import numpy as np import sys import time<ins>import numbers</ins> from scipy.optimize import minimize from ..utils.extmath import softmax from ..metrics import pairwise_distances


# Check the preferred dimensionality of the projected space         if self.n_components is not None:            check_scalar(self.n_components, 'n_components', int, 1)            check_scalar(                self.n_components, 'n_components', numbers.Integral, 1)              if self.n_components > X.shape[1]:                 raise ValueError('The preferred dimensionality of the '


.format(X.shape[1],                                          self.components_.shape[1]))         check_scalar(self.max_iter, 'max_iter', int, 1)        check_scalar(self.tol, 'tol', float, 0.)        check_scalar(self.verbose, 'verbose', int, 0)        check_scalar(self.max_iter, 'max_iter', numbers.Integral, 1)        check_scalar(self.tol, 'tol', numbers.Real, 0.)        check_scalar(self.verbose, 'verbose', numbers.Integral, 0)          if self.callback is not None:             if not callable(self.callback):


from ..tree import DecisionTreeClassifier, DecisionTreeRegressor from ..utils import check_array, check_random_state, check_X_y, safe_indexing<ins>from ..utils.extmath import softmax</ins> from ..utils.extmath import stable_cumsum from ..metrics import accuracy_score, r2_score from ..utils.validation import check_is_fitted


else:                 yield pred / norm <ins>    @staticmethod    def _compute_proba_from_decision(decision, n_classes):        """Compute probabilities from the decision function.        This is based eq. (4) of [1] where:            p(y=c|X) = exp((1 / K-1) f_c(X)) / sum_k(exp((1 / K-1) f_k(X)))                     = softmax((1 / K-1) * f(X))        References        ----------        .. [1] J. Zhu, H. Zou, S. Rosset, T. Hastie, "Multi-class AdaBoost",               2009.        """        if n_classes == 2:            decision = np.vstack([-decision, decision]).T / 2        else:            decision /= (n_classes - 1)        return softmax(decision, copy=False)</ins>     def predict_proba(self, X):         """Predict class probabilities for X.


if n_classes == 1:             return np.ones((_num_samples(X), 1))         if self.algorithm == 'SAMME.R':            # The weights are all 1. for SAMME.R            proba = sum(_samme_proba(estimator, n_classes, X)                        for estimator in self.estimators_)        else:  # self.algorithm == "SAMME"            proba = sum(estimator.predict_proba(X) * w                        for estimator, w in zip(self.estimators_,                                                self.estimator_weights_))        proba /= self.estimator_weights_.sum()        proba = np.exp((1. / (n_classes - 1)) * proba)        normalizer = proba.sum(axis=1)[:, np.newaxis]        normalizer[normalizer == 0.0] = 1.0        proba /= normalizer        return proba        decision = self.decision_function(X)        return self._compute_proba_from_decision(decision, n_classes)      def staged_predict_proba(self, X):         """Predict class probabilities for X.


X = self._validate_data(X)          n_classes = self.n_classes_        proba = None        norm = 0.        for weight, estimator in zip(self.estimator_weights_,                                     self.estimators_):            norm += weight            if self.algorithm == 'SAMME.R':                # The weights are all 1. for SAMME.R                current_proba = _samme_proba(estimator, n_classes, X)            else:  # elif self.algorithm == "SAMME":                current_proba = estimator.predict_proba(X) * weight            if proba is None:                proba = current_proba            else:                proba += current_proba            real_proba = np.exp((1. / (n_classes - 1)) * (proba / norm))            normalizer = real_proba.sum(axis=1)[:, np.newaxis]            normalizer[normalizer == 0.0] = 1.0            real_proba /= normalizer             yield real_proba        for decision in self.staged_decision_function(X):            yield self._compute_proba_from_decision(decision, n_classes)      def predict_log_proba(self, X):         """Predict class log-probabilities for X.


raise ValueError('Expected array-like (array or non-string sequence), '                          'got %r' % y)     sparseseries = (y.__class__.__name__ == 'SparseSeries')    if sparseseries:        raise ValueError("y cannot be class 'SparseSeries'.")    sparse_pandas = (y.__class__.__name__ in ['SparseSeries', 'SparseArray'])    if sparse_pandas:        raise ValueError("y cannot be class 'SparseSeries' or 'SparseArray'")      if is_multilabel(y):         return 'multilabel-indicator'


"Cython",         "pandas",         "matplotlib",<ins>        "joblib",</ins>     ]      def get_version(module):


from ..utils import Bunch from ..utils import safe_indexing from ..utils import _get_column_indices<ins>from ..utils import _check_key_type</ins> from ..utils.metaestimators import _BaseComposition from ..utils.validation import check_array, check_is_fitted


By setting ``remainder`` to be an estimator, the remaining         non-specified columns will use the ``remainder`` estimator. The         estimator must support :term:`fit` and :term:`transform`.<ins>        Note that using this feature requires that the DataFrame columns        input at :term:`fit` and :term:`transform` have identical order.</ins>      sparse_threshold : float, default = 0.3         If the output of the different transformers contains sparse matrices,


"'passthrough', or estimator. '%s' was passed instead" %                 self.remainder)         n_columns = X.shape[1]        # Make it possible to check for reordered named columns on transform        if (hasattr(X, 'columns') and                any(_check_key_type(cols, str) for cols in self._columns)):            self._df_columns = X.columns        self._n_features = X.shape[1]         cols = []         for columns in self._columns:             cols.extend(_get_column_indices(X, columns))        remaining_idx = sorted(list(set(range(n_columns)) - set(cols))) or None        remaining_idx = list(set(range(self._n_features)) - set(cols))        remaining_idx = sorted(remaining_idx) or None          self._remainder = ('remainder', self.remainder, remaining_idx)


"""         check_is_fitted(self, 'transformers_')         X = _check_X(X)        if self._n_features > X.shape[1]:            raise ValueError('Number of features of the input must be equal '                             'to or greater than that of the fitted '                             'transformer. Transformer n_features is {0} '                             'and input n_features is {1}.'                             .format(self._n_features, X.shape[1]))        # No column reordering allowed for named cols combined with remainder        if (self._remainder[2] is not None and                hasattr(self, '_df_columns') and                hasattr(X, 'columns')):            n_cols_fit = len(self._df_columns)            n_cols_transform = len(X.columns)            if (n_cols_transform >= n_cols_fit and                    any(X.columns[:n_cols_fit] != self._df_columns)):                raise ValueError('Column ordering must be equal for fit '                                 'and for transform when using the '                                 'remainder keyword')         Xs = self._fit_transform(X, None, _transform_one, fitted=True)         self._validate_output(Xs)


raise ValueError(             "'estimator' must be a fitted regressor or classifier.")     if (hasattr(estimator, 'classes_') and            isinstance(estimator.classes_[0], np.ndarray)):        raise ValueError('Multiclass-multioutput estimators are not supported')    if is_classifier(estimator):        if not hasattr(estimator, 'classes_'):            raise ValueError(                "'estimator' parameter must be a fitted estimator"            )        if isinstance(estimator.classes_[0], np.ndarray):            raise ValueError(                'Multiclass-multioutput estimators are not supported'            )      X = check_array(X)


import array from collections import defaultdict from collections.abc import Mapping<ins>from functools import partial</ins> import numbers from operator import itemgetter import re


'strip_tags']  <ins>def _preprocess(doc, accent_function=None, lower=False):    """Chain together an optional series of text preprocessing steps to    apply to a document.    Parameters    ----------    doc: str        The string to preprocess    accent_function: callable        Function for handling accented characters. Common strategies include        normalizing and removing.    lower: bool        Whether to use str.lower to lowercase all fo the text    Returns    -------    doc: str        preprocessed string    """    if lower:        doc = doc.lower()    if accent_function is not None:        doc = accent_function(doc)    return docdef _analyze(doc, analyzer=None, tokenizer=None, ngrams=None,             preprocessor=None, decoder=None, stop_words=None):    """Chain together an optional series of text processing steps to go from    a single document to ngrams, with or without tokenizing or preprocessing.    If analyzer is used, only the decoder argument is used, as the analyzer is    intended to replace the preprocessor, tokenizer, and ngrams steps.    Parameters    ----------    analyzer: callable    tokenizer: callable    ngrams: callable    preprocessor: callable    decoder: callable    stop_words: list    Returns    -------    ngrams: list        A sequence of tokens, possibly with pairs, triples, etc.    """    if decoder is not None:        doc = decoder(doc)    if analyzer is not None:        doc = analyzer(doc)    else:        if preprocessor is not None:            doc = preprocessor(doc)        if tokenizer is not None:            doc = tokenizer(doc)        if ngrams is not None:            if stop_words is not None:                doc = ngrams(doc, stop_words)            else:                doc = ngrams(doc)    return doc</ins> def strip_accents_unicode(s):     """Transform accentuated unicode symbols into their simple counterpart


if self.preprocessor is not None:             return self.preprocessor         # unfortunately python functools package does not have an efficient        # `compose` function that would have allowed us to chain a dynamic        # number of functions. However the cost of a lambda call is a few        # hundreds of nanoseconds which is negligible when compared to the        # cost of tokenizing a string of 1000 chars for instance.        noop = lambda x: x         # accent stripping         if not self.strip_accents:            strip_accents = noop            strip_accents = None         elif callable(self.strip_accents):             strip_accents = self.strip_accents         elif self.strip_accents == 'ascii':


raise ValueError('Invalid value for "strip_accents": %s' %                              self.strip_accents)         if self.lowercase:            return lambda x: strip_accents(x.lower())        else:            return strip_accents        return partial(            _preprocess, accent_function=strip_accents, lower=self.lowercase        )      def build_tokenizer(self):         """Return a function that splits a string into a sequence of tokens"""         if self.tokenizer is not None:             return self.tokenizer         token_pattern = re.compile(self.token_pattern)        return lambda doc: token_pattern.findall(doc)        return token_pattern.findall      def get_stop_words(self):         """Build or fetch the effective stop words list"""


if callable(self.analyzer):             if self.input in ['file', 'filename']:                 self._validate_custom_analyzer()            return lambda doc: self.analyzer(self.decode(doc))            return partial(                _analyze, analyzer=self.analyzer, decoder=self.decode            )          preprocess = self.build_preprocessor()          if self.analyzer == 'char':            return lambda doc: self._char_ngrams(preprocess(self.decode(doc)))            return partial(_analyze, ngrams=self._char_ngrams,                           preprocessor=preprocess, decoder=self.decode)          elif self.analyzer == 'char_wb':            return lambda doc: self._char_wb_ngrams(                preprocess(self.decode(doc)))            return partial(_analyze, ngrams=self._char_wb_ngrams,                           preprocessor=preprocess, decoder=self.decode)          elif self.analyzer == 'word':             stop_words = self.get_stop_words()             tokenize = self.build_tokenizer()             self._check_stop_words_consistency(stop_words, preprocess,                                                tokenize)            return lambda doc: self._word_ngrams(                tokenize(preprocess(self.decode(doc))), stop_words)            return partial(_analyze, ngrams=self._word_ngrams,                           tokenizer=tokenize, preprocessor=preprocess,                           decoder=self.decode, stop_words=stop_words)          else:             raise ValueError('%s is not a valid tokenization scheme/analyzer' %


similar to the Power method for determining the eigenvectors and     eigenvalues of a X'Y.     """    y_score = Y[:, [0]]    for col in Y.T:        if np.any(np.abs(col) > np.finfo(np.double).eps):            y_score = col.reshape(len(col), 1)            break     x_weights_old = 0     ite = 1     X_pinv = Y_pinv = None


seed=seed)         intercept_decay = SPARSE_INTERCEPT_DECAY     else:        X = np.ascontiguousarray(X)         dataset = ArrayData(X, y, sample_weight, seed=seed)         intercept_decay = 1.0 diff --git a/sklearn/linear_model/ridge.py b/sklearn/linear_model/ridge.py-- a/sklearn/linear_model/ridge.py++ b/sklearn/linear_model/ridge.py


_accept_sparse = _get_valid_accept_sparse(sparse.issparse(X), solver)         X = check_array(X, accept_sparse=_accept_sparse, dtype=_dtype,                         order="C")        y = check_array(y, dtype=X.dtype, ensure_2d=False, order="C")        y = check_array(y, dtype=X.dtype, ensure_2d=False, order=None)     check_consistent_length(X, y)      n_samples, n_features = X.shape


"""         out = dict()         for key in self._get_param_names():            value = getattr(self, key, None)            try:                value = getattr(self, key)            except AttributeError:                warnings.warn('From version 0.24, get_params will raise an '                              'AttributeError if a parameter cannot be '                              'retrieved as an instance attribute. Previously '                              'it would return None.',                              FutureWarning)                value = None             if deep and hasattr(value, 'get_params'):                 deep_items = value.get_params().items()                 out.update((key + '__' + k, val) for k, val in deep_items)diff --git a/sklearn/gaussian_process/kernels.py b/sklearn/gaussian_process/kernels.py-- a/sklearn/gaussian_process/kernels.py++ b/sklearn/gaussian_process/kernels.py


from collections import namedtuple import math from inspect import signature<ins>import warnings</ins>  import numpy as np from scipy.special import kv, gamma


" %s doesn't follow this convention."                                % (cls, ))         for arg in args:            params[arg] = getattr(self, arg, None)            try:                value = getattr(self, arg)            except AttributeError:                warnings.warn('From version 0.24, get_params will raise an '                              'AttributeError if a parameter cannot be '                              'retrieved as an instance attribute. Previously '                              'it would return None.',                              FutureWarning)                value = None            params[arg] = value         return params      def set_params(self, **params):diff --git a/sklearn/pipeline.py b/sklearn/pipeline.py-- a/sklearn/pipeline.py++ b/sklearn/pipeline.py


def __init__(self, steps, memory=None, verbose=False):         self.steps = steps        self._validate_steps()         self.memory = memory         self.verbose = verbose        self._validate_steps()      def get_params(self, deep=True):         """Get parameters for this estimator.


Parameters     ----------    min_samples : int > 1 or float between 0 and 1 (default=None)    min_samples : int > 1 or float between 0 and 1 (default=5)         The number of samples in a neighborhood for a point to be considered as         a core point. Also, up and down steep regions can't have more then         ``min_samples`` consecutive non-steep points. Expressed as an absolute


A feature array, or array of distances between samples if         metric='precomputed'     min_samples : int (default=5)    min_samples : int > 1 or float between 0 and 1         The number of samples in a neighborhood for a point to be considered         as a core point. Expressed as an absolute number or a fraction of the         number of samples (rounded to be at least 2).


n_samples = X.shape[0]     _validate_size(min_samples, n_samples, 'min_samples')     if min_samples <= 1:        min_samples = max(2, min_samples * n_samples)        min_samples = max(2, int(min_samples * n_samples))      # Start all points as 'unprocessed' ##     reachability_ = np.empty(n_samples)


ordering : array, shape (n_samples,)         OPTICS ordered point indices (`ordering_`)     min_samples : int > 1 or float between 0 and 1 (default=None)    min_samples : int > 1 or float between 0 and 1         The same as the min_samples given to OPTICS. Up and down steep regions         can't have more then ``min_samples`` consecutive non-steep points.         Expressed as an absolute number or a fraction of the number of samples


n_samples = len(reachability)     _validate_size(min_samples, n_samples, 'min_samples')     if min_samples <= 1:        min_samples = max(2, min_samples * n_samples)        min_samples = max(2, int(min_samples * n_samples))     if min_cluster_size is None:         min_cluster_size = min_samples     _validate_size(min_cluster_size, n_samples, 'min_cluster_size')     if min_cluster_size <= 1:        min_cluster_size = max(2, min_cluster_size * n_samples)        min_cluster_size = max(2, int(min_cluster_size * n_samples))      clusters = _xi_cluster(reachability[ordering], predecessor[ordering],                            ordering, xi,


reachability plot is defined by the ratio from one point to its         successor being at most 1-xi.     min_samples : int > 1 or float between 0 and 1 (default=None)    min_samples : int > 1         The same as the min_samples given to OPTICS. Up and down steep regions         can't have more then ``min_samples`` consecutive non-steep points.        Expressed as an absolute number or a fraction of the number of samples        (rounded to be at least 2).     min_cluster_size : int > 1 or float between 0 and 1        Minimum number of samples in an OPTICS cluster, expressed as an        absolute number or a fraction of the number of samples (rounded        to be at least 2).    min_cluster_size : int > 1        Minimum number of samples in an OPTICS cluster.      predecessor_correction : bool         Correct clusters based on the calculated predecessors.


# we set copy to False         return self._tfidf.transform(X, copy=False)     def transform(self, raw_documents, copy=True):    def transform(self, raw_documents, copy="deprecated"):         """Transform documents to document-term matrix.          Uses the vocabulary and document frequencies (df) learned by fit (or


Whether to copy X and operate on the copy or perform in-place             operations. <ins>            .. deprecated:: 0.22               The `copy` parameter is unused and was deprecated in version               0.22 and will be removed in 0.24. This parameter will be               ignored.</ins>         Returns         -------         X : sparse matrix, [n_samples, n_features]


"""         check_is_fitted(self, '_tfidf', 'The tfidf vector is not fitted') <ins>        # FIXME Remove copy parameter support in 0.24        if copy != "deprecated":            msg = ("'copy' param is unused and has been deprecated since "                   "version 0.22. Backward compatibility for 'copy' will "                   "be removed in 0.24.")            warnings.warn(msg, DeprecationWarning)</ins>         X = super().transform(raw_documents)         return self._tfidf.transform(X, copy=False)


# Author: Andreas Mueller #         Joris Van den Bossche # License: BSDimport warnings from itertools import chain import numbers import numpy as np from scipy import sparse from joblib import Parallel, delayed


"The output of the '{0}' transformer should be 2D (scipy "                     "matrix, array, or pandas DataFrame).".format(name)) <ins>    def _validate_features(self, n_features, feature_names):        """Ensures feature counts and names are the same during fit and        transform.        TODO: It should raise an error from v0.24        """        if ((self._feature_names_in is None or feature_names is None)                and self._n_features == n_features):            return        neg_col_present = np.any([_is_negative_indexing(col)                                  for col in self._columns])        if neg_col_present and self._n_features != n_features:            raise RuntimeError("At least one negative column was used to "                               "indicate columns, and the new data's number "                               "of columns does not match the data given "                               "during fit. "                               "Please make sure the data during fit and "                               "transform have the same number of columns.")        if (self._n_features != n_features or                np.any(self._feature_names_in != np.asarray(feature_names))):            warnings.warn("Given feature/column names or counts do not match "                          "the ones for the data given during fit. This will "                          "fail from v0.24.",                          DeprecationWarning)</ins>     def _log_message(self, name, idx, total):         if not self.verbose:             return None


sparse matrices.          """<ins>        # TODO: this should be `feature_names_in_` when we start having it        if hasattr(X, "columns"):            self._feature_names_in = np.asarray(X.columns)        else:            self._feature_names_in = None</ins>         X = _check_X(X)         self._validate_transformers()         self._validate_column_callables(X)


"""         check_is_fitted(self, 'transformers_')         X = _check_X(X)<ins>        if hasattr(X, "columns"):            X_feature_names = np.asarray(X.columns)        else:            X_feature_names = None</ins>          if self._n_features > X.shape[1]:             raise ValueError('Number of features of the input must be equal '


.format(self._n_features, X.shape[1]))          # No column reordering allowed for named cols combined with remainder<ins>        # TODO: remove this mechanism in 0.24, once we enforce strict column        # name order and count. See #14237 for details.</ins>         if (self._remainder[2] is not None and                 hasattr(self, '_df_columns') and                 hasattr(X, 'columns')):


'and for transform when using the '                                  'remainder keyword') <ins>        self._validate_features(X.shape[1], X_feature_names)</ins>         Xs = self._fit_transform(X, None, _transform_one, fitted=True)         self._validate_output(Xs)


remainder=remainder,                              sparse_threshold=sparse_threshold,                              verbose=verbose)<ins>def _is_negative_indexing(key):    # TODO: remove in v0.24    def is_neg(x): return isinstance(x, numbers.Integral) and x < 0    if isinstance(key, slice):        return is_neg(key.start) or is_neg(key.stop)    elif _check_key_type(key, int):        return np.any(np.asarray(key) < 0)    return False</ins>


model.alpha = best_alpha         model.l1_ratio = best_l1_ratio         model.copy_X = copy_X        model.precompute = False        precompute = getattr(self, "precompute", None)        if isinstance(precompute, str) and precompute == "auto":            model.precompute = False         model.fit(X, y)         if not hasattr(self, 'l1_ratio'):             del self.l1_ratio_


def __init__(self, estimator, n_jobs=None):         super().__init__(estimator, n_jobs) <ins>    def fit(self, X, Y, sample_weight=None):        """Fit the model to data matrix X and targets Y.        Parameters        ----------        X : {array-like, sparse matrix} of shape (n_samples, n_features)            The input data.        Y : array-like of shape (n_samples, n_classes)            The target values.        sample_weight : array-like of shape (n_samples,) or None            Sample weights. If None, then samples are equally weighted.            Only supported if the underlying classifier supports sample            weights.        Returns        -------        self : object        """        super().fit(X, Y, sample_weight)        self.classes_ = [estimator.classes_ for estimator in self.estimators_]        return self</ins>     def predict_proba(self, X):         """Probability estimates.         Returns prediction probabilities for each class of each output.


if self.order_ == 'random':                 self.order_ = random_state.permutation(Y.shape[1])         elif sorted(self.order_) != list(range(Y.shape[1])):                raise ValueError("invalid order")            raise ValueError("invalid order")          self.estimators_ = [clone(self.base_estimator)                             for _ in range(Y.shape[1])]


Notes     -----    Train and test sizes may be different in each fold, with a difference of at    most ``n_classes``.    The implementation is designed to:    * Generate test sets such that all contain the same distribution of      classes, or as close as possible.    * Be invariant to class label: relabelling ``y = ["Happy", "Sad"]`` to      ``y = [1, 0]`` should not change the indices generated.    * Preserve order dependencies in the dataset ordering, when      ``shuffle=False``: all samples from class k in some test set were      contiguous in y, or separated in y by samples from classes other than k.    * Generate test sets where the smallest and largest differ by at most one      sample.    .. versionchanged:: 0.22        The previous implementation did not follow the last constraint.      See also     --------


allowed_target_types, type_of_target_y))          y = column_or_1d(y)        n_samples = y.shape[0]        unique_y, y_inversed = np.unique(y, return_inverse=True)        y_counts = np.bincount(y_inversed)        _, y_idx, y_inv = np.unique(y, return_index=True, return_inverse=True)        # y_inv encodes y according to lexicographic order. We invert y_idx to        # map the classes so that they are encoded by order of appearance:        # 0 represents the first label appearing in y, 1 the second, etc.        _, class_perm = np.unique(y_idx, return_inverse=True)        y_encoded = class_perm[y_inv]        n_classes = len(y_idx)        y_counts = np.bincount(y_encoded)         min_groups = np.min(y_counts)         if np.all(self.n_splits > y_counts):             raise ValueError("n_splits=%d cannot be greater than the"


% (self.n_splits))         if self.n_splits > min_groups:             warnings.warn(("The least populated class in y has only %d"                           " members, which is too few. The minimum"                           " number of members in any class cannot"                           " be less than n_splits=%d."                           % (min_groups, self.n_splits)), Warning)        # pre-assign each sample to a test fold index using individual KFold        # splitting strategies for each class so as to respect the balance of        # classes        # NOTE: Passing the data corresponding to ith class say X[y==class_i]        # will break when the data is not 100% stratifiable for all classes.        # So we pass np.zeroes(max(c, n_splits)) as data to the KFold        per_cls_cvs = [            KFold(self.n_splits, shuffle=self.shuffle,                  random_state=rng).split(np.zeros(max(count, self.n_splits)))            for count in y_counts]        test_folds = np.zeros(n_samples, dtype=np.int)        for test_fold_indices, per_cls_splits in enumerate(zip(*per_cls_cvs)):            for cls, (_, test_split) in zip(unique_y, per_cls_splits):                cls_test_folds = test_folds[y == cls]                # the test split can be too big because we used                # KFold(...).split(X[:max(c, n_splits)]) when data is not 100%                # stratifiable for all the classes                # (we use a warning instead of raising an exception)                # If this is the case, let's trim it:                test_split = test_split[test_split < len(cls_test_folds)]                cls_test_folds[test_split] = test_fold_indices                test_folds[y == cls] = cls_test_folds                           " members, which is less than n_splits=%d."                           % (min_groups, self.n_splits)), UserWarning)        # Determine the optimal number of samples from each class in each fold,        # using round robin over the sorted y. (This can be done direct from        # counts, but that code is unreadable.)        y_order = np.sort(y_encoded)        allocation = np.asarray(            [np.bincount(y_order[i::self.n_splits], minlength=n_classes)             for i in range(self.n_splits)])        # To maintain the data order dependencies as best as possible within        # the stratification constraint, we assign samples from each class in        # blocks (and then mess that up when shuffle=True).        test_folds = np.empty(len(y), dtype='i')        for k in range(n_classes):            # since the kth column of allocation stores the number of samples            # of class k in each test set, this generates blocks of fold            # indices corresponding to the allocation for class k.            folds_for_class = np.arange(self.n_splits).repeat(allocation[:, k])            if self.shuffle:                rng.shuffle(folds_for_class)            test_folds[y_encoded == k] = folds_for_class         return test_folds      def _iter_test_masks(self, X, y=None, groups=None):


sklearn.metrics.pairwise.kernel_metrics : List of built-in kernels.     """<ins></ins>     def __init__(self, kernel="rbf", gamma=None, coef0=None, degree=None,                  kernel_params=None, n_components=100, random_state=None):         self.kernel = kernel


params = self.kernel_params         if params is None:             params = {}        if not callable(self.kernel):        if not callable(self.kernel) and self.kernel != 'precomputed':             for param in (KERNEL_PARAMS[self.kernel]):                 if getattr(self, param) is not None:                     params[param] = getattr(self, param)


self.coef0 is not None or                     self.degree is not None):                 raise ValueError("Don't pass gamma, coef0 or degree to "                                 "Nystroem if using a callable kernel.")                                 "Nystroem if using a callable "                                 "or precomputed kernel")          return params


Scores are computed on validation data or on training data.         """        if is_classifier(self):            y_small_train = self.classes_[y_small_train.astype(int)]         self.train_score_.append(             self.scorer_(self, X_binned_small_train, y_small_train)         )          if self._use_validation_data:            if is_classifier(self):                y_val = self.classes_[y_val.astype(int)]             self.validation_score_.append(                 self.scorer_(self, X_binned_val, y_val)             )


sample_weight, multioutput)  def median_absolute_error(y_true, y_pred):def median_absolute_error(y_true, y_pred, multioutput='uniform_average'):     """Median absolute error regression loss     Read more in the :ref:`User Guide <median_absolute_error>`.    Median absolute error output is non-negative floating point. The best value    is 0.0. Read more in the :ref:`User Guide <median_absolute_error>`.      Parameters     ----------    y_true : array-like of shape (n_samples,)    y_true : array-like of shape = (n_samples) or (n_samples, n_outputs)         Ground truth (correct) target values.     y_pred : array-like of shape (n_samples,)    y_pred : array-like of shape = (n_samples) or (n_samples, n_outputs)         Estimated target values.     multioutput : {'raw_values', 'uniform_average'} or array-like of shape        (n_outputs,)        Defines aggregating of multiple output values. Array-like value defines        weights used to average errors.        'raw_values' :            Returns a full set of errors in case of multioutput input.        'uniform_average' :            Errors of all outputs are averaged with uniform weight.     Returns     -------    loss : float        A positive floating point value (the best value is 0.0).    loss : float or ndarray of floats        If multioutput is 'raw_values', then mean absolute error is returned        for each output separately.        If multioutput is 'uniform_average' or an ndarray of weights, then the        weighted average of all output errors is returned.      Examples     --------


>>> y_pred = [2.5, 0.0, 2, 8]     >>> median_absolute_error(y_true, y_pred)     0.5    >>> y_true = [[0.5, 1], [-1, 1], [7, -6]]    >>> y_pred = [[0, 2], [-1, 2], [8, -5]]    >>> median_absolute_error(y_true, y_pred)    0.75    >>> median_absolute_error(y_true, y_pred, multioutput='raw_values')    array([0.5, 1. ])    >>> median_absolute_error(y_true, y_pred, multioutput=[0.3, 0.7])    0.85      """    y_type, y_true, y_pred, _ = _check_reg_targets(y_true, y_pred, None)    if y_type == 'continuous-multioutput':        raise ValueError("Multioutput not supported in median_absolute_error")    return np.median(np.abs(y_pred - y_true))    y_type, y_true, y_pred, multioutput = _check_reg_targets(        y_true, y_pred, multioutput)    output_errors = np.median(np.abs(y_pred - y_true), axis=0)    if isinstance(multioutput, str):        if multioutput == 'raw_values':            return output_errors        elif multioutput == 'uniform_average':            # pass None as weights to np.average: uniform mean            multioutput = None    return np.average(output_errors, weights=multioutput)   def explained_variance_score(y_true, y_pred,


n_clusters_per_class : int, optional (default=2)         The number of clusters per class.     weights : list of floats or None (default=None)    weights : array-like of shape (n_classes,) or (n_classes - 1,),\              (default=None)         The proportions of samples assigned to each class. If None, then         classes are balanced. Note that if ``len(weights) == n_classes - 1``,         then the last class weight is automatically inferred.


" features")     # Use log2 to avoid overflow errors     if n_informative < np.log2(n_classes * n_clusters_per_class):        raise ValueError("n_classes * n_clusters_per_class must"                         " be smaller or equal 2 ** n_informative")    if weights and len(weights) not in [n_classes, n_classes - 1]:        raise ValueError("Weights specified but incompatible with number "                         "of classes.")        msg = "n_classes({}) * n_clusters_per_class({}) must be"        msg += " smaller or equal 2**n_informative({})={}"        raise ValueError(msg.format(n_classes, n_clusters_per_class,                                    n_informative, 2**n_informative))    if weights is not None:        if len(weights) not in [n_classes, n_classes - 1]:            raise ValueError("Weights specified but incompatible with number "                             "of classes.")        if len(weights) == n_classes - 1:            if isinstance(weights, list):                weights = weights + [1.0 - sum(weights)]            else:                weights = np.resize(weights, n_classes)                weights[-1] = 1.0 - sum(weights[:-1])    else:        weights = [1.0 / n_classes] * n_classes      n_useless = n_features - n_informative - n_redundant - n_repeated     n_clusters = n_classes * n_clusters_per_class     if weights and len(weights) == (n_classes - 1):        weights = weights + [1.0 - sum(weights)]    if weights is None:        weights = [1.0 / n_classes] * n_classes        weights[-1] = 1.0 - sum(weights[:-1])     # Distribute samples among clusters by weight     n_samples_per_cluster = [         int(n_samples * weights[k % n_classes] / n_clusters_per_class)


"random"             A random order for each round. <ins>    skip_complete : boolean, optional (default=False)        If ``True`` then features with missing values during ``transform``        which did not have any missing values during ``fit`` will be imputed        with the initial imputation method only. Set to ``True`` if you have        many features with no missing values at both ``fit`` and ``transform``        time to save compute.</ins>     min_value : float, optional (default=None)         Minimum possible imputed value. Default of ``None`` will set minimum         to negative infinity.


Indicator used to add binary indicators for missing values.         ``None`` if add_indicator is False. <ins>    random_state_ : RandomState instance        RandomState instance that is generated either from a seed, the random        number generator or by `np.random`.</ins>     See also     --------     SimpleImputer : Univariate imputation of missing values.


Features which contain all missing values at ``fit`` are discarded upon     ``transform``. <del>    Features with missing values during ``transform`` which did not have any    missing values during ``fit`` will be imputed with the initial imputation    method only.</del>     References     ----------     .. [1] `Stef van Buuren, Karin Groothuis-Oudshoorn (2011). "mice:


n_nearest_features=None,                  initial_strategy="mean",                  imputation_order='ascending',<ins>                 skip_complete=False,</ins>                  min_value=None,                  max_value=None,                  verbose=0,


self.n_nearest_features = n_nearest_features         self.initial_strategy = initial_strategy         self.imputation_order = imputation_order<ins>        self.skip_complete = skip_complete</ins>         self.min_value = min_value         self.max_value = max_value         self.verbose = verbose


The fitted estimator used to impute             ``X_filled[missing_row_mask, feat_idx]``.         """<del>        # if nothing is missing, just return the default        # (should not happen at fit time because feat_ids would be excluded)        missing_row_mask = mask_missing_values[:, feat_idx]        if not np.any(missing_row_mask):            return X_filled, estimator</del>         if estimator is None and fit_mode is False:             raise ValueError("If fit_mode is False, then an already-fitted "                              "estimator should be passed in.")


if estimator is None:             estimator = clone(self._estimator) <ins>        missing_row_mask = mask_missing_values[:, feat_idx]</ins>         if fit_mode:             X_train = safe_indexing(X_filled[:, neighbor_feat_idx],                                     ~missing_row_mask)


~missing_row_mask)             estimator.fit(X_train, y_train)         # get posterior samples        # if no missing values, don't predict        if np.sum(missing_row_mask) == 0:            return X_filled, estimator        # get posterior samples if there is at least one missing value         X_test = safe_indexing(X_filled[:, neighbor_feat_idx],                                missing_row_mask)         if self.sample_posterior:             mus, sigmas = estimator.predict(X_test, return_std=True)             imputed_values = np.zeros(mus.shape, dtype=X_filled.dtype)            # two types of problems: (1) non-positive sigmas, (2) mus outside            # legal range of min_value and max_value (results in inf sample)            # two types of problems: (1) non-positive sigmas            # (2) mus outside legal range of min_value and max_value            # (results in inf sample)             positive_sigmas = sigmas > 0             imputed_values[~positive_sigmas] = mus[~positive_sigmas]             mus_too_low = mus < self._min_value


The order in which to impute the features.         """         frac_of_missing_values = mask_missing_values.mean(axis=0)        missing_values_idx = np.nonzero(frac_of_missing_values)[0]        if self.skip_complete:            missing_values_idx = np.flatnonzero(frac_of_missing_values)        else:            missing_values_idx = np.arange(np.shape(frac_of_missing_values)[0])         if self.imputation_order == 'roman':             ordered_idx = missing_values_idx         elif self.imputation_order == 'arabic':


self.initial_imputer_ = None         X, Xt, mask_missing_values = self._initial_imputation(X)         if self.max_iter == 0 or np.all(mask_missing_values):             self.n_iter_ = 0             return Xt         # Edge case: a single feature. We return the initial ...        if Xt.shape[1] == 1:            self.n_iter_ = 0            return Xt         # order in which to impute         # note this is probably too slow for large feature data (d > 100000)         # and a better way would be good.


return encoded_y      def _get_loss(self):<ins>        if (self.loss == 'categorical_crossentropy' and                self.n_trees_per_iteration_ == 1):            raise ValueError("'categorical_crossentropy' is not suitable for "                             "a binary classification problem. Please use "                             "'auto' or 'binary_crossentropy' instead.")</ins>         if self.loss == 'auto':             if self.n_trees_per_iteration_ == 1:                 return _LOSSES['binary_crossentropy']()


" you are sure you want to proceed regardless"                               ", set 'check_inverse=False'", UserWarning)     def fit(self, X, y, sample_weight=None):    def fit(self, X, y, **fit_params):         """Fit the model according to the given training data.          Parameters


y : array-like, shape (n_samples,)             Target values.         sample_weight : array-like, shape (n_samples,) optional            Array of weights that are assigned to individual samples.            If not provided, then each sample is given unit weight.        **fit_params : dict of string -> object            Parameters passed to the ``fit`` method of the underlying            regressor.          Returns         -------


else:             self.regressor_ = clone(self.regressor)         if sample_weight is None:            self.regressor_.fit(X, y_trans)        else:            self.regressor_.fit(X, y_trans, sample_weight=sample_weight)        self.regressor_.fit(X, y_trans, **fit_params)          return self


n_SV = self.support_vectors_.shape[0]          dual_coef_indices = np.tile(np.arange(n_SV), n_class)        dual_coef_indptr = np.arange(0, dual_coef_indices.size + 1,                                     dual_coef_indices.size / n_class)        self.dual_coef_ = sp.csr_matrix(            (dual_coef_data, dual_coef_indices, dual_coef_indptr),            (n_class, n_SV))        if not n_SV:            self.dual_coef_ = sp.csr_matrix([])        else:            dual_coef_indptr = np.arange(0, dual_coef_indices.size + 1,                                         dual_coef_indices.size / n_class)            self.dual_coef_ = sp.csr_matrix(                (dual_coef_data, dual_coef_indices, dual_coef_indptr),                (n_class, n_SV))      def predict(self, X):         """Perform regression on samples in X.


raise ValueError("y_prob contains values less than 0.")      # if pos_label=None, when y_true is in {-1, 1} or {0, 1},    # pos_labe is set to 1 (consistent with precision_recall_curve/roc_curve),    # pos_label is set to 1 (consistent with precision_recall_curve/roc_curve),     # otherwise pos_label is set to the greater label     # (different from precision_recall_curve/roc_curve,     # the purpose is to keep backward compatibility).diff --git a/sklearn/metrics/scorer.py b/sklearn/metrics/scorer.py-- a/sklearn/metrics/scorer.py++ b/sklearn/metrics/scorer.py


from collections.abc import Iterable from functools import partial from collections import Counter<ins>import warnings</ins>  import numpy as np


self._kwargs = kwargs         self._score_func = score_func         self._sign = sign<ins>        # XXX After removing the deprecated scorers (v0.24) remove the        # XXX deprecation_msg property again and remove __call__'s body again        self._deprecation_msg = None</ins>      def __repr__(self):         kwargs_string = "".join([", %s=%s" % (str(k), str(v))


score : float             Score function applied to prediction of estimator on X.         """<ins>        if self._deprecation_msg is not None:            warnings.warn(self._deprecation_msg,                          category=DeprecationWarning,                          stacklevel=2)</ins>         return self._score(partial(_cached_call, None), estimator, X, y_true,                            sample_weight=sample_weight)


score : float             Score function applied to prediction of estimator on X.         """<ins></ins>         y_pred = method_caller(estimator, "predict", X)         if sample_weight is not None:             return self._sign * self._score_func(y_true, y_pred,


score : float             Score function applied to prediction of estimator on X.         """<ins></ins>         y_type = type_of_target(y)         y_pred = method_caller(clf, "predict_proba", X)         if y_type == "binary":


score : float             Score function applied to prediction of estimator on X.         """<ins></ins>         y_type = type_of_target(y)         if y_type not in ("binary", "multilabel-indicator"):             raise ValueError("{0} format is not supported".format(y_type))


"""     if isinstance(scoring, str):         try:            scorer = SCORERS[scoring]            if scoring == 'brier_score_loss':                # deprecated                scorer = brier_score_loss_scorer            else:                scorer = SCORERS[scoring]         except KeyError:             raise ValueError('%r is not a valid scoring value. '                              'Use sorted(sklearn.metrics.SCORERS.keys()) '                             'to get valid options.' % (scoring))                             'to get valid options.' % scoring)     else:         scorer = scoring     return scorer


# Score function for probabilistic classification neg_log_loss_scorer = make_scorer(log_loss, greater_is_better=False,                                   needs_proba=True)neg_brier_score_scorer = make_scorer(brier_score_loss,                                     greater_is_better=False,                                     needs_proba=True) brier_score_loss_scorer = make_scorer(brier_score_loss,                                       greater_is_better=False,                                       needs_proba=True)deprecation_msg = ('Scoring method brier_score_loss was renamed to '                   'neg_brier_score in version 0.22 and will '                   'be removed in 0.24.')brier_score_loss_scorer._deprecation_msg = deprecation_msg   # Clustering scores


balanced_accuracy=balanced_accuracy_scorer,                average_precision=average_precision_scorer,                neg_log_loss=neg_log_loss_scorer,               brier_score_loss=brier_score_loss_scorer,               neg_brier_score=neg_brier_score_scorer,                # Cluster metrics that use supervised evaluation                adjusted_rand_score=adjusted_rand_scorer,                homogeneity_score=homogeneity_scorer,


self.n_classes_,          self.class_prior_) = class_distribution(y, sample_weight)         if (self.strategy == "constant" and                any(constant[k] not in self.classes_[k]                    for k in range(self.n_outputs_))):            # Checking in case of constant strategy if the constant            # provided by the user is in y.            raise ValueError("The constant target value must be "                             "present in training data")        if self.strategy == "constant":            for k in range(self.n_outputs_):                if not any(constant[k][0] == c for c in self.classes_[k]):                    # Checking in case of constant strategy if the constant                    # provided by the user is in y.                    err_msg = ("The constant target value must be present in "                               "the training data. You provided constant={}. "                               "Possible values are: {}."                               .format(self.constant, list(self.classes_[k])))                    raise ValueError(err_msg)          if self.n_outputs_ == 1 and not self.output_2d_:             self.n_classes_ = self.n_classes_[0]


**self.cvargs)         return cv.get_n_splits(X, y, groups) * self.n_repeats <ins>    def __repr__(self):        return _build_repr(self)</ins>  class RepeatedKFold(_RepeatedSplits):     """Repeated K-Fold cross validator.


try:             with warnings.catch_warnings(record=True) as w:                 value = getattr(self, key, None)<ins>                if value is None and hasattr(self, 'cvargs'):                    value = self.cvargs.get(key, None)</ins>             if len(w) and w[0].category == DeprecationWarning:                 # if the parameter is deprecated, don't show it                 continue


X, y = check_X_y(X, y, dtype=[X_DTYPE], force_all_finite=False)         y = self._encode_y(y)         # The rng state must be preserved if warm_start is True        if (self.warm_start and hasattr(self, '_rng')):            rng = self._rng        else:            rng = check_random_state(self.random_state)            self._rng = rng        rng = check_random_state(self.random_state)        # When warm starting, we want to re-use the same seed that was used        # the first time fit was called (e.g. for subsampling or for the        # train/val split).        if not (self.warm_start and self._is_fitted()):            self._random_seed = rng.randint(np.iinfo(np.uint32).max,                                            dtype='u8')          self._validate_parameters()         self.n_features_ = X.shape[1]  # used for validation in predict()


# Save the state of the RNG for the training and validation split.             # This is needed in order to have the same split when using             # warm starting.            if not (self._is_fitted() and self.warm_start):                self._train_val_split_seed = rng.randint(1024)              X_train, X_val, y_train, y_val = train_test_split(                 X, y, test_size=self.validation_fraction, stratify=stratify,                random_state=self._train_val_split_seed)                random_state=self._random_seed)         else:             X_train, y_train = X, y             X_val, y_val = None, None


# actual total number of bins. Everywhere in the code, the         # convention is that n_bins == max_bins + 1         n_bins = self.max_bins + 1  # + 1 for missing values        self.bin_mapper_ = _BinMapper(n_bins=n_bins, random_state=rng)        X_binned_train = self._bin_data(X_train, rng, is_training_data=True)        self.bin_mapper_ = _BinMapper(n_bins=n_bins,                                      random_state=self._random_seed)        X_binned_train = self._bin_data(X_train, is_training_data=True)         if X_val is not None:            X_binned_val = self._bin_data(X_val, rng, is_training_data=False)            X_binned_val = self._bin_data(X_val, is_training_data=False)         else:             X_binned_val = None


# the predictions of all the trees. So we use a subset of                     # the training set to compute train scores.                     # Save the seed for the small trainset generator                    self._small_trainset_seed = rng.randint(1024)                     # Compute the subsample set                     (X_binned_small_train,                      y_small_train) = self._get_small_trainset(                        X_binned_train, y_train, self._small_trainset_seed)                        X_binned_train, y_train, self._random_seed)                      self._check_early_stopping_scorer(                         X_binned_small_train, y_small_train,


if self.do_early_stopping_ and self.scoring != 'loss':                 # Compute the subsample set                 X_binned_small_train, y_small_train = self._get_small_trainset(                    X_binned_train, y_train, self._small_trainset_seed)                    X_binned_train, y_train, self._random_seed)              # Initialize the gradients and hessians             gradients, hessians = self.loss_.init_gradients_and_hessians(


def _clear_state(self):         """Clear the state of the gradient boosting model."""        for var in ('train_score_', 'validation_score_', '_rng'):        for var in ('train_score_', 'validation_score_'):             if hasattr(self, var):                 delattr(self, var)


for score in recent_scores]         return not any(recent_improvements)     def _bin_data(self, X, rng, is_training_data):    def _bin_data(self, X, is_training_data):         """Bin data X.          If is_training_data, then set the bin_mapper_ attribute.


import numpy as np  from ..utils.validation import check_is_fitted<ins>from ..base import is_classifier</ins>  from . import _criterion from . import _tree


"""     check_is_fitted(decision_tree)     tree_ = decision_tree.tree_    class_names = decision_tree.classes_    if is_classifier(decision_tree):        class_names = decision_tree.classes_     right_child_fmt = "{} {} <= {}\n"     left_child_fmt = "{} {} >  {}\n"     truncation_fmt = "{} {}\n"diff --git a/sklearn/tree/tree.py b/sklearn/tree/tree.py-- a/sklearn/tree/tree.py++ b/sklearn/tree/tree.py


expanded_class_weight = compute_sample_weight(                     self.class_weight, y_original)         else:            self.classes_ = [None] * self.n_outputs_            self.n_classes_ = [1] * self.n_outputs_        self.n_classes_ = np.array(self.n_classes_, dtype=np.intp)            self.n_classes_ = np.array(self.n_classes_, dtype=np.intp)          if getattr(y, "dtype", None) != DOUBLE or not y.flags.contiguous:             y = np.ascontiguousarray(y, dtype=DOUBLE)


min_weight_leaf,                                                 random_state)         self.tree_ = Tree(self.n_features_, self.n_classes_, self.n_outputs_)        if is_classifier(self):            self.tree_ = Tree(self.n_features_,                              self.n_classes_, self.n_outputs_)        else:            self.tree_ = Tree(self.n_features_,                              # TODO: tree should't need this in this case                              np.array([1] * self.n_outputs_, dtype=np.intp),                              self.n_outputs_)          # Use BestFirst if max_leaf_nodes given; use DepthFirst otherwise         if max_leaf_nodes < 0:


builder.build(self.tree_, X, y, sample_weight, X_idx_sorted)         if self.n_outputs_ == 1:        if self.n_outputs_ == 1 and is_classifier(self):             self.n_classes_ = self.n_classes_[0]             self.classes_ = self.classes_[0]


if self.ccp_alpha == 0.0:             return         # build pruned treee        n_classes = np.atleast_1d(self.n_classes_)        pruned_tree = Tree(self.n_features_, n_classes, self.n_outputs_)        # build pruned tree        if is_classifier(self):            n_classes = np.atleast_1d(self.n_classes_)            pruned_tree = Tree(self.n_features_, n_classes, self.n_outputs_)        else:            pruned_tree = Tree(self.n_features_,                               # TODO: the tree shouldn't need this param                               np.array([1] * self.n_outputs_, dtype=np.intp),                               self.n_outputs_)         _build_pruned_tree_ccp(pruned_tree, self.tree_, self.ccp_alpha)          self.tree_ = pruned_tree


X_idx_sorted=X_idx_sorted)         return self <ins>    @property    def classes_(self):        # TODO: Remove method in 0.24        msg = ("the classes_ attribute is to be deprecated from version "               "0.22 and will be removed in 0.24.")        warnings.warn(msg, DeprecationWarning)        return np.array([None] * self.n_outputs_)    @property    def n_classes_(self):        # TODO: Remove method in 0.24        msg = ("the n_classes_ attribute is to be deprecated from version "               "0.22 and will be removed in 0.24.")        warnings.warn(msg, DeprecationWarning)        return np.array([1] * self.n_outputs_, dtype=np.intp)</ins>  class ExtraTreeClassifier(DecisionTreeClassifier):     """An extremely randomized tree classifier.


# Let us not impose fortran ordering so far: it is             # not useful for the cross-validation loop and will be done             # by the model fitting itself            X = check_array(X, 'csc', copy=False)            X = check_array(X, 'csc', dtype=[np.float64, np.float32],                            copy=False)             if sparse.isspmatrix(X):                 if (hasattr(reference_to_old_X, "data") and                    not np.may_share_memory(reference_to_old_X.data, X.data)):


dtypes_orig = None     if hasattr(array, "dtypes") and hasattr(array.dtypes, '__array__'):         dtypes_orig = np.array(array.dtypes)<ins>        if all(isinstance(dtype, np.dtype) for dtype in dtypes_orig):            dtype_orig = np.result_type(*array.dtypes)</ins>      if dtype_numeric:         if dtype_orig is not None and dtype_orig.kind == "O":


self.best_params_ = results["params"][self.best_index_]          if self.refit:            self.best_estimator_ = clone(base_estimator).set_params(                **self.best_params_)            # we clone again after setting params in case some            # of the params are estimators as well.            self.best_estimator_ = clone(clone(base_estimator).set_params(                **self.best_params_))             refit_start_time = time.time()             if y is not None:                 self.best_estimator_.fit(X, y, **fit_params)diff --git a/sklearn/model_selection/_validation.py b/sklearn/model_selection/_validation.py-- a/sklearn/model_selection/_validation.py++ b/sklearn/model_selection/_validation.py


train_scores = {}     if parameters is not None:        estimator.set_params(**parameters)        # clone after setting parameters in case any parameters        # are estimators (like pipeline steps)        # because pipeline doesn't clone steps in fit        cloned_parameters = {}        for k, v in parameters.items():            cloned_parameters[k] = clone(v, safe=False)        estimator = estimator.set_params(**cloned_parameters)      start_time = time.time()


Remove accentuated char for any unicode symbol that has a direct         ASCII equivalent.     """    normalized = unicodedata.normalize('NFKD', s)    if normalized == s:    try:        # If `s` is ASCII-compatible, then it does not contain any accented        # characters and we can avoid an expensive list comprehension        s.encode("ASCII", errors="strict")         return s    else:    except UnicodeEncodeError:        normalized = unicodedata.normalize('NFKD', s)         return ''.join([c for c in normalized if not unicodedata.combining(c)])


trans.get_feature_names()])         return feature_names     def fit(self, X, y=None):    def fit(self, X, y=None, **fit_params):         """Fit all transformers using X.          Parameters


self : FeatureUnion             This estimator         """        transformers = self._parallel_func(X, y, {}, _fit_one)        transformers = self._parallel_func(X, y, fit_params, _fit_one)         if not transformers:             # All transformers are None             return self


# If converged or at max_iter, adds the cluster         if (np.linalg.norm(my_mean - my_old_mean) < stop_thresh or                 completed_iterations == max_iter):            return tuple(my_mean), len(points_within)            break         completed_iterations += 1    return tuple(my_mean), len(points_within), completed_iterations   def mean_shift(X, bandwidth=None, seeds=None, bin_seeding=False,


<sphx_glr_auto_examples_cluster_plot_mean_shift.py>`.      """    if bandwidth is None:        bandwidth = estimate_bandwidth(X, n_jobs=n_jobs)    elif bandwidth <= 0:        raise ValueError("bandwidth needs to be greater than zero or None,"                         " got %f" % bandwidth)    if seeds is None:        if bin_seeding:            seeds = get_bin_seeds(X, bandwidth, min_bin_freq)        else:            seeds = X    n_samples, n_features = X.shape    center_intensity_dict = {}    # We use n_jobs=1 because this will be used in nested calls under    # parallel calls to _mean_shift_single_seed so there is no need for    # for further parallelism.    nbrs = NearestNeighbors(radius=bandwidth, n_jobs=1).fit(X)    # execute iterations on all seeds in parallel    all_res = Parallel(n_jobs=n_jobs)(        delayed(_mean_shift_single_seed)        (seed, X, nbrs, max_iter) for seed in seeds)    # copy results in a dictionary    for i in range(len(seeds)):        if all_res[i] is not None:            center_intensity_dict[all_res[i][0]] = all_res[i][1]    if not center_intensity_dict:        # nothing near seeds        raise ValueError("No point was within bandwidth=%f of any seed."                         " Try a different seeding strategy \                         or increase the bandwidth."                         % bandwidth)    # POST PROCESSING: remove near duplicate points    # If the distance between two kernels is less than the bandwidth,    # then we have to remove one because it is a duplicate. Remove the    # one with fewer points.    sorted_by_intensity = sorted(center_intensity_dict.items(),                                 key=lambda tup: (tup[1], tup[0]),                                 reverse=True)    sorted_centers = np.array([tup[0] for tup in sorted_by_intensity])    unique = np.ones(len(sorted_centers), dtype=np.bool)    nbrs = NearestNeighbors(radius=bandwidth,                            n_jobs=n_jobs).fit(sorted_centers)    for i, center in enumerate(sorted_centers):        if unique[i]:            neighbor_idxs = nbrs.radius_neighbors([center],                                                  return_distance=False)[0]            unique[neighbor_idxs] = 0            unique[i] = 1  # leave the current point as unique    cluster_centers = sorted_centers[unique]    # ASSIGN LABELS: a point belongs to the cluster that it is closest to    nbrs = NearestNeighbors(n_neighbors=1, n_jobs=n_jobs).fit(cluster_centers)    labels = np.zeros(n_samples, dtype=np.int)    distances, idxs = nbrs.kneighbors(X)    if cluster_all:        labels = idxs.flatten()    else:        labels.fill(-1)        bool_selector = distances.flatten() <= bandwidth        labels[bool_selector] = idxs.flatten()[bool_selector]    return cluster_centers, labels    model = MeanShift(bandwidth=bandwidth, seeds=seeds,                      min_bin_freq=min_bin_freq,                      bin_seeding=bin_seeding,                      cluster_all=cluster_all, n_jobs=n_jobs,                      max_iter=max_iter).fit(X)    return model.cluster_centers_, model.labels_   def get_bin_seeds(X, bin_size, min_bin_freq=1):


``-1`` means using all processors. See :term:`Glossary <n_jobs>`         for more details. <ins>    max_iter : int, default=300        Maximum number of iterations, per seed point before the clustering        operation terminates (for that seed point), if has not converged yet.        .. versionadded:: 0.22</ins>     Attributes     ----------     cluster_centers_ : array, [n_clusters, n_features]


labels_ :         Labels of each point. <ins>    n_iter_ : int        Maximum number of iterations performed on each seed.        .. versionadded:: 0.22</ins>     Examples     --------     >>> from sklearn.cluster import MeanShift


"""     def __init__(self, bandwidth=None, seeds=None, bin_seeding=False,                 min_bin_freq=1, cluster_all=True, n_jobs=None):                 min_bin_freq=1, cluster_all=True, n_jobs=None, max_iter=300):         self.bandwidth = bandwidth         self.seeds = seeds         self.bin_seeding = bin_seeding         self.cluster_all = cluster_all         self.min_bin_freq = min_bin_freq         self.n_jobs = n_jobs        self.max_iter = max_iter      def fit(self, X, y=None):         """Perform clustering.


"""         X = check_array(X)        self.cluster_centers_, self.labels_ = \            mean_shift(X, bandwidth=self.bandwidth, seeds=self.seeds,                       min_bin_freq=self.min_bin_freq,                       bin_seeding=self.bin_seeding,                       cluster_all=self.cluster_all, n_jobs=self.n_jobs)        bandwidth = self.bandwidth        if bandwidth is None:            bandwidth = estimate_bandwidth(X, n_jobs=self.n_jobs)        elif bandwidth <= 0:            raise ValueError("bandwidth needs to be greater than zero or None,"                             " got %f" % bandwidth)        seeds = self.seeds        if seeds is None:            if self.bin_seeding:                seeds = get_bin_seeds(X, bandwidth, self.min_bin_freq)            else:                seeds = X        n_samples, n_features = X.shape        center_intensity_dict = {}        # We use n_jobs=1 because this will be used in nested calls under        # parallel calls to _mean_shift_single_seed so there is no need for        # for further parallelism.        nbrs = NearestNeighbors(radius=bandwidth, n_jobs=1).fit(X)        # execute iterations on all seeds in parallel        all_res = Parallel(n_jobs=self.n_jobs)(            delayed(_mean_shift_single_seed)            (seed, X, nbrs, self.max_iter) for seed in seeds)        # copy results in a dictionary        for i in range(len(seeds)):            if all_res[i][1]:  # i.e. len(points_within) > 0                center_intensity_dict[all_res[i][0]] = all_res[i][1]        self.n_iter_ = max([x[2] for x in all_res])        if not center_intensity_dict:            # nothing near seeds            raise ValueError("No point was within bandwidth=%f of any seed."                             " Try a different seeding strategy \                             or increase the bandwidth."                             % bandwidth)        # POST PROCESSING: remove near duplicate points        # If the distance between two kernels is less than the bandwidth,        # then we have to remove one because it is a duplicate. Remove the        # one with fewer points.        sorted_by_intensity = sorted(center_intensity_dict.items(),                                     key=lambda tup: (tup[1], tup[0]),                                     reverse=True)        sorted_centers = np.array([tup[0] for tup in sorted_by_intensity])        unique = np.ones(len(sorted_centers), dtype=np.bool)        nbrs = NearestNeighbors(radius=bandwidth,                                n_jobs=self.n_jobs).fit(sorted_centers)        for i, center in enumerate(sorted_centers):            if unique[i]:                neighbor_idxs = nbrs.radius_neighbors([center],                                                      return_distance=False)[0]                unique[neighbor_idxs] = 0                unique[i] = 1  # leave the current point as unique        cluster_centers = sorted_centers[unique]        # ASSIGN LABELS: a point belongs to the cluster that it is closest to        nbrs = NearestNeighbors(n_neighbors=1,                                n_jobs=self.n_jobs).fit(cluster_centers)        labels = np.zeros(n_samples, dtype=np.int)        distances, idxs = nbrs.kneighbors(X)        if self.cluster_all:            labels = idxs.flatten()        else:            labels.fill(-1)            bool_selector = distances.flatten() <= bandwidth            labels[bool_selector] = idxs.flatten()[bool_selector]        self.cluster_centers_, self.labels_ = cluster_centers, labels         return self      def predict(self, X):


import numpy as np from joblib import Parallel, delayed<ins>import scipy.sparse as sparse</ins>  from ..base import clone from ..base import ClassifierMixin, RegressorMixin, TransformerMixin


@abstractmethod     def __init__(self, estimators, final_estimator=None, cv=None,                 stack_method='auto', n_jobs=None, verbose=0):                 stack_method='auto', n_jobs=None, verbose=0,                 passthrough=False):         super().__init__(estimators=estimators)         self.final_estimator = final_estimator         self.cv = cv         self.stack_method = stack_method         self.n_jobs = n_jobs         self.verbose = verbose        self.passthrough = passthrough      def _clone_final_estimator(self, default):         if self.final_estimator is not None:


else:             self.final_estimator_ = clone(default)     def _concatenate_predictions(self, predictions):        """Concatenate the predictions of each first layer learner.    def _concatenate_predictions(self, X, predictions):        """Concatenate the predictions of each first layer learner and        possibly the input dataset `X`.        If `X` is sparse and `self.passthrough` is False, the output of        `transform` will be dense (the predictions). If `X` is sparse        and `self.passthrough` is True, the output of `transform` will        be sparse.          This helper is in charge of ensuring the preditions are 2D arrays and         it will drop one of the probability column when using probabilities


X_meta.append(preds[:, 1:])                 else:                     X_meta.append(preds)        return np.concatenate(X_meta, axis=1)        if self.passthrough:            X_meta.append(X)            if sparse.issparse(X):                return sparse.hstack(X_meta, format=X.format)        return np.hstack(X_meta)      @staticmethod     def _method_name(name, estimator, method):


if est != 'drop'         ]         X_meta = self._concatenate_predictions(predictions)        X_meta = self._concatenate_predictions(X, predictions)         if sample_weight is not None:             try:                 self.final_estimator_.fit(


for est, meth in zip(self.estimators_, self.stack_method_)             if est != 'drop'         ]        return self._concatenate_predictions(predictions)        return self._concatenate_predictions(X, predictions)      @if_delegate_has_method(delegate='final_estimator_')     def predict(self, X, **predict_params):


`None` means 1 unless in a `joblib.parallel_backend` context. -1 means         using all processors. See Glossary for more details. <ins>    passthrough : bool, default=False        When False, only the predictions of estimators will be used as        training data for `final_estimator`. When True, the        `final_estimator` is trained on the predictions as well as the        original training data.</ins>     Attributes     ----------     estimators_ : list of estimators


"""     def __init__(self, estimators, final_estimator=None, cv=None,                 stack_method='auto', n_jobs=None, verbose=0):                 stack_method='auto', n_jobs=None, passthrough=False,                 verbose=0):         super().__init__(             estimators=estimators,             final_estimator=final_estimator,             cv=cv,             stack_method=stack_method,             n_jobs=n_jobs,            passthrough=passthrough,             verbose=verbose         )


`None` means 1 unless in a `joblib.parallel_backend` context. -1 means         using all processors. See Glossary for more details. <ins>    passthrough : bool, default=False        When False, only the predictions of estimators will be used as        training data for `final_estimator`. When True, the        `final_estimator` is trained on the predictions as well as the        original training data.</ins>     Attributes     ----------     estimators_ : list of estimator


"""     def __init__(self, estimators, final_estimator=None, cv=None, n_jobs=None,                 verbose=0):                 passthrough=False, verbose=0):         super().__init__(             estimators=estimators,             final_estimator=final_estimator,             cv=cv,             stack_method="predict",             n_jobs=n_jobs,            passthrough=passthrough,             verbose=verbose         )


elif self.imputation_order == 'ascending':             n = len(frac_of_missing_values) - len(missing_values_idx)             ordered_idx = np.argsort(frac_of_missing_values,                                     kind='mergesort')[n:][::-1]                                     kind='mergesort')[n:]         elif self.imputation_order == 'descending':             n = len(frac_of_missing_values) - len(missing_values_idx)             ordered_idx = np.argsort(frac_of_missing_values,                                     kind='mergesort')[n:]                                     kind='mergesort')[n:][::-1]         elif self.imputation_order == 'random':             ordered_idx = missing_values_idx             self.random_state_.shuffle(ordered_idx)


from ..utils import Bunch from ..utils import check_array from ..utils import check_random_state<ins>from ..utils.validation import _check_sample_weight</ins> from ..utils import compute_sample_weight from ..utils.multiclass import check_classification_targets from ..utils.validation import check_is_fitted


"or larger than 1").format(max_leaf_nodes))          if sample_weight is not None:            if (getattr(sample_weight, "dtype", None) != DOUBLE or                    not sample_weight.flags.contiguous):                sample_weight = np.ascontiguousarray(                    sample_weight, dtype=DOUBLE)            if len(sample_weight.shape) > 1:                raise ValueError("Sample weights array has more "                                 "than one dimension: %d" %                                 len(sample_weight.shape))            if len(sample_weight) != n_samples:                raise ValueError("Number of weights=%d does not match "                                 "number of samples=%d" %                                 (len(sample_weight), n_samples))            sample_weight = _check_sample_weight(sample_weight, X, DOUBLE)          if expanded_class_weight is not None:             if sample_weight is not None:


unconverged = (np.sum((se == convergence_iter) + (se == 0))                            != n_samples)             if (not unconverged and (K > 0)) or (it == max_iter):                never_converged = False                 if verbose:                     print("Converged after %d iterations." % it)                 break     else:        never_converged = True         if verbose:             print("Did not converge")      I = np.flatnonzero(E)     K = I.size  # Identify exemplars     if K > 0:    if K > 0 and not never_converged:         c = np.argmax(S[:, I], axis=1)         c[I] = np.arange(K)  # Identify clusters         # Refine the final set of exemplars and clusters and return results


Cluster labels.         """         check_is_fitted(self)<ins>        X = check_array(X)</ins>         if not hasattr(self, "cluster_centers_"):             raise ValueError("Predict method is not supported when "                              "affinity='precomputed'.")


def _estimator_type(self):         return self.estimator._estimator_type <ins>    @property    def _pairwise(self):        # allows cross-validation to see 'precomputed' metrics        return getattr(self.estimator, '_pairwise', False)</ins>     def score(self, X, y=None):         """Returns the score on the given data, if the estimator has been refit.


The predicted labels.     """     labels_true = check_array(        labels_true, ensure_2d=False, ensure_min_samples=0        labels_true, ensure_2d=False, ensure_min_samples=0, dtype=None,     )     labels_pred = check_array(        labels_pred, ensure_2d=False, ensure_min_samples=0        labels_pred, ensure_2d=False, ensure_min_samples=0, dtype=None,     )      # input checks


return _weighted_sum(score, sample_weight, normalize)  def confusion_matrix(y_true, y_pred, labels=None, sample_weight=None):    """Compute confusion matrix to evaluate the accuracy of a classificationdef confusion_matrix(y_true, y_pred, labels=None, sample_weight=None,                     normalize=None):    """Compute confusion matrix to evaluate the accuracy of a classification.      By definition a confusion matrix :math:`C` is such that :math:`C_{i, j}`     is equal to the number of observations known to be in group :math:`i` and


Parameters     ----------    y_true : array, shape = [n_samples]    y_true : array-like of shape (n_samples,)         Ground truth (correct) target values.     y_pred : array, shape = [n_samples]    y_pred : array-like of shape (n_samples,)         Estimated targets as returned by a classifier.     labels : array, shape = [n_classes], optional    labels : array-like of shape (n_classes), default=None         List of labels to index the matrix. This may be used to reorder         or select a subset of labels.        If none is given, those that appear at least once        If ``None`` is given, those that appear at least once         in ``y_true`` or ``y_pred`` are used in sorted order.      sample_weight : array-like of shape (n_samples,), default=None         Sample weights.     normalize : {'true', 'pred', 'all'}, default=None        Normalizes confusion matrix over the true (rows), predicted (columns)        conditions or all the population. If None, confusion matrix will not be        normalized.     Returns     -------     C : ndarray of shape (n_classes, n_classes)        Confusion matrix        Confusion matrix.      References     ----------


else:         dtype = np.float64     CM = coo_matrix((sample_weight, (y_true, y_pred)),    cm = coo_matrix((sample_weight, (y_true, y_pred)),                     shape=(n_labels, n_labels), dtype=dtype,                     ).toarray()     return CM    with np.errstate(all='ignore'):        if normalize == 'true':            cm = cm / cm.sum(axis=1, keepdims=True)        elif normalize == 'pred':            cm = cm / cm.sum(axis=0, keepdims=True)        elif normalize == 'all':            cm = cm / cm.sum()        cm = np.nan_to_num(cm)    return cm   def multilabel_confusion_matrix(y_true, y_pred, sample_weight=None,diff --git a/sklearn/metrics/_plot/confusion_matrix.py b/sklearn/metrics/_plot/confusion_matrix.py-- a/sklearn/metrics/_plot/confusion_matrix.py++ b/sklearn/metrics/_plot/confusion_matrix.py


Includes values in confusion matrix.      normalize : {'true', 'pred', 'all'}, default=None        Normalizes confusion matrix over the true (rows), predicited (columns)        Normalizes confusion matrix over the true (rows), predicted (columns)         conditions or all the population. If None, confusion matrix will not be         normalized.


y_pred = estimator.predict(X)     cm = confusion_matrix(y_true, y_pred, sample_weight=sample_weight,                          labels=labels)    if normalize == 'true':        cm = cm / cm.sum(axis=1, keepdims=True)    elif normalize == 'pred':        cm = cm / cm.sum(axis=0, keepdims=True)    elif normalize == 'all':        cm = cm / cm.sum()                          labels=labels, normalize=normalize)      if display_labels is None:         if labels is None:


Parameters         ----------        X : array-like of shape (n_samples, n_features)        X : {array-like, sparse matrix} of shape (n_samples, n_features)             Training data, where `n_samples` is the number of samples             and `n_features` is the number of features.


Returns the instance itself.         """         self._validate_params()        X, y = self._validate_data(X, y)        X, y = self._validate_data(            X,            y,            accept_sparse=["csr", "csc"],            reset=True,        )         self.X_ = X         check_classification_targets(y)


Attributes     ----------    X_ : ndarray of shape (n_samples, n_features)    X_ : {array-like, sparse matrix} of shape (n_samples, n_features)         Input array.      classes_ : ndarray of shape (n_classes,)


which might cause predictions to change if the data is modified         externally. <ins>    n_targets : int, default=None        The number of dimensions of the target values. Used to decide the number        of outputs when sampling from the prior distributions (i.e. calling        :meth:`sample_y` before :meth:`fit`). This parameter is ignored once        :meth:`fit` has been called.        .. versionadded:: 1.3</ins>     random_state : int, RandomState instance or None, default=None         Determines random number generation used to initialize the centers.         Pass an int for reproducible results across multiple function calls.


"n_restarts_optimizer": [Interval(Integral, 0, None, closed="left")],         "normalize_y": ["boolean"],         "copy_X_train": ["boolean"],<ins>        "n_targets": [Interval(Integral, 1, None, closed="left"), None],</ins>         "random_state": ["random_state"],     }


n_restarts_optimizer=0,         normalize_y=False,         copy_X_train=True,<ins>        n_targets=None,</ins>         random_state=None,     ):         self.kernel = kernel


self.n_restarts_optimizer = n_restarts_optimizer         self.normalize_y = normalize_y         self.copy_X_train = copy_X_train<ins>        self.n_targets = n_targets</ins>         self.random_state = random_state      def fit(self, X, y):


dtype=dtype,         ) <ins>        n_targets_seen = y.shape[1] if y.ndim > 1 else 1        if self.n_targets is not None and n_targets_seen != self.n_targets:            raise ValueError(                "The number of targets seen in `y` is different from the parameter "                f"`n_targets`. Got {n_targets_seen} != {self.n_targets}."            )</ins>         # Normalize target value         if self.normalize_y:             self._y_train_mean = np.mean(y, axis=0)


)             else:                 kernel = self.kernel            y_mean = np.zeros(X.shape[0])            n_targets = self.n_targets if self.n_targets is not None else 1            y_mean = np.zeros(shape=(X.shape[0], n_targets)).squeeze()             if return_cov:                 y_cov = kernel(X)                if n_targets > 1:                    y_cov = np.repeat(                        np.expand_dims(y_cov, -1), repeats=n_targets, axis=-1                    )                 return y_mean, y_cov             elif return_std:                 y_var = kernel.diag(X)                if n_targets > 1:                    y_var = np.repeat(                        np.expand_dims(y_var, -1), repeats=n_targets, axis=-1                    )                 return y_mean, np.sqrt(y_var)             else:                 return y_mean


import functools  import numpy as np<ins>from scipy.sparse import issparse</ins>  from ...utils import check_random_state from ...utils import check_X_y


Parameters     ----------    D_chunk : array-like of shape (n_chunk_samples, n_samples)        Precomputed distances for a chunk.    D_chunk : {array-like, sparse matrix} of shape (n_chunk_samples, n_samples)        Precomputed distances for a chunk. If a sparse matrix is provided,        only CSR format is accepted.     start : int         First index in the chunk.     labels : array-like of shape (n_samples,)


label_freqs : array-like         Distribution of cluster labels in ``labels``.     """    n_chunk_samples = D_chunk.shape[0]     # accumulate distances from each sample to each cluster    clust_dists = np.zeros((len(D_chunk), len(label_freqs)), dtype=D_chunk.dtype)    for i in range(len(D_chunk)):        clust_dists[i] += np.bincount(            labels, weights=D_chunk[i], minlength=len(label_freqs)        )    cluster_distances = np.zeros(        (n_chunk_samples, len(label_freqs)), dtype=D_chunk.dtype    )     # intra_index selects intra-cluster distances within clust_dists    intra_index = (np.arange(len(D_chunk)), labels[start : start + len(D_chunk)])    # intra_clust_dists are averaged over cluster size outside this function    intra_clust_dists = clust_dists[intra_index]    if issparse(D_chunk):        if D_chunk.format != "csr":            raise TypeError(                "Expected CSR matrix. Please pass sparse matrix in CSR format."            )        for i in range(n_chunk_samples):            indptr = D_chunk.indptr            indices = D_chunk.indices[indptr[i] : indptr[i + 1]]            sample_weights = D_chunk.data[indptr[i] : indptr[i + 1]]            sample_labels = np.take(labels, indices)            cluster_distances[i] += np.bincount(                sample_labels, weights=sample_weights, minlength=len(label_freqs)            )    else:        for i in range(n_chunk_samples):            sample_weights = D_chunk[i]            sample_labels = labels            cluster_distances[i] += np.bincount(                sample_labels, weights=sample_weights, minlength=len(label_freqs)            )    # intra_index selects intra-cluster distances within cluster_distances    end = start + n_chunk_samples    intra_index = (np.arange(n_chunk_samples), labels[start:end])    # intra_cluster_distances are averaged over cluster size outside this function    intra_cluster_distances = cluster_distances[intra_index]     # of the remaining distances we normalise and extract the minimum    clust_dists[intra_index] = np.inf    clust_dists /= label_freqs    inter_clust_dists = clust_dists.min(axis=1)    return intra_clust_dists, inter_clust_dists    cluster_distances[intra_index] = np.inf    cluster_distances /= label_freqs    inter_cluster_distances = cluster_distances.min(axis=1)    return intra_cluster_distances, inter_cluster_distances   def silhouette_samples(X, labels, *, metric="euclidean", **kwds):


Parameters     ----------    X : array-like of shape (n_samples_a, n_samples_a) if metric == \    X : {array-like, sparse matrix} of shape (n_samples_a, n_samples_a) if metric == \             "precomputed" or (n_samples_a, n_features) otherwise        An array of pairwise distances between samples, or a feature array.        An array of pairwise distances between samples, or a feature array. If        a sparse matrix is provided, CSR format should be favoured avoiding        an additional copy.      labels : array-like of shape (n_samples,)         Label values for each sample.


.. [2] `Wikipedia entry on the Silhouette Coefficient        <https://en.wikipedia.org/wiki/Silhouette_(clustering)>`_     """    X, labels = check_X_y(X, labels, accept_sparse=["csc", "csr"])    X, labels = check_X_y(X, labels, accept_sparse=["csr"])      # Check for non-zero diagonal entries in precomputed distance matrix     if metric == "precomputed":


)         if X.dtype.kind == "f":             atol = np.finfo(X.dtype).eps * 100            if np.any(np.abs(np.diagonal(X)) > atol):                raise ValueError(error_msg)        elif np.any(np.diagonal(X) != 0):  # integral dtype            raise ValueError(error_msg)            if np.any(np.abs(X.diagonal()) > atol):                raise error_msg        elif np.any(X.diagonal() != 0):  # integral dtype            raise error_msg      le = LabelEncoder()     labels = le.fit_transform(labels)


trapezoidal rule, which uses linear interpolation and can be too     optimistic. <del>    Note: this implementation is restricted to the binary classification task    or multilabel classification task.</del>     Read more in the :ref:`User Guide <precision_recall_f_measure_metrics>`.      Parameters


>>> y_scores = np.array([0.1, 0.4, 0.35, 0.8])     >>> average_precision_score(y_true, y_scores)     0.83...<ins>    >>> y_true = np.array([0, 0, 1, 1, 2, 2])    >>> y_scores = np.array([    ...     [0.7, 0.2, 0.1],    ...     [0.4, 0.3, 0.3],    ...     [0.1, 0.8, 0.1],    ...     [0.2, 0.3, 0.5],    ...     [0.4, 0.4, 0.2],    ...     [0.1, 0.2, 0.7],    ... ])    >>> average_precision_score(y_true, y_scores)    0.77...</ins>     """      def _binary_uninterpolated_average_precision(


return -np.sum(np.diff(recall) * np.array(precision)[:-1])      y_type = type_of_target(y_true, input_name="y_true")    if y_type == "multilabel-indicator" and pos_label != 1:        raise ValueError(            "Parameter pos_label is fixed to 1 for "            "multilabel-indicator y_true. Do not set "            "pos_label or set pos_label to 1."        )    elif y_type == "binary":        # Convert to Python primitive type to avoid NumPy type / Python str        # comparison. See https://github.com/numpy/numpy/issues/6784        present_labels = np.unique(y_true).tolist()    # Convert to Python primitive type to avoid NumPy type / Python str    # comparison. See https://github.com/numpy/numpy/issues/6784    present_labels = np.unique(y_true).tolist()    if y_type == "binary":         if len(present_labels) == 2 and pos_label not in present_labels:             raise ValueError(                 f"pos_label={pos_label} is not a valid label. It should be "                 f"one of {present_labels}"             )    elif y_type == "multilabel-indicator" and pos_label != 1:        raise ValueError(            "Parameter pos_label is fixed to 1 for multilabel-indicator y_true. "            "Do not set pos_label or set pos_label to 1."        )    elif y_type == "multiclass":        if pos_label != 1:            raise ValueError(                "Parameter pos_label is fixed to 1 for multiclass y_true. "                "Do not set pos_label or set pos_label to 1."            )        y_true = label_binarize(y_true, classes=present_labels)     average_precision = partial(         _binary_uninterpolated_average_precision, pos_label=pos_label     )


y="no_validation",         reset=True,         validate_separately=False,<ins>        cast_to_ndarray=True,</ins>         **check_params,     ):         """Validate input data and set or check the `n_features_in_` attribute.


`estimator=self` is automatically added to these dicts to generate             more informative error message in case of invalid input data. <ins>        cast_to_ndarray : bool, default=True            Cast `X` and `y` to ndarray with checks in `check_params`. If            `False`, `X` and `y` are unchanged and only `feature_names` and            `n_features_in_` are checked.</ins>         **check_params : kwargs             Parameters passed to :func:`sklearn.utils.check_array` or             :func:`sklearn.utils.check_X_y`. Ignored if validate_separately


if no_val_X and no_val_y:             raise ValueError("Validation should be done on X, y or both.")         elif not no_val_X and no_val_y:            X = check_array(X, input_name="X", **check_params)            if cast_to_ndarray:                X = check_array(X, input_name="X", **check_params)             out = X         elif no_val_X and not no_val_y:            y = _check_y(y, **check_params)            if cast_to_ndarray:                y = _check_y(y, **check_params) if cast_to_ndarray else y             out = y         else:            if validate_separately:            if validate_separately and cast_to_ndarray:                 # We need this because some estimators validate X and y                 # separately, and in general, separately calling check_array()                 # on X and y isn't equivalent to just calling check_X_y()diff --git a/sklearn/feature_selection/_base.py b/sklearn/feature_selection/_base.py-- a/sklearn/feature_selection/_base.py++ b/sklearn/feature_selection/_base.py


from ..cross_decomposition._pls import _PLS from ..utils import (     check_array,    safe_mask,     safe_sqr, ) from ..utils._tags import _safe_tagsfrom ..utils import _safe_indexingfrom ..utils._set_output import _get_output_config from ..utils.validation import _check_feature_names_in, check_is_fitted


X_r : array of shape [n_samples, n_selected_features]             The input samples with only the selected features.         """<ins>        # Preserve X when X is a dataframe and the output is configured to        # be pandas.        output_config_dense = _get_output_config("transform", estimator=self)["dense"]        preserve_X = hasattr(X, "iloc") and output_config_dense == "pandas"</ins>         # note: we use _safe_tags instead of _get_tags because this is a         # public Mixin.         X = self._validate_data(