a
    �ù»j07  ã                   @   sÌ   d Z ddlmZmZ ddlZddlmZmZm	Z	m
Z
mZ ddlmZmZ ddlmZmZ ddlmZmZmZmZmZ dd	lmZmZmZmZ dd
lmZ ddlm Z m!Z! ddl"m#Z# G dd„ de#eeƒZ$dS )z
Sequential feature selection
é    )ÚIntegralÚRealNé   )ÚBaseEstimatorÚMetaEstimatorMixinÚ_fit_contextÚcloneÚis_classifier)Úcheck_scoringÚget_scorer_names)Úcheck_cvÚcross_val_score)ÚMetadataRouterÚMethodMappingÚ_raise_for_paramsÚ_routing_enabledÚprocess_routing)Ú
HasMethodsÚIntervalÚ
RealNotIntÚ
StrOptions)Úget_tags)Úcheck_is_fittedÚvalidate_dataé   )ÚSelectorMixinc                	       sÞ   e Zd ZU dZedgƒgedhƒeedddd�eeddd	d�gdee	ddd	d�ged
dhƒgdee
eƒ ƒƒegdgdegdœZeed< ddd
ddddœdd„Zedd�ddd„ƒZdd„ Zdd„ Z‡ fdd„Zdd„ Z‡  ZS ) ÚSequentialFeatureSelectora·  Transformer that performs Sequential Feature Selection.

    This Sequential Feature Selector adds (forward selection) or
    removes (backward selection) features to form a feature subset in a
    greedy fashion. At each stage, this estimator chooses the best feature to
    add or remove based on the cross-validation score of an estimator. In
    the case of unsupervised learning, this Sequential Feature Selector
    looks only at the features (X), not the desired outputs (y).

    Read more in the :ref:`User Guide <sequential_feature_selection>`.

    .. versionadded:: 0.24

    Parameters
    ----------
    estimator : estimator instance
        An unfitted estimator.

    n_features_to_select : "auto", int or float, default="auto"
        If `"auto"`, the behaviour depends on the `tol` parameter:

        - if `tol` is not `None`, then features are selected while the score
          change does not exceed `tol`.
        - otherwise, half of the features are selected.

        If integer, the parameter is the absolute number of features to select.
        If float between 0 and 1, it is the fraction of features to select.

        .. versionadded:: 1.1
           The option `"auto"` was added in version 1.1.

        .. versionchanged:: 1.3
           The default changed from `"warn"` to `"auto"` in 1.3.

    tol : float, default=None
        If the score is not incremented by at least `tol` between two
        consecutive feature additions or removals, stop adding or removing.

        `tol` can be negative when removing features using `direction="backward"`.
        `tol` is required to be strictly positive when doing forward selection.
        It can be useful to reduce the number of features at the cost of a small
        decrease in the score.

        `tol` is enabled only when `n_features_to_select` is `"auto"`.

        .. versionadded:: 1.1

    direction : {'forward', 'backward'}, default='forward'
        Whether to perform forward selection or backward selection.

    scoring : str or callable, default=None
        A single str (see :ref:`scoring_parameter`) or a callable
        (see :ref:`scoring_callable`) to evaluate the predictions on the test set.

        NOTE that when using a custom scorer, it should return a single
        value.

        If None, the estimator's score method is used.

    cv : int, cross-validation generator or an iterable, default=None
        Determines the cross-validation splitting strategy.
        Possible inputs for cv are:

        - None, to use the default 5-fold cross validation,
        - integer, to specify the number of folds in a `(Stratified)KFold`,
        - :term:`CV splitter`,
        - An iterable yielding (train, test) splits as arrays of indices.

        For integer/None inputs, if the estimator is a classifier and ``y`` is
        either binary or multiclass,
        :class:`~sklearn.model_selection.StratifiedKFold` is used. In all other
        cases, :class:`~sklearn.model_selection.KFold` is used. These splitters
        are instantiated with `shuffle=False` so the splits will be the same
        across calls.

        Refer :ref:`User Guide <cross_validation>` for the various
        cross-validation strategies that can be used here.

    n_jobs : int, default=None
        Number of jobs to run in parallel. When evaluating a new feature to
        add or remove, the cross-validation procedure is parallel over the
        folds.
        ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.
        ``-1`` means using all processors. See :term:`Glossary <n_jobs>`
        for more details.

    Attributes
    ----------
    n_features_in_ : int
        Number of features seen during :term:`fit`. Only defined if the
        underlying estimator exposes such an attribute when fit.

        .. versionadded:: 0.24

    feature_names_in_ : ndarray of shape (`n_features_in_`,)
        Names of features seen during :term:`fit`. Defined only when `X`
        has feature names that are all strings.

        .. versionadded:: 1.0

    n_features_to_select_ : int
        The number of features that were selected.

    support_ : ndarray of shape (n_features,), dtype=bool
        The mask of selected features.

    See Also
    --------
    GenericUnivariateSelect : Univariate feature selector with configurable
        strategy.
    RFE : Recursive feature elimination based on importance weights.
    RFECV : Recursive feature elimination based on importance weights, with
        automatic selection of the number of features.
    SelectFromModel : Feature selection based on thresholds of importance
        weights.

    Examples
    --------
    >>> from sklearn.feature_selection import SequentialFeatureSelector
    >>> from sklearn.neighbors import KNeighborsClassifier
    >>> from sklearn.datasets import load_iris
    >>> X, y = load_iris(return_X_y=True)
    >>> knn = KNeighborsClassifier(n_neighbors=3)
    >>> sfs = SequentialFeatureSelector(knn, n_features_to_select=3)
    >>> sfs.fit(X, y)
    SequentialFeatureSelector(estimator=KNeighborsClassifier(n_neighbors=3),
                              n_features_to_select=3)
    >>> sfs.get_support()
    array([ True, False,  True,  True])
    >>> sfs.transform(X).shape
    (150, 3)
    ÚfitÚautor   r   Úright)ÚclosedNZneitherÚforwardÚbackwardZ	cv_object©Ú	estimatorÚn_features_to_selectÚtolÚ	directionÚscoringÚcvÚn_jobsÚ_parameter_constraintsé   )r%   r&   r'   r(   r)   r*   c                C   s.   || _ || _|| _|| _|| _|| _|| _d S ©Nr#   )Úselfr$   r%   r&   r'   r(   r)   r*   © r/   úKE:\soccer\ml_env\Lib\site-packages\sklearn/feature_selection/_sequential.pyÚ__init__°   s    z"SequentialFeatureSelector.__init__F)Zprefer_skip_nested_validationc                 K   sØ  t || dƒ |  ¡ }t| |dd|jj d�}|jd }| jdkrb| jdurV|d | _q¦|d | _nDt	| jt
ƒrŠ| j|kr€tdƒ‚| j| _nt	| jtƒr¦t|| j ƒ| _| jdurÌ| jd	k rÌ| jd
krÌtdƒ‚t| j|t| jƒd�}t| jƒ}tj|td�}| jdk�s| jd
k�r| jn|| j }	tj }
| jdu�o>| jdk}tƒ �rZt| dfi |¤Ž t|	ƒD ]L}| j|||||fi |¤Ž\}}|�r ||
 | jk �r  �q°|}
d||< �qb| jdk�rÂ| }|| _| j ¡ | _| S )aÞ  Learn the features to select from X.

        Parameters
        ----------
        X : array-like of shape (n_samples, n_features)
            Training vectors, where `n_samples` is the number of samples and
            `n_features` is the number of predictors.

        y : array-like of shape (n_samples,), default=None
            Target values. This parameter may be ignored for
            unsupervised learning.

        **params : dict, default=None
            Parameters to be passed to the underlying `estimator`, `cv`
            and `scorer` objects.

            .. versionadded:: 1.6

                Only available if `enable_metadata_routing=True`,
                which can be set by using
                ``sklearn.set_config(enable_metadata_routing=True)``.
                See :ref:`Metadata Routing User Guide <metadata_routing>` for
                more details.

        Returns
        -------
        self : object
            Returns the instance itself.
        r   Zcscr   )Zaccept_sparseZensure_min_featuresZensure_all_finiter   r   Nz*n_features_to_select must be < n_features.r   r!   z:tol must be strictly positive when doing forward selection©Ú
classifier)ÚshapeZdtypeTr"   )r   Ú__sklearn_tags__r   Ú
input_tagsÚ	allow_nanr4   r%   r&   Zn_features_to_select_Ú
isinstancer   Ú
ValueErrorr   Úintr'   r   r)   r	   r$   r   ÚnpZzerosÚboolÚinfr   r   ÚrangeÚ_get_best_new_feature_scoreÚsupport_Úsum)r.   ÚXÚyÚparamsÚtagsZ
n_featuresr)   Zcloned_estimatorÚcurrent_maskZn_iterationsZ	old_scoreZis_auto_selectÚ_Únew_feature_idxZ	new_scorer/   r/   r0   r   Ã   sh    "û




ÿ
ÿÿ
ý
ÿÿ
zSequentialFeatureSelector.fitc              
      sŒ   t  | ¡}i ‰ |D ]V}| ¡ }	d|	|< | jdkr8|	 }	|d d …|	f }
t||
||| j| j|d� ¡ ˆ |< qtˆ ‡ fdd„d�}|ˆ | fS )NTr"   )r)   r(   r*   rD   c                    s   ˆ |  S r-   r/   )Úfeature_idx©Zscoresr/   r0   Ú<lambda>B  ó    zGSequentialFeatureSelector._get_best_new_feature_score.<locals>.<lambda>)Úkey)	r;   ZflatnonzeroÚcopyr'   r   r(   r*   ÚmeanÚmax)r.   r$   rB   rC   r)   rF   rD   Zcandidate_feature_indicesrI   Zcandidate_maskZX_newrH   r/   rJ   r0   r?   +  s&    
ù	z5SequentialFeatureSelector._get_best_new_feature_scorec                 C   s   t | ƒ | jS r-   )r   r@   )r.   r/   r/   r0   Ú_get_support_maskE  s    z+SequentialFeatureSelector._get_support_maskc                    s2   t ƒ  ¡ }t| jƒjj|j_t| jƒjj|j_|S r-   )Úsuperr5   r   r$   r6   r7   Úsparse)r.   rE   ©Ú	__class__r/   r0   r5   I  s    
z*SequentialFeatureSelector.__sklearn_tags__c                 C   s~   t | jjd�}|j| jtƒ jddd�d� |jt| jt| jƒd�tƒ jddd�d� |jt	| j| j
d�tƒ jdd	d�d
� |S )aj  Get metadata routing of this object.

        Please check :ref:`User Guide <metadata_routing>` on how the routing
        mechanism works.

        .. versionadded:: 1.6

        Returns
        -------
        routing : MetadataRouter
            A :class:`~sklearn.utils.metadata_routing.MetadataRouter` encapsulating
            routing information.
        )Úownerr   )ZcallerZcallee)r$   Úmethod_mappingr2   Úsplit)ZsplitterrW   )r(   Zscore)ZscorerrW   )r   rU   Ú__name__Úaddr$   r   r   r)   r	   r
   r(   )r.   Zrouterr/   r/   r0   Úget_metadata_routingO  s    þþþz.SequentialFeatureSelector.get_metadata_routing)N)rY   Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   Úsetr   Úcallabler+   ÚdictÚ__annotations__r1   r   r   r?   rQ   r5   r[   Ú__classcell__r/   r/   rT   r0   r      s8   
 
ýõ÷þdr   )%r^   Únumbersr   r   Únumpyr;   Úbaser   r   r   r   r	   Zmetricsr
   r   Zmodel_selectionr   r   Zutils._metadata_requestsr   r   r   r   r   Zutils._param_validationr   r   r   r   Zutils._tagsr   Zutils.validationr   r   Z_baser   r   r/   r/   r/   r0   Ú<module>   s   