3
[h7                 @   s   d dl Zd dlmZ d dlmZ d dlZd dlZddl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 d	d
dgZdd	 Zeddddddd
ZG dd dee
e	ZdS )    N)interpolate)	spearmanr   )BaseEstimatorTransformerMixinRegressorMixin)check_arraycheck_consistent_length)_check_sample_weight_deprecate_positional_args)'_inplace_contiguous_isotonic_regression_make_uniquecheck_increasingisotonic_regressionIsotonicRegressionc       	      C   s   t | |\}}|dk}|d	krt| dkrdtjd| d|   }dtjt| d  }tj|d|  }tj|d|  }tj|tj|krtj	d |S )
aG  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 of shape (n_samples,)
            Training data.

    y : array-like of 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      ?r   g\(\?zwConfidence interval of the Spearman correlation coefficient spans zero. Determination of ``increasing`` may be suspect.      )r   r   )
r   lenmathlogsqrttanhnpsignwarningswarn)	xyrho_Zincreasing_boolFZF_seZrho_0Zrho_1 r"   8/tmp/pip-build-zwgx3nbq/scikit-learn/sklearn/isotonic.pyr      s    "
T)sample_weighty_miny_max
increasingc            C   s   |rt jdd nt jddd }t| dt jt jgd} t j| | | jd} t|| | jd}t j|| }t	| | |dk	s|dk	r|dkrt j
 }|dkrt j
}t j| |||  | | S )a  Solve the isotonic regression model.

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

    Parameters
    ----------
    y : array-like of shape (n_samples,)
        The data.

    sample_weight : array-like of shape (n_samples,), default=None
        Weights on each point of the regression.
        If None, weight is set to 1 (equal weights).

    y_min : float, default=None
        Lower bound on the lowest predicted value (the minimum value may
        still be higher). If not set, defaults to -inf.

    y_max : float, default=None
        Upper bound on the highest predicted value (the maximum may still be
        lower). If not set, defaults to +inf.

    increasing : bool, 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.
    Nr   F)	ensure_2ddtype)r)   )r   Zs_r   float64float32arrayr)   r
   Zascontiguousarrayr   infclip)r   r$   r%   r&   r'   orderr"   r"   r#   r   O   s    &"
c                   s   e Zd ZdZedddddddZ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dd Z  ZS )r   au
  Isotonic regression model.

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

    .. versionadded:: 0.13

    Parameters
    ----------
    y_min : float, default=None
        Lower bound on the lowest predicted value (the minimum value may
        still be higher). If not set, defaults to -inf.

    y_max : float, default=None
        Upper bound on the highest predicted value (the maximum may still be
        lower). If not set, defaults to +inf.

    increasing : bool or 'auto', default=True
        Determines whether the predictions should be constrained to increase
        or decrease with `X`. 'auto' will decide based on the Spearman
        correlation estimate's sign.

    out_of_bounds : {'nan', 'clip', 'raise'}, default='nan'
        Handles how `X` values outside of the training domain are handled
        during prediction.

        - 'nan', predictions will be NaN.
        - 'clip', predictions will be set to the value corresponding to
          the nearest train interval endpoint.
        - 'raise', a `ValueError` is raised.

    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.

    X_thresholds_ : ndarray of shape (n_thresholds,)
        Unique ascending `X` values used to interpolate
        the y = f(X) monotonic function.

        .. versionadded:: 0.24

    y_thresholds_ : ndarray of shape (n_thresholds,)
        De-duplicated `y` values suitable to interpolate the y = f(X)
        monotonic function.

        .. versionadded:: 0.24

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

    increasing_ : bool
        Inferred value for ``increasing``.

    Notes
    -----
    Ties are broken using the secondary method from de 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
    de Leeuw, Hornik, Mair
    Journal of Statistical Software 2009

    Correctness of Kruskal's algorithms for monotone regression with ties
    de Leeuw, Psychometrica, 1977

    Examples
    --------
    >>> from sklearn.datasets import make_regression
    >>> from sklearn.isotonic import IsotonicRegression
    >>> X, y = make_regression(n_samples=10, n_features=1, random_state=41)
    >>> iso_reg = IsotonicRegression().fit(X, y)
    >>> iso_reg.predict([.1, .2])
    array([1.8628..., 3.7256...])
    NTnan)r%   r&   r'   out_of_boundsc            C   s   || _ || _|| _|| _d S )N)r%   r&   r'   r2   )selfr%   r&   r'   r2   r"   r"   r#   __init__   s    zIsotonicRegression.__init__c             C   s2   |j dkp |j dko |jd dks.d}t|d S )Nr      zKIsotonic regression input X should be a 1d array or 2d array with 1 feature)ndimshape
ValueError)r3   Xmsgr"   r"   r#   _check_input_data_shape   s    "z*IsotonicRegression._check_input_data_shapec                sX   | j dkrtdj| j | j dk}t dkr@ fdd| _ntj| d|d	| _d
S )zBuild the f_ interp1d function.raiser1   r/   zIThe argument ``out_of_bounds`` must be in 'nan', 'clip', 'raise'; got {0}r   c                s    j | jS )N)repeatr7   )r   )r   r"   r#   <lambda>   s    z-IsotonicRegression._build_f.<locals>.<lambda>Zlinear)kindbounds_errorN)r<   r1   r/   )r2   r8   formatr   f_r   Zinterp1d)r3   r9   r   r@   r"   )r   r#   _build_f   s    



zIsotonicRegression._build_fc       
         sV  | j | |jd
}| jdkr,t||| _n| j| _t|||jd}|dk}|| || ||   }}}tj||f  fdd|||gD \}}}t	|||\}}}|}t
||| j| j| jd}tj|tj| | _| _|rJtjt|ftd}	tjtj|dd |dd tj|dd |d	d |	dd< ||	 ||	 fS ||fS dS )z Build the y_ IsotonicRegression.r   auto)r)   r   c                s   g | ]}|  qS r"   r"   ).0r-   )r0   r"   r#   
<listcomp>  s    z/IsotonicRegression._build_y.<locals>.<listcomp>)r$   r%   r&   r'   Nr5   r*   r*   r*   r*   )r;   reshaper'   r   Zincreasing_r
   r)   r   Zlexsortr   r   r%   r&   minmaxX_min_X_max_Zonesr   bool
logical_or	not_equal)
r3   r9   r   r$   Ztrim_duplicatesmaskZunique_XZunique_yZunique_sample_weightZ	keep_datar"   )r0   r#   _build_y   s0    



&zIsotonicRegression._build_yc             C   sz   t ddd}t|fdtjtjgi|}t|fd|ji|}t||| | j|||\}}|| | _| _	| j
|| | S )a  Fit the model using X, y as training data.

        Parameters
        ----------
        X : array-like of shape (n_samples,) or (n_samples, 1)
            Training data.

            .. versionchanged:: 0.24
               Also accepts 2d array with 1 feature.

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

        sample_weight : array-like of shape (n_samples,), 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 :meth:`transform` needs X to interpolate
        new input data.
        F)Zaccept_sparser(   r)   )dictr   r   r+   r,   r)   r	   rQ   X_thresholds_y_thresholds_rC   )r3   r9   r   r$   Zcheck_paramsr"   r"   r#   fit)  s    zIsotonicRegression.fitc             C   s   t | dr| jj}ntj}t||dd}| j| |jd	}| jd
krVt	dj
| j| jdkrrtj|| j| j}| j|}|j|j}|S )a  Transform new data by linear interpolation

        Parameters
        ----------
        T : array-like of shape (n_samples,) or (n_samples, 1)
            Data to transform.

            .. versionchanged:: 0.24
               Also accepts 2d array with 1 feature.

        Returns
        -------
        y_pred : ndarray of shape (n_samples,)
            The transformed data
        rS   F)r)   r(   r   r<   r1   r/   zIThe argument ``out_of_bounds`` must be in 'nan', 'clip', 'raise'; got {0}r*   )r<   r1   r/   )hasattrrS   r)   r   r+   r   r;   rH   r2   r8   rA   r/   rK   rL   rB   Zastype)r3   Tr)   resr"   r"   r#   	transformX  s    







zIsotonicRegression.transformc             C   s
   | j |S )a%  Predict new data by linear interpolation.

        Parameters
        ----------
        T : array-like of shape (n_samples,) or (n_samples, 1)
            Data to transform.

        Returns
        -------
        y_pred : ndarray of shape (n_samples,)
            Transformed data.
        )rY   )r3   rW   r"   r"   r#   predict  s    zIsotonicRegression.predictc                s   t  j }|jdd |S )z1Pickle-protocol - return state of the estimator. rB   N)super__getstate__pop)r3   state)	__class__r"   r#   r\     s    
zIsotonicRegression.__getstate__c                s4   t  j| t| dr0t| dr0| j| j| j dS )znPickle-protocol - set state of the estimator.

        We need to rebuild the interpolation function.
        rS   rT   N)r[   __setstate__rV   rC   rS   rT   )r3   r^   )r_   r"   r#   r`     s    zIsotonicRegression.__setstate__c             C   s
   ddgiS )NZX_typesZ1darrayr"   )r3   r"   r"   r#   
_more_tags  s    zIsotonicRegression._more_tags)T)N)__name__
__module____qualname____doc__r   r4   r;   rC   rQ   rU   rY   rZ   r\   r`   ra   __classcell__r"   r"   )r_   r#   r      s   T
/
/+	)Znumpyr   Zscipyr   Zscipy.statsr   r   r   baser   r   r   utilsr   r	   Zutils.validationr
   r   Z	_isotonicr   r   __all__r   r   r   r"   r"   r"   r#   <module>   s   95