a
    ;Za*                     @   s   d dl Z d dlZddlmZ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	gZG d
d	 d	eeZdS )    N   )BaseEstimatorRegressorMixinclone)check_is_fitted)
_safe_tags)check_array_safe_indexing)FunctionTransformer)NotFittedErrorTransformedTargetRegressorc                   @   sR   e Zd ZdZddddddddZdd Zd	d
 Zdd Zdd Ze	dd Z
dS )r   a  Meta-estimator to regress on a transformed target.

    Useful for applying a non-linear transformation to the target `y` in
    regression problems. This transformation can be given as a Transformer
    such as the :class:`~sklearn.preprocessing.QuantileTransformer` or as a
    function and its inverse such as `np.log` and `np.exp`.

    The computation during :meth:`fit` is::

        regressor.fit(X, func(y))

    or::

        regressor.fit(X, transformer.transform(y))

    The computation during :meth:`predict` is::

        inverse_func(regressor.predict(X))

    or::

        transformer.inverse_transform(regressor.predict(X))

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

    .. versionadded:: 0.20

    Parameters
    ----------
    regressor : object, default=None
        Regressor object such as derived from
        :class:`~sklearn.base.RegressorMixin`. This regressor will
        automatically be cloned each time prior to fitting. If `regressor is
        None`, :class:`~sklearn.linear_model.LinearRegression` is created and used.

    transformer : object, default=None
        Estimator object such as derived from
        :class:`~sklearn.base.TransformerMixin`. Cannot be set at the same time
        as `func` and `inverse_func`. If `transformer is None` as well as
        `func` and `inverse_func`, the transformer will be an identity
        transformer. Note that the transformer will be cloned during fitting.
        Also, the transformer is restricting `y` to be a numpy array.

    func : function, default=None
        Function to apply to `y` before passing to :meth:`fit`. Cannot be set
        at the same time as `transformer`. The function needs to return a
        2-dimensional array. If `func is None`, the function used will be the
        identity function.

    inverse_func : function, default=None
        Function to apply to the prediction of the regressor. Cannot be set at
        the same time as `transformer`. The function needs to return a
        2-dimensional array. The inverse function is used to return
        predictions to the same space of the original training labels.

    check_inverse : bool, default=True
        Whether to check that `transform` followed by `inverse_transform`
        or `func` followed by `inverse_func` leads to the original targets.

    Attributes
    ----------
    regressor_ : object
        Fitted regressor.

    transformer_ : object
        Transformer used in :meth:`fit` and :meth:`predict`.

    n_features_in_ : int
        Number of features seen during :term:`fit`. Only defined if the
        underlying regressor 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

    See Also
    --------
    sklearn.preprocessing.FunctionTransformer : Construct a transformer from an
        arbitrary callable.

    Notes
    -----
    Internally, the target `y` is always converted into a 2-dimensional array
    to be used by scikit-learn transformers. At the time of prediction, the
    output will be reshaped to a have the same number of dimensions as `y`.

    See :ref:`examples/compose/plot_transformed_target.py
    <sphx_glr_auto_examples_compose_plot_transformed_target.py>`.

    Examples
    --------
    >>> import numpy as np
    >>> from sklearn.linear_model import LinearRegression
    >>> from sklearn.compose import TransformedTargetRegressor
    >>> tt = TransformedTargetRegressor(regressor=LinearRegression(),
    ...                                 func=np.log, inverse_func=np.exp)
    >>> X = np.arange(4).reshape(-1, 1)
    >>> y = np.exp(2 * X).ravel()
    >>> tt.fit(X, y)
    TransformedTargetRegressor(...)
    >>> tt.score(X, y)
    1.0
    >>> tt.regressor_.coef_
    array([2.])
    NT)transformerfuncinverse_funccheck_inversec                C   s"   || _ || _|| _|| _|| _d S )N)	regressorr   r   r   r   )selfr   r   r   r   r    r   6lib/python3.9/site-packages/sklearn/compose/_target.py__init__   s
    	z#TransformedTargetRegressor.__init__c                 C   s   | j dur(| jdus| jdur(tdnL| j dur@t| j | _n4| jdur\| jdu r\tdt| j| jd| jd| _| j| | jrt	ddt
d|jd d }t||}| j|}t|| j|std	t dS )
zCheck transformer and fit transformer.

        Create the default transformer, fit it and make additional inverse
        check on a subset (optional).

        NzE'transformer' and functions 'func'/'inverse_func' cannot both be set.z=When 'func' is provided, 'inverse_func' must also be providedT)r   r   Zvalidater      r   
   zThe provided functions or transformer are not strictly inverse of each other. If you are sure you want to proceed regardless, set 'check_inverse=False')r   r   r   
ValueErrorr   transformer_r
   r   fitslicemaxshaper	   	transformnpZallcloseinverse_transformwarningswarnUserWarning)r   yZidx_selectedZy_selZy_sel_tr   r   r   _fit_transformer   s<    



z+TransformedTargetRegressor._fit_transformerc                 K   s   t |dddddd}|j| _|jdkr4|dd}n|}| | | j|}|jdkrr|jd dkrr|jdd}| j	d	u rdd
l
m} | | _nt| j	| _| jj||fi | t| jdr| jj| _| S )aB  Fit the model according to the given training data.

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

        y : array-like of shape (n_samples,)
            Target values.

        **fit_params : dict
            Parameters passed to the `fit` method of the underlying
            regressor.

        Returns
        -------
        self : object
            Fitted estimator.
        FTZnumeric)Zaccept_sparseZforce_all_finiteZ	ensure_2dZdtypeZallow_ndr   r   ZaxisNLinearRegressionfeature_names_in_)r   ndim_training_dimreshaper%   r   r   r   squeezer   linear_modelr)   
regressor_r   r   hasattrr*   )r   Xr$   Z
fit_paramsZy_2dZy_transr)   r   r   r   r      s0    




zTransformedTargetRegressor.fitc                 K   sz   t |  | jj|fi |}|jdkr<| j|dd}n| j|}| jdkrv|jdkrv|jd dkrv|j	dd}|S )aK  Predict using the base regressor, applying inverse.

        The regressor is used to predict and the `inverse_func` or
        `inverse_transform` is applied before returning the prediction.

        Parameters
        ----------
        X : {array-like, sparse matrix} of shape (n_samples, n_features)
            Samples.

        **predict_params : dict of str -> object
            Parameters passed to the `predict` method of the underlying
            regressor.

        Returns
        -------
        y_hat : ndarray of shape (n_samples,)
            Predicted values.
        r   r&   r   r'   )
r   r0   predictr+   r   r    r-   r,   r   r.   )r   r2   Zpredict_paramsZpredZ
pred_transr   r   r   r3      s    
z"TransformedTargetRegressor.predictc                 C   s2   | j }|d u r ddlm} | }dt|dddS )Nr   r(   Tmultioutput)key)Z
poor_scorer4   )r   r/   r)   r   )r   r   r)   r   r   r   
_more_tags   s    
z%TransformedTargetRegressor._more_tagsc              
   C   sN   zt |  W n8 tyD } z td| jj|W Y d}~n
d}~0 0 | jjS )z+Number of features seen during :term:`fit`.z*{} object has no n_features_in_ attribute.N)r   r   AttributeErrorformat	__class____name__r0   n_features_in_)r   Znfer   r   r   r;   ,  s    z)TransformedTargetRegressor.n_features_in_)N)r:   
__module____qualname____doc__r   r%   r   r3   r6   propertyr;   r   r   r   r   r      s   p ,@#)r!   Znumpyr   baser   r   r   Zutils.validationr   Zutils._tagsr   Zutilsr   r	   Zpreprocessingr
   
exceptionsr   __all__r   r   r   r   r   <module>   s   