B
    	\O4                 @   s   d dl Zd dlmZ d dlmZ ddlmZmZm	Z	 ddl
mZmZmZ ddlmZmZ d dlZd dlZdd	d
gZdd Zddd	ZG dd
 d
eee	ZdS )    N)interpolate)	spearmanr   )BaseEstimatorTransformerMixinRegressorMixin)as_float_arraycheck_arraycheck_consistent_length)'_inplace_contiguous_isotonic_regression_make_uniquecheck_increasingisotonic_regressionIsotonicRegressionc       	      C   s   t | |\}}|dk}|dkrt| dkrdtd| d|   }dtt| d  }t|d|  }t|d|  }t|t|krt	d |S )	aC  Determine whether y is monotonically correlated with x.

    y is found increasing or decreasing with respect to x based on a Spearman
    correlation test.

    Parameters
    ----------
    x : array-like, shape=(n_samples,)
            Training data.

    y : array-like, shape=(n_samples,)
        Training target.

    Returns
    -------
    increasing_bool : boolean
        Whether the relationship is increasing or decreasing.

    Notes
    -----
    The Spearman correlation coefficient is estimated from the data, and the
    sign of the resulting estimate is used as the result.

    In the event that the 95% confidence interval based on Fisher transform
    spans zero, a warning is raised.

    References
    ----------
    Fisher transformation. Wikipedia.
    https://en.wikipedia.org/wiki/Fisher_transformation
    r   )g      g      ?   g      ?g      ?r   g\(\?zwConfidence interval of the Spearman correlation coefficient spans zero. Determination of ``increasing`` may be suspect.)
r   lenmathlogZsqrtZtanhnpZsignwarningswarn)	xyZrho_Zincreasing_boolFZF_seZrho_0Zrho_1 r   /lib/python3.7/site-packages/sklearn/isotonic.pyr      s    "
Tc             C   s   |rt jdd nt jddd }t j| | t jd} |dkrTt jt| t jd}nt j|| t jd}t| | |dk	s|dk	r|dkrt j }|dkrt j}t | |||  | | S )a  Solve the isotonic regression model::

        min sum w[i] (y[i] - y_[i]) ** 2

        subject to y_min = y_[1] <= y_[2] ... <= y_[n] = y_max

    where:
        - y[i] are inputs (real numbers)
        - y_[i] are fitted
        - w[i] are optional strictly positive weights (default to 1.0)

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

    Parameters
    ----------
    y : iterable of floats
        The data.

    sample_weight : iterable of floats, optional, default: None
        Weights on each point of the regression.
        If None, weight is set to 1 (equal weights).

    y_min : optional, default: None
        If not None, set the lowest value of the fit to y_min.

    y_max : optional, default: None
        If not None, set the highest value of the fit to y_max.

    increasing : boolean, optional, default: True
        Whether to compute ``y_`` is increasing (if set to True) or decreasing
        (if set to False)

    Returns
    -------
    y_ : list of floats
        Isotonic fit of y.

    References
    ----------
    "Active set algorithms for isotonic regression; A unifying framework"
    by Michael J. Best and Nilotpal Chakravarti, section 3.
    N)dtype)	r   Zs_arrayfloat64onesr   r   infclip)r   sample_weighty_miny_max
increasingorderr   r   r   r   M   s    ,"
c                   sl   e Zd ZdZdddZdddZd	d
 ZdddZdddZdd Z	dd Z
 fddZ fddZ  ZS )r   aI	  Isotonic regression model.

    The isotonic regression optimization problem is defined by::

        min sum w_i (y[i] - y_[i]) ** 2

        subject to y_[i] <= y_[j] whenever X[i] <= X[j]
        and min(y_) = y_min, max(y_) = y_max

    where:
        - ``y[i]`` are inputs (real numbers)
        - ``y_[i]`` are fitted
        - ``X`` specifies the order.
          If ``X`` is non-decreasing then ``y_`` is non-decreasing.
        - ``w[i]`` are optional strictly positive weights (default to 1.0)

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

    Parameters
    ----------
    y_min : optional, default: None
        If not None, set the lowest value of the fit to y_min.

    y_max : optional, default: None
        If not None, set the highest value of the fit to y_max.

    increasing : boolean or string, optional, default: True
        If boolean, whether or not to fit the isotonic regression with y
        increasing or decreasing.

        The string value "auto" determines whether y should
        increase or decrease based on the Spearman correlation estimate's
        sign.

    out_of_bounds : string, optional, default: "nan"
        The ``out_of_bounds`` parameter handles how x-values outside of the
        training domain are handled.  When set to "nan", predicted y-values
        will be NaN.  When set to "clip", predicted y-values will be
        set to the value corresponding to the nearest train interval endpoint.
        When set to "raise", allow ``interp1d`` to throw ValueError.


    Attributes
    ----------
    X_min_ : float
        Minimum value of input array `X_` for left bound.

    X_max_ : float
        Maximum value of input array `X_` for right bound.

    f_ : function
        The stepwise interpolating function that covers the input domain ``X``.

    Notes
    -----
    Ties are broken using the secondary method from Leeuw, 1977.

    References
    ----------
    Isotonic Median Regression: A Linear Programming Approach
    Nilotpal Chakravarti
    Mathematics of Operations Research
    Vol. 14, No. 2 (May, 1989), pp. 303-308

    Isotone Optimization in R : Pool-Adjacent-Violators
    Algorithm (PAVA) and Active Set Methods
    Leeuw, Hornik, Mair
    Journal of Statistical Software 2009

    Correctness of Kruskal's algorithms for monotone regression with ties
    Leeuw, Psychometrica, 1977
    NTnanc             C   s   || _ || _|| _|| _d S )N)r%   r&   r'   out_of_bounds)selfr%   r&   r'   r*   r   r   r   __init__   s    zIsotonicRegression.__init__c             C   s   t |jdkrtdd S )Nr   zX should be a 1d array)r   shape
ValueError)r+   Xr   r$   r   r   r   _check_fit_data   s    z"IsotonicRegression._check_fit_datac                sX   | j dkrtd| j | j dk}t dkr@ fdd| _ntj| d|d| _d	S )
zBuild the f_ interp1d function.)raiser)   r#   zIThe argument ``out_of_bounds`` must be in 'nan', 'clip', 'raise'; got {0}r1   r   c                s     | jS )N)repeatr-   )r   )r   r   r   <lambda>   s    z-IsotonicRegression._build_f.<locals>.<lambda>Zlinear)Zkindbounds_errorN)r*   r.   formatr   f_r   Zinterp1d)r+   r/   r   r4   r   )r   r   _build_f   s    



zIsotonicRegression._build_fc       
   	      s  t ||| dd ||gD \}}t|}| ||| | jdkrPt||| _n| j| _|dk	rt|dd}|dk}|| || ||   }}}ntt	|}t
||f  fdd|||gD \}}}t|||\}}}| | _}t||| j| j| jd	 | _}t|t| | _| _|rtjt	|ftd
}	tt|dd |dd t|dd |dd |	dd< ||	 ||	 fS ||fS dS )z Build the y_ IsotonicRegression.c             S   s   g | ]}t |d dqS )F)	ensure_2d)r	   ).0r   r   r   r   
<listcomp>   s    z/IsotonicRegression._build_y.<locals>.<listcomp>autoNF)r8   r   c                s    g | ]}|  j tjd dqS )F)copy)Zastyper   r    )r9   r   )r(   r   r   r:     s   )r'   )r   r   r      )r
   r   r0   r'   r   Zincreasing_r	   r   r!   r   Zlexsortr   Z_X_r   r%   r&   Z_y_minmaxX_min_X_max_boolZ
logical_orZ	not_equal)
r+   r/   r   r$   Ztrim_duplicatesmaskZunique_XZunique_yZunique_sample_weightZ	keep_datar   )r(   r   _build_y   s:    


&zIsotonicRegression._build_yc             C   s0   |  |||\}}|| | _| _| || | S )ax  Fit the model using X, y as training data.

        Parameters
        ----------
        X : array-like, shape=(n_samples,)
            Training data.

        y : array-like, shape=(n_samples,)
            Training target.

        sample_weight : array-like, shape=(n_samples,), optional, default: None
            Weights. If set to None, all weights will be set to 1 (equal
            weights).

        Returns
        -------
        self : object
            Returns an instance of self.

        Notes
        -----
        X is stored for future use, as `transform` needs X to interpolate
        new input data.
        )rE   _necessary_X__necessary_y_r7   )r+   r/   r   r$   r   r   r   fit(  s    zIsotonicRegression.fitc             C   s^   t |}t|jdkrtd| jdkr8td| j| jdkrTt|| j| j	}| 
|S )a  Transform new data by linear interpolation

        Parameters
        ----------
        T : array-like, shape=(n_samples,)
            Data to transform.

        Returns
        -------
        T_ : array, shape=(n_samples,)
            The transformed data
        r   z.Isotonic regression input should be a 1d array)r1   r)   r#   zIThe argument ``out_of_bounds`` must be in 'nan', 'clip', 'raise'; got {0}r#   )r   r   r-   r.   r*   r5   r   r#   rA   rB   r6   )r+   Tr   r   r   	transformO  s    


zIsotonicRegression.transformc             C   s
   |  |S )a	  Predict new data by linear interpolation.

        Parameters
        ----------
        T : array-like, shape=(n_samples,)
            Data to transform.

        Returns
        -------
        T_ : array, shape=(n_samples,)
            Transformed data.
        )rJ   )r+   rI   r   r   r   predictj  s    zIsotonicRegression.predictc                s   t t|  }|dd |S )z1Pickle-protocol - return state of the estimator. r6   N)superr   __getstate__pop)r+   state)	__class__r   r   rM   y  s    zIsotonicRegression.__getstate__c                s8   t t| | t| dr4t| dr4| | j| j dS )znPickle-protocol - set state of the estimator.

        We need to rebuild the interpolation function.
        rF   rG   N)rL   r   __setstate__hasattrr7   rF   rG   )r+   rO   )rP   r   r   rQ     s    zIsotonicRegression.__setstate__)NNTr)   )N)T)N)__name__
__module____qualname____doc__r,   r0   r7   rE   rH   rJ   rK   rM   rQ   __classcell__r   r   )rP   r   r      s   H 


8
')NNNT)Znumpyr   Zscipyr   Zscipy.statsr   baser   r   r   Zutilsr   r	   r
   Z	_isotonicr   r   r   r   __all__r   r   r   r   r   r   r   <module>   s   9 
=