B
    	\"                 @   sh   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
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)check_arraysafe_indexing)FunctionTransformerTransformedTargetRegressorc               @   s4   e Zd ZdZdddZdd Zddd	Zd
d ZdS )r
   a  Meta-estimator to regress on a transformed target.

    Useful for applying a non-linear transformation in regression
    problems. This transformation can be given as a Transformer such as the
    QuantileTransformer or as a function and its inverse such as ``log`` and
    ``exp``.

    The computation during ``fit`` is::

        regressor.fit(X, func(y))

    or::

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

    The computation during ``predict`` is::

        inverse_func(regressor.predict(X))

    or::

        transformer.inverse_transform(regressor.predict(X))

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

    Parameters
    ----------
    regressor : object, default=LinearRegression()
        Regressor object such as derived from ``RegressorMixin``. This
        regressor will automatically be cloned each time prior to fitting.

    transformer : object, default=None
        Estimator object such as derived from ``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, optional
        Function to apply to ``y`` before passing to ``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, optional
        Function to apply to the prediction of the regressor. Cannot be set at
        the same time as ``transformer`` as well. 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 ``fit`` and ``predict``.

    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) # doctest: +ELLIPSIS
    TransformedTargetRegressor(...)
    >>> tt.score(X, y)
    1.0
    >>> tt.regressor_.coef_
    array([2.])

    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>`.

    NTc             C   s"   || _ || _|| _|| _|| _d S )N)	regressortransformerfuncinverse_funccheck_inverse)selfr   r   r   r   r    r   6lib/python3.7/site-packages/sklearn/compose/_target.py__init__k   s
    z#TransformedTargetRegressor.__init__c             C   s   | j dk	r(| jdk	s| jdk	r(tdnL| j dk	r@t| j | _n4| jdk	r\| jdk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_transformers   s&    




z+TransformedTargetRegressor._fit_transformerc             C   s   t |ddddd}|j| _|jdkr2|dd}n|}| | | j|}|jdkrp|jd dkrp|jdd}| j	d	krdd
l
m} | | _nt| j	| _|d	kr| j|| n| jj|||d | S )ao  Fit the model according to the given training data.

        Parameters
        ----------
        X : {array-like, sparse matrix}, 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, 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.

        Returns
        -------
        self : object
        FTZnumeric)Zaccept_sparseZforce_all_finiteZ	ensure_2dZdtyper   r   )axisN)LinearRegression)sample_weight)r   ndim_training_dimreshaper#   r   r   r   squeezer   Zlinear_modelr&   
regressor_r   r   )r   Xr"   r'   Zy_2dZy_transr&   r   r   r   r      s$    




zTransformedTargetRegressor.fitc             C   st   t | d | j|}|jdkr6| j|dd}n| j|}| jdkrp|jdkrp|jd dkrp|j	dd}|S )a  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}, shape = (n_samples, n_features)
            Samples.

        Returns
        -------
        y_hat : array, shape = (n_samples,)
            Predicted values.

        r,   r   r$   r   )r%   )
r   r,   predictr(   r   r   r*   r)   r   r+   )r   r-   ZpredZ
pred_transr   r   r   r.      s    


z"TransformedTargetRegressor.predict)NNNNT)N)__name__
__module____qualname____doc__r   r#   r   r.   r   r   r   r   r
      s   Y 
$
8)r   Znumpyr   baser   r   r   Zutils.validationr   Zutilsr   r   Zpreprocessingr	   __all__r
   r   r   r   r   <module>   s   