B
    0db                 @   sF  d Z ddlmZ ddlmZ ddlZddlmZ ddl	m
Z
 ddlmZmZ dd	lmZ dd
lmZ ddlmZmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm Z  ddddgZ!dd Z"G dd de Z#dd Z$dddddZ%dd  Z&d)d"d#Z'd*d$d%Z(G d&d dee Z)ddd'd(dZ*dS )+z
The :mod:`sklearn.pipeline` module implements utilities to build a composite
estimator, as a chain of transforms and estimators.
    )defaultdict)isliceN)sparse)Parallel   )cloneTransformerMixin)_VisualBlock)available_if)Bunch_print_elapsed_time)
deprecated)
_safe_tags)check_memory)check_is_fitted)delayed)NotFittedError)_BaseCompositionPipelineFeatureUnionmake_pipeline
make_unionc                s    fdd}|S )z\Check that final_estimator has `attr`.

    Used together with `avaliable_if` in `Pipeline`.c                s   t | j  dS )NT)getattr_final_estimator)self)attr B/var/www/html/venv/lib/python3.7/site-packages/sklearn/pipeline.pycheck+   s    z#_final_estimator_has.<locals>.checkr   )r   r   r   )r   r   _final_estimator_has&   s    r   c               @   s  e Zd ZdZdgZdddddZdSd	d
Zdd Zdd ZdTddZ	dd Z
dd Zedd Zedd Zedd Zdd Zdd ZdUdd ZdVd!d"ZdWd#d$Zeed%d&d' Zeed(dXd)d*Zeed+d,d- Zeed.d/d0 Zeed1d2d3 Zeed4d5d6 Zd7d8 Zeed9d: Zd;d< Zeed=d> Z eed?dYd@dAZ!edBdC Z"dDdE Z#e$dFedGdH Z%dZdIdJZ&edKdL Z'edMdN Z(dOdP Z)dQdR Z*dS )[r   a  
    Pipeline of transforms with a final estimator.

    Sequentially apply a list of transforms and a final estimator.
    Intermediate steps of the pipeline must be 'transforms', that is, they
    must implement `fit` and `transform` methods.
    The final estimator only needs to implement `fit`.
    The transformers in the pipeline can be cached using ``memory`` argument.

    The purpose of the pipeline is to assemble several steps that can be
    cross-validated together while setting different parameters. For this, it
    enables setting parameters of the various steps using their names and the
    parameter name separated by a `'__'`, as in the example below. A step's
    estimator may be replaced entirely by setting the parameter with its name
    to another estimator, or a transformer removed by setting it to
    `'passthrough'` or `None`.

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

    .. versionadded:: 0.5

    Parameters
    ----------
    steps : list of tuple
        List of (name, transform) tuples (implementing `fit`/`transform`) that
        are chained, in the order in which they are chained, with the last
        object an estimator.

    memory : str or object with the joblib.Memory interface, default=None
        Used to cache the fitted transformers of the pipeline. By default,
        no caching is performed. If a string is given, it is the path to
        the caching directory. Enabling caching triggers a clone of
        the transformers before fitting. Therefore, the transformer
        instance given to the pipeline cannot be inspected
        directly. Use the attribute ``named_steps`` or ``steps`` to
        inspect estimators within the pipeline. Caching the
        transformers is advantageous when fitting is time consuming.

    verbose : bool, default=False
        If True, the time elapsed while fitting each step will be printed as it
        is completed.

    Attributes
    ----------
    named_steps : :class:`~sklearn.utils.Bunch`
        Dictionary-like object, with the following attributes.
        Read-only attribute to access any step parameter by user given name.
        Keys are step names and values are steps parameters.

    classes_ : ndarray of shape (n_classes,)
        The classes labels. Only exist if the last step of the pipeline is a
        classifier.

    n_features_in_ : int
        Number of features seen during :term:`fit`. Only defined if the
        underlying first estimator in `steps` 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`. Only defined if the
        underlying estimator exposes such an attribute when fit.

        .. versionadded:: 1.0

    See Also
    --------
    make_pipeline : Convenience function for simplified pipeline construction.

    Examples
    --------
    >>> from sklearn.svm import SVC
    >>> from sklearn.preprocessing import StandardScaler
    >>> from sklearn.datasets import make_classification
    >>> from sklearn.model_selection import train_test_split
    >>> from sklearn.pipeline import Pipeline
    >>> X, y = make_classification(random_state=0)
    >>> X_train, X_test, y_train, y_test = train_test_split(X, y,
    ...                                                     random_state=0)
    >>> pipe = Pipeline([('scaler', StandardScaler()), ('svc', SVC())])
    >>> # The pipeline can be used as any other estimator
    >>> # and avoids leaking the test set into the train set
    >>> pipe.fit(X_train, y_train)
    Pipeline(steps=[('scaler', StandardScaler()), ('svc', SVC())])
    >>> pipe.score(X_test, y_test)
    0.88
    stepsNF)memoryverbosec            C   s   || _ || _|| _|   d S )N)r    r!   r"   _validate_steps)r   r    r!   r"   r   r   r   __init__   s    zPipeline.__init__Tc             C   s   | j d|dS )a  Get parameters for this estimator.

        Returns the parameters given in the constructor as well as the
        estimators contained within the `steps` of the `Pipeline`.

        Parameters
        ----------
        deep : bool, default=True
            If True, will return the parameters for this estimator and
            contained subobjects that are estimators.

        Returns
        -------
        params : mapping of string to any
            Parameter names mapped to their values.
        r    )deep)_get_params)r   r%   r   r   r   
get_params   s    zPipeline.get_paramsc             K   s   | j d| | S )aC  Set the parameters of this estimator.

        Valid parameter keys can be listed with ``get_params()``. Note that
        you can directly set the parameters of the estimators contained in
        `steps`.

        Parameters
        ----------
        **kwargs : dict
            Parameters of this estimator or parameters of estimators contained
            in `steps`. Parameters of the steps may be set using its name and
            the parameter name separated by a '__'.

        Returns
        -------
        self : object
            Pipeline class instance.
        r    )r    )_set_params)r   kwargsr   r   r   
set_params   s    zPipeline.set_paramsc             C   s   t | j \}}| | |d d }|d }xP|D ]H}|d ks2|dkrHq2t|ds\t|drft|ds2td|t|f q2W |d k	r|dkrt|dstd|t|f d S )Npassthroughfitfit_transform	transformzAll intermediate steps should be transformers and implement fit and transform or be the string 'passthrough' '%s' (type %s) doesn'tzaLast step of Pipeline should implement fit or be the string 'passthrough'. '%s' (type %s) doesn't)zipr    _validate_nameshasattr	TypeErrortype)r   names
estimatorstransformers	estimatortr   r   r   r#      s$    


zPipeline._validate_stepsc             c   sl   t | j}|s|d8 }xPtt| jd|D ]:\}\}}|sH|||fV  q*|dk	r*|dkr*|||fV  q*W dS )z
        Generate (idx, (name, trans)) tuples from self.steps

        When filter_passthrough is True, 'passthrough' and None transformers
        are filtered out.
        r   r   Nr,   )lenr    	enumerater   )r   
with_finalfilter_passthroughstopidxnametransr   r   r   _iter   s    
 zPipeline._iterc             C   s
   t | jS )z4
        Returns the length of the Pipeline
        )r:   r    )r   r   r   r   __len__   s    zPipeline.__len__c             C   sh   t |tr6|jdkrtd| j| j| | j| jdS y| j| \}}W n tk
rb   | j	| S X |S )a  Returns a sub-pipeline or a single estimator in the pipeline

        Indexing with an integer will return an estimator; using a slice
        returns another Pipeline instance which copies a slice of this
        Pipeline. This copy is shallow: modifying (or fitting) estimators in
        the sub-pipeline will affect the larger pipeline and vice-versa.
        However, replacing a value in `step` will not affect a copy.
        )r   Nz*Pipeline slicing only supports a step of 1)r!   r"   )

isinstanceslicestep
ValueError	__class__r    r!   r"   r3   named_steps)r   indr@   estr   r   r   __getitem__   s    	

zPipeline.__getitem__c             C   s   | j d d jS )Nr+   r   )r    _estimator_type)r   r   r   r   rM     s    zPipeline._estimator_typec             C   s   t f t| jS )zAccess the steps by name.

        Read-only attribute to access any step by given name.
        Keys are steps names and values are the steps objects.)r   dictr    )r   r   r   r   rI     s    zPipeline.named_stepsc             C   s   | j d d }|d krdS |S )Nr+   r   r,   )r    )r   r8   r   r   r   r     s    zPipeline._final_estimatorc             C   s0   | j s
d S | j| \}}d|d t| j|f S )Nz(step %d of %d) Processing %sr   )r"   r    r:   )r   step_idxr@   _r   r   r   _log_message!  s    zPipeline._log_messagec             K   s\   dd | j D }xF| D ]:\}}d|kr8td||dd\}}||| |< qW |S )Nc             S   s   i | ]\}}|d k	ri |qS )Nr   ).0r@   rF   r   r   r   
<dictcomp>)  s    z.Pipeline._check_fit_params.<locals>.<dictcomp>__zPipeline.fit does not accept the {} parameter. You can pass parameters to specific steps of your pipeline using the stepname__parameter format, e.g. `Pipeline.fit(X, y, logisticregression__sample_weight=sample_weight)`.r   )r    itemsrG   formatsplit)r   
fit_paramsfit_params_stepsZpnameZpvalrF   paramr   r   r   _check_fit_params(  s    zPipeline._check_fit_paramsc          
   K   s   t | j| _|   t| j}|t}x| jdddD ]\}}}|d ksR|dkrptd| 	| w8W d Q R X t
|dr|jd kr|}	qt|}	n,t
|dr|jd kr|}	qt|}	nt|}	||	||d fd| 	|d|| \}}
||
f| j|< q8W |S )NF)r<   r=   r,   r   locationcachedir)message_clsnamemessage)listr    r#   r   r!   cache_fit_transform_onerB   r   rQ   r2   r\   r   r]   )r   XyrY   r!   Zfit_transform_one_cachedrO   r@   transformerZcloned_transformerZfitted_transformerr   r   r   _fit9  s8    







zPipeline._fitc          	   K   st   | j f |}| j||f|}td| t| jd 4 | jdkrf|| jd d  }| jj||f| W dQ R X | S )a$  Fit the model.

        Fit all the transformers one after the other and transform the
        data. Finally, fit the transformed data using the final estimator.

        Parameters
        ----------
        X : iterable
            Training data. Must fulfill input requirements of first step of the
            pipeline.

        y : iterable, default=None
            Training targets. Must fulfill label requirements for all steps of
            the pipeline.

        **fit_params : dict of string -> object
            Parameters passed to the ``fit`` method of each step, where
            each parameter name is prefixed such that parameter ``p`` for step
            ``s`` has key ``s__p``.

        Returns
        -------
        self : object
            Pipeline with fitted steps.
        r   r   r,   r+   r   N)r[   rf   r   rQ   r:   r    r   r-   )r   rc   rd   rX   rY   Xtfit_params_last_stepr   r   r   r-   k  s    
zPipeline.fitc          	   K   s   | j f |}| j||f|}| j}td| t| jd T |dkrJ|S || jd d  }t|drv|j||f|S |j	||f|
|S W dQ R X dS )a  Fit the model and transform with the final estimator.

        Fits all the transformers one after the other and transform the
        data. Then uses `fit_transform` on transformed data with the final
        estimator.

        Parameters
        ----------
        X : iterable
            Training data. Must fulfill input requirements of first step of the
            pipeline.

        y : iterable, default=None
            Training targets. Must fulfill label requirements for all steps of
            the pipeline.

        **fit_params : dict of string -> object
            Parameters passed to the ``fit`` method of each step, where
            each parameter name is prefixed such that parameter ``p`` for step
            ``s`` has key ``s__p``.

        Returns
        -------
        Xt : ndarray of shape (n_samples, n_transformed_features)
            Transformed samples.
        r   r   r,   r+   r   r.   N)r[   rf   r   r   rQ   r:   r    r2   r.   r-   r/   )r   rc   rd   rX   rY   rg   Z	last_steprh   r   r   r   r.     s    
zPipeline.fit_transformpredictc             K   sB   |}x$| j ddD ]\}}}||}qW | jd d j|f|S )a#  Transform the data, and apply `predict` with the final estimator.

        Call `transform` of each transformer in the pipeline. The transformed
        data are finally passed to the final estimator that calls `predict`
        method. Only valid if the final estimator implements `predict`.

        Parameters
        ----------
        X : iterable
            Data to predict on. Must fulfill input requirements of first step
            of the pipeline.

        **predict_params : dict of string -> object
            Parameters to the ``predict`` called at the end of all
            transformations in the pipeline. Note that while this may be
            used to return uncertainties from some models with return_std
            or return_cov, uncertainties that are generated by the
            transformations in the pipeline are not propagated to the
            final estimator.

            .. versionadded:: 0.20

        Returns
        -------
        y_pred : ndarray
            Result of calling `predict` on the final estimator.
        F)r<   r+   r   )rB   r/   r    ri   )r   rc   Zpredict_paramsrg   rP   r@   r/   r   r   r   ri     s    zPipeline.predictfit_predictc          	   K   sr   | j f |}| j||f|}|| jd d  }td| t| jd   | jd d j||f|}W dQ R X |S )a  Transform the data, and apply `fit_predict` with the final estimator.

        Call `fit_transform` of each transformer in the pipeline. The
        transformed data are finally passed to the final estimator that calls
        `fit_predict` method. Only valid if the final estimator implements
        `fit_predict`.

        Parameters
        ----------
        X : iterable
            Training data. Must fulfill input requirements of first step of
            the pipeline.

        y : iterable, default=None
            Training targets. Must fulfill label requirements for all steps
            of the pipeline.

        **fit_params : dict of string -> object
            Parameters passed to the ``fit`` method of each step, where
            each parameter name is prefixed such that parameter ``p`` for step
            ``s`` has key ``s__p``.

        Returns
        -------
        y_pred : ndarray
            Result of calling `fit_predict` on the final estimator.
        r+   r   r   r   N)r[   rf   r    r   rQ   r:   rj   )r   rc   rd   rX   rY   rg   rh   Zy_predr   r   r   rj     s    $zPipeline.fit_predictpredict_probac             K   sB   |}x$| j ddD ]\}}}||}qW | jd d j|f|S )a>  Transform the data, and apply `predict_proba` with the final estimator.

        Call `transform` of each transformer in the pipeline. The transformed
        data are finally passed to the final estimator that calls
        `predict_proba` method. Only valid if the final estimator implements
        `predict_proba`.

        Parameters
        ----------
        X : iterable
            Data to predict on. Must fulfill input requirements of first step
            of the pipeline.

        **predict_proba_params : dict of string -> object
            Parameters to the `predict_proba` called at the end of all
            transformations in the pipeline.

        Returns
        -------
        y_proba : ndarray of shape (n_samples, n_classes)
            Result of calling `predict_proba` on the final estimator.
        F)r<   r+   r   )rB   r/   r    rk   )r   rc   Zpredict_proba_paramsrg   rP   r@   r/   r   r   r   rk     s    zPipeline.predict_probadecision_functionc             C   s>   |}x$| j ddD ]\}}}||}qW | jd d |S )a  Transform the data, and apply `decision_function` with the final estimator.

        Call `transform` of each transformer in the pipeline. The transformed
        data are finally passed to the final estimator that calls
        `decision_function` method. Only valid if the final estimator
        implements `decision_function`.

        Parameters
        ----------
        X : iterable
            Data to predict on. Must fulfill input requirements of first step
            of the pipeline.

        Returns
        -------
        y_score : ndarray of shape (n_samples, n_classes)
            Result of calling `decision_function` on the final estimator.
        F)r<   r+   r   )rB   r/   r    rl   )r   rc   rg   rP   r@   r/   r   r   r   rl     s    zPipeline.decision_functionscore_samplesc             C   s>   |}x$| j ddD ]\}}}||}qW | jd d |S )a  Transform the data, and apply `score_samples` with the final estimator.

        Call `transform` of each transformer in the pipeline. The transformed
        data are finally passed to the final estimator that calls
        `score_samples` method. Only valid if the final estimator implements
        `score_samples`.

        Parameters
        ----------
        X : iterable
            Data to predict on. Must fulfill input requirements of first step
            of the pipeline.

        Returns
        -------
        y_score : ndarray of shape (n_samples,)
            Result of calling `score_samples` on the final estimator.
        F)r<   r+   r   )rB   r/   r    rm   )r   rc   rg   rP   re   r   r   r   rm   3  s    zPipeline.score_samplespredict_log_probac             K   sB   |}x$| j ddD ]\}}}||}qW | jd d j|f|S )a\  Transform the data, and apply `predict_log_proba` with the final estimator.

        Call `transform` of each transformer in the pipeline. The transformed
        data are finally passed to the final estimator that calls
        `predict_log_proba` method. Only valid if the final estimator
        implements `predict_log_proba`.

        Parameters
        ----------
        X : iterable
            Data to predict on. Must fulfill input requirements of first step
            of the pipeline.

        **predict_log_proba_params : dict of string -> object
            Parameters to the ``predict_log_proba`` called at the end of all
            transformations in the pipeline.

        Returns
        -------
        y_log_proba : ndarray of shape (n_samples, n_classes)
            Result of calling `predict_log_proba` on the final estimator.
        F)r<   r+   r   )rB   r/   r    rn   )r   rc   Zpredict_log_proba_paramsrg   rP   r@   r/   r   r   r   rn   L  s    zPipeline.predict_log_probac             C   s   | j dkpt| j dS )Nr,   r/   )r   r2   )r   r   r   r   _can_transformi  s    zPipeline._can_transformc             C   s*   |}x |   D ]\}}}||}qW |S )a  Transform the data, and apply `transform` with the final estimator.

        Call `transform` of each transformer in the pipeline. The transformed
        data are finally passed to the final estimator that calls
        `transform` method. Only valid if the final estimator
        implements `transform`.

        This also works where final estimator is `None` in which case all prior
        transformations are applied.

        Parameters
        ----------
        X : iterable
            Data to transform. Must fulfill input requirements of first step
            of the pipeline.

        Returns
        -------
        Xt : ndarray of shape (n_samples, n_transformed_features)
            Transformed data.
        )rB   r/   )r   rc   rg   rP   r/   r   r   r   r/   n  s    zPipeline.transformc             C   s   t dd |  D S )Nc             s   s   | ]\}}}t |d V  qdS )inverse_transformN)r2   )rR   rP   r9   r   r   r   	<genexpr>  s    z2Pipeline._can_inverse_transform.<locals>.<genexpr>)allrB   )r   r   r   r   _can_inverse_transform  s    zPipeline._can_inverse_transformc             C   s2   t t|  }x|D ]\}}}||}qW |S )a  Apply `inverse_transform` for each step in a reverse order.

        All estimators in the pipeline must support `inverse_transform`.

        Parameters
        ----------
        Xt : array-like of shape (n_samples, n_transformed_features)
            Data samples, where ``n_samples`` is the number of samples and
            ``n_features`` is the number of features. Must fulfill
            input requirements of last step of pipeline's
            ``inverse_transform`` method.

        Returns
        -------
        Xt : ndarray of shape (n_samples, n_features)
            Inverse transformed data, that is, data in the original feature
            space.
        )reversedr`   rB   rp   )r   rg   Zreverse_iterrP   r/   r   r   r   rp     s    zPipeline.inverse_transformscorec       	      C   sX   |}x$| j ddD ]\}}}||}qW i }|dk	r>||d< | jd d j||f|S )a  Transform the data, and apply `score` with the final estimator.

        Call `transform` of each transformer in the pipeline. The transformed
        data are finally passed to the final estimator that calls
        `score` method. Only valid if the final estimator implements `score`.

        Parameters
        ----------
        X : iterable
            Data to predict on. Must fulfill input requirements of first step
            of the pipeline.

        y : iterable, default=None
            Targets used for scoring. Must fulfill label requirements for all
            steps of the pipeline.

        sample_weight : array-like, default=None
            If not None, this argument is passed as ``sample_weight`` keyword
            argument to the ``score`` method of the final estimator.

        Returns
        -------
        score : float
            Result of calling `score` on the final estimator.
        F)r<   Nsample_weightr+   r   )rB   r/   r    ru   )	r   rc   rd   rv   rg   rP   r@   r/   Zscore_paramsr   r   r   ru     s    zPipeline.scorec             C   s   | j d d jS )z@The classes labels. Only exist if the last step is a classifier.r+   r   )r    classes_)r   r   r   r   rw     s    zPipeline.classes_c             C   s   dt | jd d diS )Npairwiser   r   )r   r    )r   r   r   r   
_more_tags  s    zPipeline._more_tagszcAttribute `_pairwise` was deprecated in version 0.24 and will be removed in 1.1 (renaming of 0.26).c             C   s   t | jd d ddS )Nr   r   	_pairwiseF)r   r    )r   r   r   r   rz     s    zPipeline._pairwisec             C   sB   |}x8|   D ],\}}}t|ds0td|||}qW |S )aj  Get output feature names for transformation.

        Transform input features using the pipeline.

        Parameters
        ----------
        input_features : array-like of str or None, default=None
            Input features.

        Returns
        -------
        feature_names_out : ndarray of str objects
            Transformed feature names.
        get_feature_names_outzpEstimator {} does not provide get_feature_names_out. Did you mean to call pipeline[:-1].get_feature_names_out()?)rB   r2   AttributeErrorrV   r{   )r   input_featuresZfeature_names_outrP   r@   r/   r   r   r   r{     s    
zPipeline.get_feature_names_outc             C   s   | j d d jS )z7Number of features seen during first step `fit` method.r   r   )r    n_features_in_)r   r   r   r   r~     s    zPipeline.n_features_in_c             C   s   | j d d jS )z6Names of features seen during first step `fit` method.r   r   )r    feature_names_in_)r   r   r   r   r     s    zPipeline.feature_names_in_c             C   s0   yt | jd d  dS  tk
r*   dS X dS )z'Indicate whether pipeline has been fit.r+   r   TFN)r   r    r   )r   r   r   r   __sklearn_is_fitted__  s
    zPipeline.__sklearn_is_fitted__c                sJ   t | j \}}dd   fdd| jD }dd |D }td|||ddS )	Nc             S   s,   |d ks|dkr|  dS |  d|j j S )Nr,   z: passthroughz: )rH   __name__)r@   rK   r   r   r   	_get_name  s    
z-Pipeline._sk_visual_block_.<locals>._get_namec                s   g | ]\}} ||qS r   r   )rR   r@   rK   )r   r   r   
<listcomp>  s    z.Pipeline._sk_visual_block_.<locals>.<listcomp>c             S   s   g | ]}t |qS r   )str)rR   rK   r   r   r   r     s    serialF)r5   name_detailsZdash_wrapped)r0   r    r	   )r   rP   r6   r5   r   r   )r   r   _sk_visual_block_  s    zPipeline._sk_visual_block_)T)TT)N)N)N)N)NN)N)+r   
__module____qualname____doc___required_parametersr$   r'   r*   r#   rB   rC   rL   propertyrM   rI   r   rQ   r[   rf   r-   r.   r
   r   ri   rj   rk   rl   rm   rn   ro   r/   rs   rp   ru   rw   ry   r   rz   r{   r~   r   r   r   r   r   r   r   r   3   sP   X
#
	
2
#
("
$
"
c             C   s   dd | D }t t}x&t| |D ]\}}||  d7  < q"W x&t| D ]\}}|dkrL||= qLW xPttt| D ]<}|| }||krx||  d||  7  < ||  d8  < qxW tt|| S )zGenerate names for estimators.c             S   s(   g | ] }t |tr|nt|j qS r   )rD   r   r4   r   lower)rR   r8   r   r   r   r   '  s   z$_name_estimators.<locals>.<listcomp>r   z-%d)r   intr0   r`   rU   rt   ranger:   )r6   r5   Z	namecountrK   r@   kvir   r   r   _name_estimators#  s    
r   F)r!   r"   c             G   s   t t|| |dS )a  Construct a :class:`Pipeline` from the given estimators.

    This is a shorthand for the :class:`Pipeline` constructor; it does not
    require, and does not permit, naming the estimators. Instead, their names
    will be set to the lowercase of their types automatically.

    Parameters
    ----------
    *steps : list of Estimator objects
        List of the scikit-learn estimators that are chained together.

    memory : str or object with the joblib.Memory interface, default=None
        Used to cache the fitted transformers of the pipeline. By default,
        no caching is performed. If a string is given, it is the path to
        the caching directory. Enabling caching triggers a clone of
        the transformers before fitting. Therefore, the transformer
        instance given to the pipeline cannot be inspected
        directly. Use the attribute ``named_steps`` or ``steps`` to
        inspect estimators within the pipeline. Caching the
        transformers is advantageous when fitting is time consuming.

    verbose : bool, default=False
        If True, the time elapsed while fitting each step will be printed as it
        is completed.

    Returns
    -------
    p : Pipeline
        Returns a scikit-learn :class:`Pipeline` object.

    See Also
    --------
    Pipeline : Class for creating a pipeline of transforms with a final
        estimator.

    Examples
    --------
    >>> from sklearn.naive_bayes import GaussianNB
    >>> from sklearn.preprocessing import StandardScaler
    >>> from sklearn.pipeline import make_pipeline
    >>> make_pipeline(StandardScaler(), GaussianNB(priors=None))
    Pipeline(steps=[('standardscaler', StandardScaler()),
                    ('gaussiannb', GaussianNB())])
    )r!   r"   )r   r   )r!   r"   r    r   r   r   r   ;  s    -c             K   s   |  |}|d kr|S || S )N)r/   )re   rc   rd   weightrX   resr   r   r   _transform_onek  s    
r    c          	   K   sd   t ||8 t| dr(| j||f|}n| j||f||}W dQ R X |dkrX|| fS || | fS )z
    Fits ``transformer`` to ``X`` and ``y``. The transformed result is returned
    with the fitted transformer. If ``weight`` is not ``None``, the result will
    be multiplied by ``weight``.
    r.   N)r   r2   r.   r-   r/   )re   rc   rd   r   r^   r_   rX   r   r   r   r   rb   s  s    
 rb   c          	   K   s&   t || | j||f|S Q R X dS )z2
    Fits ``transformer`` to ``X`` and ``y``.
    N)r   r-   )re   rc   rd   r   r^   r_   rX   r   r   r   _fit_one  s    r   c               @   s   e Zd ZdZdgZddddddZd*d	d
Zdd Zdd Zdd Z	dd Z
eddd Zd+ddZd,ddZd-ddZdd Zdd Zd d! Zd"d# Zd$d% Zed&d' Zd(d) ZdS ).r   a
  Concatenates results of multiple transformer objects.

    This estimator applies a list of transformer objects in parallel to the
    input data, then concatenates the results. This is useful to combine
    several feature extraction mechanisms into a single transformer.

    Parameters of the transformers may be set using its name and the parameter
    name separated by a '__'. A transformer may be replaced entirely by
    setting the parameter with its name to another transformer,
    or removed by setting to 'drop'.

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

    .. versionadded:: 0.13

    Parameters
    ----------
    transformer_list : list of tuple
        List of tuple containing `(str, transformer)`. The first element
        of the tuple is name affected to the transformer while the
        second element is a scikit-learn transformer instance.
        The transformer instance can also be `"drop"` for it to be
        ignored.

        .. versionchanged:: 0.22
           Deprecated `None` as a transformer in favor of 'drop'.

    n_jobs : int, default=None
        Number of jobs to run in parallel.
        ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.
        ``-1`` means using all processors. See :term:`Glossary <n_jobs>`
        for more details.

        .. versionchanged:: v0.20
           `n_jobs` default changed from 1 to None

    transformer_weights : dict, default=None
        Multiplicative weights for features per transformer.
        Keys are transformer names, values the weights.
        Raises ValueError if key not present in ``transformer_list``.

    verbose : bool, default=False
        If True, the time elapsed while fitting each transformer will be
        printed as it is completed.

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

        .. versionadded:: 0.24

    See Also
    --------
    make_union : Convenience function for simplified feature union
        construction.

    Examples
    --------
    >>> from sklearn.pipeline import FeatureUnion
    >>> from sklearn.decomposition import PCA, TruncatedSVD
    >>> union = FeatureUnion([("pca", PCA(n_components=1)),
    ...                       ("svd", TruncatedSVD(n_components=2))])
    >>> X = [[0., 1., 3], [2., 2., 5]]
    >>> union.fit_transform(X)
    array([[ 1.5       ,  3.0...,  0.8...],
           [-1.5       ,  5.7..., -0.4...]])
    transformer_listNF)n_jobstransformer_weightsr"   c            C   s$   || _ || _|| _|| _|   d S )N)r   r   r   r"   _validate_transformers)r   r   r   r   r"   r   r   r   r$     s
    zFeatureUnion.__init__Tc             C   s   | j d|dS )a  Get parameters for this estimator.

        Returns the parameters given in the constructor as well as the
        estimators contained within the `transformer_list` of the
        `FeatureUnion`.

        Parameters
        ----------
        deep : bool, default=True
            If True, will return the parameters for this estimator and
            contained subobjects that are estimators.

        Returns
        -------
        params : mapping of string to any
            Parameter names mapped to their values.
        r   )r%   )r&   )r   r%   r   r   r   r'     s    zFeatureUnion.get_paramsc             K   s   | j d| | S )aa  Set the parameters of this estimator.

        Valid parameter keys can be listed with ``get_params()``. Note that
        you can directly set the parameters of the estimators contained in
        `tranformer_list`.

        Parameters
        ----------
        **kwargs : dict
            Parameters of this estimator or parameters of estimators contained
            in `transform_list`. Parameters of the transformers may be set
            using its name and the parameter name separated by a '__'.

        Returns
        -------
        self : object
            FeatureUnion class instance.
        r   )r   )r(   )r   r)   r   r   r   r*     s    zFeatureUnion.set_paramsc             C   sf   t | j \}}| | xH|D ]@}|dkr,qt|ds@t|drJt|dstd|t|f qW d S )Ndropr-   r.   r/   zIAll estimators should implement fit and transform. '%s' (type %s) doesn't)r0   r   r1   r2   r3   r4   )r   r5   r7   r9   r   r   r   r     s    

z#FeatureUnion._validate_transformersc             C   sJ   | j s
d S tdd | jD }x&| j D ]}||kr&td| dq&W d S )Nc             s   s   | ]\}}|V  qd S )Nr   )rR   r@   rP   r   r   r   rq   !  s    z=FeatureUnion._validate_transformer_weights.<locals>.<genexpr>z"Attempting to weight transformer "z-", but it is not present in transformer_list.)r   setr   rG   )r   Ztransformer_namesr@   r   r   r   _validate_transformer_weights  s    z*FeatureUnion._validate_transformer_weightsc                s    | j pi j  fdd| jD S )zg
        Generate (name, trans, weight) tuples excluding None and
        'drop' transformers.
        c             3   s(   | ] \}}|d kr|| |fV  qdS )r   Nr   )rR   r@   rA   )
get_weightr   r   rq   0  s   z%FeatureUnion._iter.<locals>.<genexpr>)r   getr   )r   r   )r   r   rB   )  s    
zFeatureUnion._iterzlget_feature_names is deprecated in 1.0 and will be removed in 1.2. Please use get_feature_names_out instead.c                s`   g }xV|   D ]J\ }}t|ds<tdt t|jf | fdd| D  qW |S )zGet feature names from all transformers.

        Returns
        -------
        feature_names : list of strings
            Names of the features produced by transform.
        get_feature_namesz<Transformer %s (type %s) does not provide get_feature_names.c                s   g | ]} d  | qS )rT   r   )rR   f)r@   r   r   r   H  s    z2FeatureUnion.get_feature_names.<locals>.<listcomp>)rB   r2   r|   r   r4   r   extendr   )r   feature_namesrA   r   r   )r@   r   r   5  s    
 zFeatureUnion.get_feature_namesc                sl   g }xX|   D ]L\ }}t|ds<tdt t|jf | fdd||D  qW tj	|t
dS )a4  Get output feature names for transformation.

        Parameters
        ----------
        input_features : array-like of str or None, default=None
            Input features.

        Returns
        -------
        feature_names_out : ndarray of str objects
            Transformed feature names.
        r{   z@Transformer %s (type %s) does not provide get_feature_names_out.c                s   g | ]}  d | qS )rT   r   )rR   r   )r@   r   r   r   `  s    z6FeatureUnion.get_feature_names_out.<locals>.<listcomp>)Zdtype)rB   r2   r|   r   r4   r   r   r{   npZasarrayobject)r   r}   r   rA   rP   r   )r@   r   r{   K  s    
z"FeatureUnion.get_feature_names_outc             K   s&   |  |||t}|s| S | | | S )a  Fit all transformers using X.

        Parameters
        ----------
        X : iterable or array-like, depending on transformers
            Input data, used to fit transformers.

        y : array-like of shape (n_samples, n_outputs), default=None
            Targets for supervised learning.

        **fit_params : dict, default=None
            Parameters to pass to the fit method of the estimator.

        Returns
        -------
        self : object
            FeatureUnion class instance.
        )_parallel_funcr   _update_transformer_list)r   rc   rd   rX   r7   r   r   r   r-   d  s
    
zFeatureUnion.fitc             K   sH   |  |||t}|s(t|jd dfS t| \}}| | | |S )a  Fit all transformers, transform the data and concatenate results.

        Parameters
        ----------
        X : iterable or array-like, depending on transformers
            Input data to be transformed.

        y : array-like of shape (n_samples, n_outputs), default=None
            Targets for supervised learning.

        **fit_params : dict, default=None
            Parameters to pass to the fit method of the estimator.

        Returns
        -------
        X_t : array-like or sparse matrix of                 shape (n_samples, sum_n_components)
            The `hstack` of results of transformers. `sum_n_components` is the
            sum of `n_components` (output dimension) over transformers.
        r   )r   rb   r   zerosshaper0   r   _hstack)r   rc   rd   rX   resultsXsr7   r   r   r   r.     s    
zFeatureUnion.fit_transformc             C   s   | j s
d S d|||f S )Nz(step %d of %d) Processing %s)r"   )r   r@   r?   totalr   r   r   rQ     s    zFeatureUnion._log_messagec                sV   t j_    t  tjd fddtdD S )z Runs func in parallel on X and y)r   c          
   3   sF   | ]>\}\}}}t | |fd ||tdV  qdS )r   )r^   r_   N)r   rQ   r:   )rR   r?   r@   re   r   )rc   rX   funcr   r7   rd   r   r   rq     s   	z.FeatureUnion._parallel_func.<locals>.<genexpr>r   )r`   r   r   r   rB   r   r   r;   )r   rc   rd   rX   r   r   )rc   rX   r   r   r7   rd   r   r     s    
	zFeatureUnion._parallel_funcc                sD   t | jd fdd|  D }|s:t jd dfS | |S )a  Transform X separately by each transformer, concatenate results.

        Parameters
        ----------
        X : iterable or array-like, depending on transformers
            Input data to be transformed.

        Returns
        -------
        X_t : array-like or sparse matrix of                 shape (n_samples, sum_n_components)
            The `hstack` of results of transformers. `sum_n_components` is the
            sum of `n_components` (output dimension) over transformers.
        )r   c             3   s&   | ]\}}}t t| d |V  qd S )N)r   r   )rR   r@   rA   r   )rc   r   r   rq     s   z)FeatureUnion.transform.<locals>.<genexpr>r   )r   r   rB   r   r   r   r   )r   rc   r   r   )rc   r   r/     s    

zFeatureUnion.transformc             C   s0   t dd |D r"t| }n
t|}|S )Nc             s   s   | ]}t |V  qd S )N)r   issparse)rR   r   r   r   r   rq     s    z'FeatureUnion._hstack.<locals>.<genexpr>)anyr   ZhstackZtocsrr   )r   r   r   r   r   r     s    
zFeatureUnion._hstackc                s*   t    fdd| jD | jd d < d S )Nc                s(   g | ] \}}||d kr|nt  fqS )r   )next)rR   r@   old)r7   r   r   r     s   z9FeatureUnion._update_transformer_list.<locals>.<listcomp>)iterr   )r   r7   r   )r7   r   r     s    
z%FeatureUnion._update_transformer_listc             C   s   | j d d jS )z+Number of features seen during :term:`fit`.r   r   )r   r~   )r   r   r   r   r~     s    zFeatureUnion.n_features_in_c             C   s   t | j \}}td||dS )Nparallel)r5   )r0   r   r	   )r   r5   r7   r   r   r   r     s    zFeatureUnion._sk_visual_block_)T)N)N)N)r   r   r   r   r   r$   r'   r*   r   r   rB   r   r   r{   r-   r.   rQ   r   r/   r   r   r   r~   r   r   r   r   r   r     s(   F



)r   r"   c             G   s   t t|| |dS )a(  
    Construct a FeatureUnion from the given transformers.

    This is a shorthand for the FeatureUnion constructor; it does not require,
    and does not permit, naming the transformers. Instead, they will be given
    names automatically based on their types. It also does not allow weighting.

    Parameters
    ----------
    *transformers : list of estimators

    n_jobs : int, default=None
        Number of jobs to run in parallel.
        ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.
        ``-1`` means using all processors. See :term:`Glossary <n_jobs>`
        for more details.

        .. versionchanged:: v0.20
           `n_jobs` default changed from 1 to None

    verbose : bool, default=False
        If True, the time elapsed while fitting each transformer will be
        printed as it is completed.

    Returns
    -------
    f : FeatureUnion

    See Also
    --------
    FeatureUnion : Class for concatenating the results of multiple transformer
        objects.

    Examples
    --------
    >>> from sklearn.decomposition import PCA, TruncatedSVD
    >>> from sklearn.pipeline import make_union
    >>> make_union(PCA(), TruncatedSVD())
     FeatureUnion(transformer_list=[('pca', PCA()),
                                   ('truncatedsvd', TruncatedSVD())])
    )r   r"   )r   r   )r   r"   r7   r   r   r   r     s    *)r   N)r   N)+r   collectionsr   	itertoolsr   numpyr   Zscipyr   Zjoblibr   baser   r   Zutils._estimator_html_reprr	   Zutils.metaestimatorsr
   utilsr   r   Zutils.deprecationr   Zutils._tagsr   Zutils.validationr   r   Zutils.fixesr   
exceptionsr   r   __all__r   r   r   r   r   rb   r   r   r   r   r   r   r   <module>   sB        u0	

  ^