U
    ^»{jÚž  ã                   @   sh  d Z ddlZddlZddlmZ ddlmZ ddlm	Z	 ddl
mZmZmZmZmZmZmZmZmZmZmZ dd	lmZmZmZmZmZmZ G d
d„ dƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZ G dd„ deƒZ!G dd„ deƒZ"G dd„ deƒZ#G dd„ deƒZ$G dd„ deƒZ%G dd„ deƒZ&G dd„ deƒZ'G d d!„ d!eƒZ(eee e!e"e#e$e&e'e(d"œ
Z)dS )#z¹
This module contains loss classes suitable for fitting.

It is not part of the public API.
Specific losses are used for regression, binary classification or multiclass
classification.
é    N©Úxlogyé   )Úcheck_scalar)Ú_weighted_percentileé   )ÚCyAbsoluteErrorÚCyExponentialLossÚCyHalfBinomialLossÚCyHalfGammaLossÚCyHalfMultinomialLossÚCyHalfPoissonLossÚCyHalfSquaredErrorÚCyHalfTweedieLossÚCyHalfTweedieLossIdentityÚCyHuberLossÚCyPinballLoss)ÚHalfLogitLinkÚIdentityLinkÚIntervalÚ	LogitLinkÚLogLinkÚMultinomialLogitc                   @   sŒ   e Zd ZdZdZdZdZddd„Zdd„ Zd	d
„ Z	ddd„Z
ddd„Zd dd„Zd!dd„Zd"dd„Zd#dd„Zd$dd„Zejdfdd„ZdS )%ÚBaseLossa  Base class for a loss function of 1-dimensional targets.

    Conventions:

        - y_true.shape = sample_weight.shape = (n_samples,)
        - y_pred.shape = raw_prediction.shape = (n_samples,)
        - If is_multiclass is true (multiclass classification), then
          y_pred.shape = raw_prediction.shape = (n_samples, n_classes)
          Note that this corresponds to the return value of decision_function.

    y_true, y_pred, sample_weight and raw_prediction must either be all float64
    or all float32.
    gradient and hessian must be either both float64 or both float32.

    Note that y_pred = link.inverse(raw_prediction).

    Specific loss classes can inherit specific link classes to satisfy
    BaseLink's abstractmethods.

    Parameters
    ----------
    sample_weight : {None, ndarray}
        If sample_weight is None, the hessian might be constant.
    n_classes : {None, int}
        The number of classes for classification, else None.

    Attributes
    ----------
    closs: CyLossFunction
    link : BaseLink
    interval_y_true : Interval
        Valid interval for y_true
    interval_y_pred : Interval
        Valid Interval for y_pred
    differentiable : bool
        Indicates whether or not loss function is differentiable in
        raw_prediction everywhere.
    need_update_leaves_values : bool
        Indicates whether decision trees in gradient boosting need to uptade
        leave values after having been fit to the (negative) gradients.
    approx_hessian : bool
        Indicates whether the hessian is approximated or exact. If,
        approximated, it should be larger or equal to the exact one.
    constant_hessian : bool
        Indicates whether the hessian is one for this loss.
    is_multiclass : bool
        Indicates whether n_classes > 2 is allowed.
    FTNc                 C   sB   || _ || _d| _d| _|| _ttj tjddƒ| _| jj	| _	d S )NF)
ÚclossÚlinkÚapprox_hessianÚconstant_hessianÚ	n_classesr   ÚnpÚinfÚinterval_y_trueÚinterval_y_pred)Úselfr   r   r   © r$   úQ/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sklearn/_loss/loss.pyÚ__init__�   s    zBaseLoss.__init__c                 C   s   | j  |¡S ©zuReturn True if y is in the valid range of y_true.

        Parameters
        ----------
        y : ndarray
        )r!   Úincludes©r#   Úyr$   r$   r%   Úin_y_true_rangeŠ   s    zBaseLoss.in_y_true_rangec                 C   s   | j  |¡S )zuReturn True if y is in the valid range of y_pred.

        Parameters
        ----------
        y : ndarray
        )r"   r(   r)   r$   r$   r%   Úin_y_pred_range“   s    zBaseLoss.in_y_pred_ranger   c                 C   sJ   |dkrt  |¡}|jdkr4|jd dkr4| d¡}| jj|||||d�S )aJ  Compute the pointwise loss value for each input.

        Parameters
        ----------
        y_true : C-contiguous array of shape (n_samples,)
            Observed, true target values.
        raw_prediction : C-contiguous array of shape (n_samples,) or array of             shape (n_samples, n_classes)
            Raw prediction values (in link space).
        sample_weight : None or C-contiguous array of shape (n_samples,)
            Sample weights.
        loss_out : None or C-contiguous array of shape (n_samples,)
            A location into which the result is stored. If None, a new array
            might be created.
        n_threads : int, default=1
            Might use openmp thread parallelism.

        Returns
        -------
        loss : array of shape (n_samples,)
            Element-wise loss function.
        Nr   r   ©Úy_trueÚraw_predictionÚsample_weightÚloss_outÚ	n_threads)r   Ú
empty_likeÚndimÚshapeÚsqueezer   Úloss)r#   r.   r/   r0   r1   r2   r$   r$   r%   r7   œ   s    

ûzBaseLoss.lossc                 C   s¬   |dkr8|dkr&t  |¡}t  |¡}qPt j||jd�}n|dkrPt j||jd�}|jdkrr|jd dkrr| d¡}|jdkr”|jd dkr”| d¡}| jj||||||d�S )a¯  Compute loss and gradient w.r.t. raw_prediction for each input.

        Parameters
        ----------
        y_true : C-contiguous array of shape (n_samples,)
            Observed, true target values.
        raw_prediction : C-contiguous array of shape (n_samples,) or array of             shape (n_samples, n_classes)
            Raw prediction values (in link space).
        sample_weight : None or C-contiguous array of shape (n_samples,)
            Sample weights.
        loss_out : None or C-contiguous array of shape (n_samples,)
            A location into which the loss is stored. If None, a new array
            might be created.
        gradient_out : None or C-contiguous array of shape (n_samples,) or array             of shape (n_samples, n_classes)
            A location into which the gradient is stored. If None, a new array
            might be created.
        n_threads : int, default=1
            Might use openmp thread parallelism.

        Returns
        -------
        loss : array of shape (n_samples,)
            Element-wise loss function.

        gradient : array of shape (n_samples,) or (n_samples, n_classes)
            Element-wise gradients.
        N©Údtyper   r   )r.   r/   r0   r1   Úgradient_outr2   )r   r3   r9   r4   r5   r6   r   Úloss_gradient)r#   r.   r/   r0   r1   r:   r2   r$   r$   r%   r;   È   s&    &


úzBaseLoss.loss_gradientc                 C   sl   |dkrt  |¡}|jdkr4|jd dkr4| d¡}|jdkrV|jd dkrV| d¡}| jj|||||d�S )aª  Compute gradient of loss w.r.t raw_prediction for each input.

        Parameters
        ----------
        y_true : C-contiguous array of shape (n_samples,)
            Observed, true target values.
        raw_prediction : C-contiguous array of shape (n_samples,) or array of             shape (n_samples, n_classes)
            Raw prediction values (in link space).
        sample_weight : None or C-contiguous array of shape (n_samples,)
            Sample weights.
        gradient_out : None or C-contiguous array of shape (n_samples,) or array             of shape (n_samples, n_classes)
            A location into which the result is stored. If None, a new array
            might be created.
        n_threads : int, default=1
            Might use openmp thread parallelism.

        Returns
        -------
        gradient : array of shape (n_samples,) or (n_samples, n_classes)
            Element-wise gradients.
        Nr   r   )r.   r/   r0   r:   r2   )r   r3   r4   r5   r6   r   Úgradient)r#   r.   r/   r0   r:   r2   r$   r$   r%   r<     s    


ûzBaseLoss.gradientc                 C   sÂ   |dkr2|dkr&t  |¡}t  |¡}qDt  |¡}n|dkrDt  |¡}|jdkrf|jd dkrf| d¡}|jdkrˆ|jd dkrˆ| d¡}|jdkrª|jd dkrª| d¡}| jj||||||d�S )aÿ  Compute gradient and hessian of loss w.r.t raw_prediction.

        Parameters
        ----------
        y_true : C-contiguous array of shape (n_samples,)
            Observed, true target values.
        raw_prediction : C-contiguous array of shape (n_samples,) or array of             shape (n_samples, n_classes)
            Raw prediction values (in link space).
        sample_weight : None or C-contiguous array of shape (n_samples,)
            Sample weights.
        gradient_out : None or C-contiguous array of shape (n_samples,) or array             of shape (n_samples, n_classes)
            A location into which the gradient is stored. If None, a new array
            might be created.
        hessian_out : None or C-contiguous array of shape (n_samples,) or array             of shape (n_samples, n_classes)
            A location into which the hessian is stored. If None, a new array
            might be created.
        n_threads : int, default=1
            Might use openmp thread parallelism.

        Returns
        -------
        gradient : arrays of shape (n_samples,) or (n_samples, n_classes)
            Element-wise gradients.

        hessian : arrays of shape (n_samples,) or (n_samples, n_classes)
            Element-wise hessians.
        Nr   r   )r.   r/   r0   r:   Úhessian_outr2   )r   r3   r4   r5   r6   r   Úgradient_hessian)r#   r.   r/   r0   r:   r=   r2   r$   r$   r%   r>   6  s*    '




úzBaseLoss.gradient_hessianc                 C   s   t j| j||dd|d�|d�S )a{  Compute the weighted average loss.

        Parameters
        ----------
        y_true : C-contiguous array of shape (n_samples,)
            Observed, true target values.
        raw_prediction : C-contiguous array of shape (n_samples,) or array of             shape (n_samples, n_classes)
            Raw prediction values (in link space).
        sample_weight : None or C-contiguous array of shape (n_samples,)
            Sample weights.
        n_threads : int, default=1
            Might use openmp thread parallelism.

        Returns
        -------
        loss : float
            Mean or averaged loss function.
        Nr-   ©Úweights)r   Úaverager7   )r#   r.   r/   r0   r2   r$   r$   r%   Ú__call__w  s    ûøzBaseLoss.__call__c                 C   s¾   t j||dd�}dt  |j¡j }| jjt j kr8d}n| jjrJ| jj}n| jj| }| jj	t jkrjd}n| jj
r|| jj	}n| jj	| }|dkr¤|dkr¤| j |¡S | j t  |||¡¡S dS )a#  Compute raw_prediction of an intercept-only model.

        This can be used as initial estimates of predictions, i.e. before the
        first iteration in fit.

        Parameters
        ----------
        y_true : array-like of shape (n_samples,)
            Observed, true target values.
        sample_weight : None or array of shape (n_samples,)
            Sample weights.

        Returns
        -------
        raw_prediction : numpy scalar or array of shape (n_classes,)
            Raw predictions of an intercept-only model.
        r   ©r@   Úaxisé
   N)r   rA   Úfinfor9   Úepsr"   Úlowr    Zlow_inclusiveÚhighZhigh_inclusiver   Úclip)r#   r.   r0   Zy_predrG   Za_minZa_maxr$   r$   r%   Úfit_intercept_only–  s    

zBaseLoss.fit_intercept_onlyc                 C   s
   t  |¡S )zpCalculate term dropped in loss.

        With this term added, the loss of perfect predictions is zero.
        )r   Z
zeros_like©r#   r.   r0   r$   r$   r%   Úconstant_to_optimal_zeroÀ  s    z!BaseLoss.constant_to_optimal_zeroÚFc                 C   sv   |t jt jfkr td|› d�ƒ‚| jr2|| jf}n|f}t j|||d�}| jr^t jd|d�}nt j|||d�}||fS )au  Initialize arrays for gradients and hessians.

        Unless hessians are constant, arrays are initialized with undefined values.

        Parameters
        ----------
        n_samples : int
            The number of samples, usually passed to `fit()`.
        dtype : {np.float64, np.float32}, default=np.float64
            The dtype of the arrays gradient and hessian.
        order : {'C', 'F'}, default='F'
            Order of the arrays gradient and hessian. The default 'F' makes the arrays
            contiguous along samples.

        Returns
        -------
        gradient : C-contiguous array of shape (n_samples,) or array of shape             (n_samples, n_classes)
            Empty array (allocated but not initialized) to be used as argument
            gradient_out.
        hessian : C-contiguous array of shape (n_samples,), array of shape
            (n_samples, n_classes) or shape (1,)
            Empty (allocated but not initialized) array to be used as argument
            hessian_out.
            If constant_hessian is True (e.g. `HalfSquaredError`), the array is
            initialized to ``1``.
        zCValid options for 'dtype' are np.float32 and np.float64. Got dtype=z	 instead.)r5   r9   Úorder)r   )r5   r9   )	r   Zfloat32Úfloat64Ú
ValueErrorÚis_multiclassr   Úemptyr   Zones)r#   Z	n_samplesr9   rO   r5   r<   Zhessianr$   r$   r%   Úinit_gradient_and_hessianÇ  s    
ÿz"BaseLoss.init_gradient_and_hessian)N)NNr   )NNNr   )NNr   )NNNr   )Nr   )N)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úneed_update_leaves_valuesÚdifferentiablerR   r&   r+   r,   r7   r;   r<   r>   rB   rK   rM   r   rP   rT   r$   r$   r$   r%   r   B   s:   :
		   ú
0    ù
B   ú
4    ù
A

*
r   c                       s"   e Zd ZdZd‡ fdd„	Z‡  ZS )ÚHalfSquaredErroraÜ  Half squared error with identity link, for regression.

    Domain:
    y_true and y_pred all real numbers

    Link:
    y_pred = raw_prediction

    For a given sample x_i, half squared error is defined as::

        loss(x_i) = 0.5 * (y_true_i - raw_prediction_i)**2

    The factor of 0.5 simplifies the computation of gradients and results in a
    unit hessian (and is consistent with what is done in LightGBM). It is also
    half the Normal distribution deviance.
    Nc                    s"   t ƒ jtƒ tƒ d� |d k| _d S )N©r   r   )Úsuperr&   r   r   r   ©r#   r0   ©Ú	__class__r$   r%   r&     s    zHalfSquaredError.__init__)N©rU   rV   rW   rX   r&   Ú__classcell__r$   r$   r_   r%   r[   ÿ  s   r[   c                       s4   e Zd ZdZdZdZd	‡ fdd„	Zd
dd„Z‡  ZS )ÚAbsoluteErrora  Absolute error with identity link, for regression.

    Domain:
    y_true and y_pred all real numbers

    Link:
    y_pred = raw_prediction

    For a given sample x_i, the absolute error is defined as::

        loss(x_i) = |y_true_i - raw_prediction_i|
    FTNc                    s(   t ƒ jtƒ tƒ d� d| _|d k| _d S )Nr\   T)r]   r&   r   r   r   r   r^   r_   r$   r%   r&   '  s    zAbsoluteError.__init__c                 C   s&   |dkrt j|dd�S t||dƒS dS )ú•Compute raw_prediction of an intercept-only model.

        This is the weighted median of the target, i.e. over the samples
        axis=0.
        Nr   ©rD   é2   )r   Úmedianr   rL   r$   r$   r%   rK   ,  s    z AbsoluteError.fit_intercept_only)N)N©	rU   rV   rW   rX   rZ   rY   r&   rK   rb   r$   r$   r_   r%   rc     s
   rc   c                       s4   e Zd ZdZdZdZd
‡ fdd„	Zddd	„Z‡  ZS )ÚPinballLossa®  Quantile loss aka pinball loss, for regression.

    Domain:
    y_true and y_pred all real numbers
    quantile in (0, 1)

    Link:
    y_pred = raw_prediction

    For a given sample x_i, the pinball loss is defined as::

        loss(x_i) = rho_{quantile}(y_true_i - raw_prediction_i)

        rho_{quantile}(u) = u * (quantile - 1_{u<0})
                          = -u *(1 - quantile)  if u < 0
                             u * quantile       if u >= 0

    Note: 2 * PinballLoss(quantile=0.5) equals AbsoluteError().

    Additional Attributes
    ---------------------
    quantile : float
        The quantile level of the quantile to be estimated. Must be in range (0, 1).
    FTNç      à?c                    sF   t |dtjdddd� tƒ jtt|ƒd�tƒ d� d| _|d k| _	d S )	NÚquantiler   r   Úneither©Ztarget_typeZmin_valZmax_valZinclude_boundaries)rk   r\   T)
r   ÚnumbersÚRealr]   r&   r   Úfloatr   r   r   )r#   r0   rk   r_   r$   r%   r&   U  s    úþzPinballLoss.__init__c                 C   s8   |dkr t j|d| jj dd�S t||d| jj ƒS dS )rd   Néd   r   re   )r   Ú
percentiler   rk   r   rL   r$   r$   r%   rK   e  s      
ÿzPinballLoss.fit_intercept_only)Nrj   )Nrh   r$   r$   r_   r%   ri   8  s
   ri   c                       s4   e Zd ZdZdZdZd‡ fdd„	Zdd	d
„Z‡  ZS )Ú	HuberLossaê  Huber loss, for regression.

    Domain:
    y_true and y_pred all real numbers
    quantile in (0, 1)

    Link:
    y_pred = raw_prediction

    For a given sample x_i, the Huber loss is defined as::

        loss(x_i) = 1/2 * abserr**2            if abserr <= delta
                    delta * (abserr - delta/2) if abserr > delta

        abserr = |y_true_i - raw_prediction_i|
        delta = quantile(abserr, self.quantile)

    Note: HuberLoss(quantile=1) equals HalfSquaredError and HuberLoss(quantile=0)
    equals delta * (AbsoluteError() - delta/2).

    Additional Attributes
    ---------------------
    quantile : float
        The quantile level which defines the breaking point `delta` to distinguish
        between absolute error and squared error. Must be in range (0, 1).

     Reference
    ---------
    .. [1] Friedman, J.H. (2001). :doi:`Greedy function approximation: A gradient
      boosting machine <10.1214/aos/1013203451>`.
      Annals of Statistics, 29, 1189-1232.
    FTNçÍÌÌÌÌÌì?rj   c                    sH   t |dtjdddd� || _tƒ jtt|ƒd�tƒ d� d| _	d	| _
d S )
Nrk   r   r   rl   rm   )Údeltar\   TF)r   rn   ro   rk   r]   r&   r   rp   r   r   r   )r#   r0   rk   ru   r_   r$   r%   r&   ˜  s    úþzHuberLoss.__init__c                 C   s`   |dkrt j|ddd�}nt||dƒ}|| }t  |¡t  | jjt  |¡¡ }|t j||d� S )rd   Nrf   r   re   r?   )	r   rr   r   ÚsignÚminimumr   ru   ÚabsrA   )r#   r.   r0   rg   ÚdiffÚtermr$   r$   r%   rK   ©  s    
 zHuberLoss.fit_intercept_only)Nrt   rj   )Nrh   r$   r$   r_   r%   rs   s  s
   !rs   c                       s,   e Zd ZdZd‡ fdd„	Zddd„Z‡  ZS )	ÚHalfPoissonLossaƒ  Half Poisson deviance loss with log-link, for regression.

    Domain:
    y_true in non-negative real numbers
    y_pred in positive real numbers

    Link:
    y_pred = exp(raw_prediction)

    For a given sample x_i, half the Poisson deviance is defined as::

        loss(x_i) = y_true_i * log(y_true_i/exp(raw_prediction_i))
                    - y_true_i + exp(raw_prediction_i)

    Half the Poisson deviance is actually the negative log-likelihood up to
    constant terms (not involving raw_prediction) and simplifies the
    computation of the gradients.
    We also skip the constant term `y_true_i * log(y_true_i) - y_true_i`.
    Nc                    s*   t ƒ jtƒ tƒ d� tdtjddƒ| _d S )Nr\   r   TF)r]   r&   r   r   r   r   r    r!   r^   r_   r$   r%   r&   Ñ  s    zHalfPoissonLoss.__init__c                 C   s"   t ||ƒ| }|d k	r||9 }|S )Nr   ©r#   r.   r0   rz   r$   r$   r%   rM   Õ  s    z(HalfPoissonLoss.constant_to_optimal_zero)N)N©rU   rV   rW   rX   r&   rM   rb   r$   r$   r_   r%   r{   ¼  s   r{   c                       s,   e Zd ZdZd‡ fdd„	Zddd„Z‡  ZS )	ÚHalfGammaLossaV  Half Gamma deviance loss with log-link, for regression.

    Domain:
    y_true and y_pred in positive real numbers

    Link:
    y_pred = exp(raw_prediction)

    For a given sample x_i, half Gamma deviance loss is defined as::

        loss(x_i) = log(exp(raw_prediction_i)/y_true_i)
                    + y_true/exp(raw_prediction_i) - 1

    Half the Gamma deviance is actually proportional to the negative log-
    likelihood up to constant terms (not involving raw_prediction) and
    simplifies the computation of the gradients.
    We also skip the constant term `-log(y_true_i) - 1`.
    Nc                    s*   t ƒ jtƒ tƒ d� tdtjddƒ| _d S )Nr\   r   F)r]   r&   r   r   r   r   r    r!   r^   r_   r$   r%   r&   ð  s    zHalfGammaLoss.__init__c                 C   s$   t  |¡ d }|d k	r ||9 }|S ©Nr   )r   Úlogr|   r$   r$   r%   rM   ô  s    z&HalfGammaLoss.constant_to_optimal_zero)N)Nr}   r$   r$   r_   r%   r~   Ü  s   r~   c                       s,   e Zd ZdZd‡ fdd„	Zd	dd„Z‡  ZS )
ÚHalfTweedieLossaÿ  Half Tweedie deviance loss with log-link, for regression.

    Domain:
    y_true in real numbers for power <= 0
    y_true in non-negative real numbers for 0 < power < 2
    y_true in positive real numbers for 2 <= power
    y_pred in positive real numbers
    power in real numbers

    Link:
    y_pred = exp(raw_prediction)

    For a given sample x_i, half Tweedie deviance loss with p=power is defined
    as::

        loss(x_i) = max(y_true_i, 0)**(2-p) / (1-p) / (2-p)
                    - y_true_i * exp(raw_prediction_i)**(1-p) / (1-p)
                    + exp(raw_prediction_i)**(2-p) / (2-p)

    Taking the limits for p=0, 1, 2 gives HalfSquaredError with a log link,
    HalfPoissonLoss and HalfGammaLoss.

    We also skip constant terms, but those are different for p=0, 1, 2.
    Therefore, the loss is not continuous in `power`.

    Note furthermore that although no Tweedie distribution exists for
    0 < power < 1, it still gives a strictly consistent scoring function for
    the expectation.
    Nç      ø?c                    sv   t ƒ jtt|ƒd�tƒ d� | jjdkr@ttj	 tj	ddƒ| _
n2| jjdk r`tdtj	ddƒ| _
ntdtj	ddƒ| _
d S ©N)Úpowerr\   r   Fr   T)r]   r&   r   rp   r   r   r„   r   r   r    r!   ©r#   r0   r„   r_   r$   r%   r&     s    þzHalfTweedieLoss.__init__c                 C   sœ   | j jdkrtƒ j||d�S | j jdkr8tƒ j||d�S | j jdkrTtƒ j||d�S | j j}t t |d¡d| ¡d|  d|  }|d k	r”||9 }|S d S )Nr   )r.   r0   r   r   )r   r„   r[   rM   r{   r~   r   Úmaximum)r#   r.   r0   Úprz   r$   r$   r%   rM   &  s(     ÿ ÿ ÿ(z(HalfTweedieLoss.constant_to_optimal_zero)Nr‚   )Nr}   r$   r$   r_   r%   r�   û  s   r�   c                       s"   e Zd ZdZd‡ fdd„	Z‡  ZS )ÚHalfTweedieLossIdentityan  Half Tweedie deviance loss with identity link, for regression.

    Domain:
    y_true in real numbers for power <= 0
    y_true in non-negative real numbers for 0 < power < 2
    y_true in positive real numbers for 2 <= power
    y_pred in positive real numbers for power != 0
    y_pred in real numbers for power = 0
    power in real numbers

    Link:
    y_pred = raw_prediction

    For a given sample x_i, half Tweedie deviance loss with p=power is defined
    as::

        loss(x_i) = max(y_true_i, 0)**(2-p) / (1-p) / (2-p)
                    - y_true_i * raw_prediction_i**(1-p) / (1-p)
                    + raw_prediction_i**(2-p) / (2-p)

    Note that the minimum value of this loss is 0.

    Note furthermore that although no Tweedie distribution exists for
    0 < power < 1, it still gives a strictly consistent scoring function for
    the expectation.
    Nr‚   c                    s¬   t ƒ jtt|ƒd�tƒ d� | jjdkr@ttj	 tj	ddƒ| _
n2| jjdk r`tdtj	ddƒ| _
ntdtj	ddƒ| _
| jjdkr–ttj	 tj	ddƒ| _ntdtj	ddƒ| _d S rƒ   )r]   r&   r   rp   r   r   r„   r   r   r    r!   r"   r…   r_   r$   r%   r&   W  s    þz HalfTweedieLossIdentity.__init__)Nr‚   ra   r$   r$   r_   r%   rˆ   ;  s   rˆ   c                       s4   e Zd ZdZd	‡ fdd„	Zd
dd„Zdd„ Z‡  ZS )ÚHalfBinomialLossaY  Half Binomial deviance loss with logit link, for binary classification.

    This is also know as binary cross entropy, log-loss and logistic loss.

    Domain:
    y_true in [0, 1], i.e. regression on the unit interval
    y_pred in (0, 1), i.e. boundaries excluded

    Link:
    y_pred = expit(raw_prediction)

    For a given sample x_i, half Binomial deviance is defined as the negative
    log-likelihood of the Binomial/Bernoulli distribution and can be expressed
    as::

        loss(x_i) = log(1 + exp(raw_pred_i)) - y_true_i * raw_pred_i

    See The Elements of Statistical Learning, by Hastie, Tibshirani, Friedman,
    section 4.4.1 (about logistic regression).

    Note that the formulation works for classification, y = {0, 1}, as well as
    logistic regression, y = [0, 1].
    If you add `constant_to_optimal_zero` to the loss, you get half the
    Bernoulli/binomial deviance.

    More details: Inserting the predicted probability y_pred = expit(raw_prediction)
    in the loss gives the well known::

        loss(x_i) = - y_true_i * log(y_pred_i) - (1 - y_true_i) * log(1 - y_pred_i)
    Nc                    s*   t ƒ jtƒ tƒ dd� tddddƒ| _d S ©Nr   ©r   r   r   r   r   T)r]   r&   r
   r   r   r!   r^   r_   r$   r%   r&   ‰  s    ýzHalfBinomialLoss.__init__c                 C   s0   t ||ƒt d| d| ƒ }|d k	r,||9 }|S r   r   r|   r$   r$   r%   rM   ‘  s    z)HalfBinomialLoss.constant_to_optimal_zeroc                 C   sx   |j dkr"|jd dkr"| d¡}tj|jd df|jd�}| j |¡|dd…df< d|dd…df  |dd…df< |S ©a=  Predict probabilities.

        Parameters
        ----------
        raw_prediction : array of shape (n_samples,) or (n_samples, 1)
            Raw prediction values (in link space).

        Returns
        -------
        proba : array of shape (n_samples, 2)
            Element-wise class probabilities.
        r   r   r   r8   N©r4   r5   r6   r   rS   r9   r   Úinverse©r#   r/   Zprobar$   r$   r%   Úpredict_proba˜  s    
 zHalfBinomialLoss.predict_proba)N)N©rU   rV   rW   rX   r&   rM   r�   rb   r$   r$   r_   r%   r‰   i  s   
r‰   c                       sJ   e Zd ZdZdZd‡ fdd„	Zdd„ Zdd	d
„Zdd„ Zddd„Z	‡  Z
S )ÚHalfMultinomialLossa”  Categorical cross-entropy loss, for multiclass classification.

    Domain:
    y_true in {0, 1, 2, 3, .., n_classes - 1}
    y_pred has n_classes elements, each element in (0, 1)

    Link:
    y_pred = softmax(raw_prediction)

    Note: We assume y_true to be already label encoded. The inverse link is
    softmax. But the full link function is the symmetric multinomial logit
    function.

    For a given sample x_i, the categorical cross-entropy loss is defined as
    the negative log-likelihood of the multinomial distribution, it
    generalizes the binary cross-entropy to more than 2 classes::

        loss_i = log(sum(exp(raw_pred_{i, k}), k=0..n_classes-1))
                - sum(y_true_{i, k} * raw_pred_{i, k}, k=0..n_classes-1)

    See [1].

    Note that for the hessian, we calculate only the diagonal part in the
    classes: If the full hessian for classes k and l and sample i is H_i_k_l,
    we calculate H_i_k_k, i.e. k=l.

    Reference
    ---------
    .. [1] :arxiv:`Simon, Noah, J. Friedman and T. Hastie.
        "A Blockwise Descent Algorithm for Group-penalized Multiresponse and
        Multinomial Regression".
        <1311.6529>`
    TNé   c                    s<   t ƒ jtƒ tƒ |d� tdtjddƒ| _tddddƒ| _d S )Nr‹   r   TFr   )	r]   r&   r   r   r   r   r    r!   r"   )r#   r0   r   r_   r$   r%   r&   Ó  s    ýzHalfMultinomialLoss.__init__c                 C   s    | j  |¡ot | t¡|k¡S r'   )r!   r(   r   ÚallZastypeÚintr)   r$   r$   r%   r+   Ü  s    z#HalfMultinomialLoss.in_y_true_rangec                 C   s€   t j| j|jd�}t  |j¡j}t| jƒD ]6}t j||k|dd�||< t  || |d| ¡||< q*| j	 	|ddd…f ¡ 
d¡S )z¥Compute raw_prediction of an intercept-only model.

        This is the softmax of the weighted average of the target, i.e. over
        the samples axis=0.
        r8   r   rC   r   Néÿÿÿÿ)r   Zzerosr   r9   rF   rG   ÚrangerA   rJ   r   Zreshape)r#   r.   r0   ÚoutrG   Úkr$   r$   r%   rK   å  s    z&HalfMultinomialLoss.fit_intercept_onlyc                 C   s   | j  |¡S )a=  Predict probabilities.

        Parameters
        ----------
        raw_prediction : array of shape (n_samples, n_classes)
            Raw prediction values (in link space).

        Returns
        -------
        proba : array of shape (n_samples, n_classes)
            Element-wise class probabilities.
        )r   rŽ   )r#   r/   r$   r$   r%   r�   ò  s    z!HalfMultinomialLoss.predict_probar   c                 C   s\   |dkr2|dkr&t  |¡}t  |¡}qDt  |¡}n|dkrDt  |¡}| jj||||||d�S )aK  Compute gradient and class probabilities fow raw_prediction.

        Parameters
        ----------
        y_true : C-contiguous array of shape (n_samples,)
            Observed, true target values.
        raw_prediction : array of shape (n_samples, n_classes)
            Raw prediction values (in link space).
        sample_weight : None or C-contiguous array of shape (n_samples,)
            Sample weights.
        gradient_out : None or array of shape (n_samples, n_classes)
            A location into which the gradient is stored. If None, a new array
            might be created.
        proba_out : None or array of shape (n_samples, n_classes)
            A location into which the class probabilities are stored. If None,
            a new array might be created.
        n_threads : int, default=1
            Might use openmp thread parallelism.

        Returns
        -------
        gradient : array of shape (n_samples, n_classes)
            Element-wise gradients.

        proba : array of shape (n_samples, n_classes)
            Element-wise class probabilities.
        N)r.   r/   r0   r:   Ú	proba_outr2   )r   r3   r   Úgradient_proba)r#   r.   r/   r0   r:   rš   r2   r$   r$   r%   r›     s    $

úz"HalfMultinomialLoss.gradient_proba)Nr“   )N)NNNr   )rU   rV   rW   rX   rR   r&   r+   rK   r�   r›   rb   r$   r$   r_   r%   r’   ®  s   "		
    ùr’   c                       s4   e Zd ZdZd	‡ fdd„	Zd
dd„Zdd„ Z‡  ZS )ÚExponentialLossa"  Exponential loss with (half) logit link, for binary classification.

    This is also know as boosting loss.

    Domain:
    y_true in [0, 1], i.e. regression on the unit interval
    y_pred in (0, 1), i.e. boundaries excluded

    Link:
    y_pred = expit(2 * raw_prediction)

    For a given sample x_i, the exponential loss is defined as::

        loss(x_i) = y_true_i * exp(-raw_pred_i)) + (1 - y_true_i) * exp(raw_pred_i)

    See:
    - J. Friedman, T. Hastie, R. Tibshirani.
      "Additive logistic regression: a statistical view of boosting (With discussion
      and a rejoinder by the authors)." Ann. Statist. 28 (2) 337 - 407, April 2000.
      https://doi.org/10.1214/aos/1016218223
    - A. Buja, W. Stuetzle, Y. Shen. (2005).
      "Loss Functions for Binary Class Probability Estimation and Classification:
      Structure and Applications."

    Note that the formulation works for classification, y = {0, 1}, as well as
    "exponential logistic" regression, y = [0, 1].
    Note that this is a proper scoring rule, but without it's canonical link.

    More details: Inserting the predicted probability
    y_pred = expit(2 * raw_prediction) in the loss gives::

        loss(x_i) = y_true_i * sqrt((1 - y_pred_i) / y_pred_i)
            + (1 - y_true_i) * sqrt(y_pred_i / (1 - y_pred_i))
    Nc                    s*   t ƒ jtƒ tƒ dd� tddddƒ| _d S rŠ   )r]   r&   r	   r   r   r!   r^   r_   r$   r%   r&   \  s    ýzExponentialLoss.__init__c                 C   s*   dt  |d|  ¡ }|d k	r&||9 }|S )Néþÿÿÿr   )r   Úsqrtr|   r$   r$   r%   rM   d  s    z(ExponentialLoss.constant_to_optimal_zeroc                 C   sx   |j dkr"|jd dkr"| d¡}tj|jd df|jd�}| j |¡|dd…df< d|dd…df  |dd…df< |S rŒ   r�   r�   r$   r$   r%   r�   k  s    
 zExponentialLoss.predict_proba)N)Nr‘   r$   r$   r_   r%   rœ   8  s   #
rœ   )
Zsquared_errorZabsolute_errorZpinball_lossZ
huber_lossZpoisson_lossZ
gamma_lossZtweedie_lossZbinomial_lossZmultinomial_lossZexponential_loss)*rX   rn   Únumpyr   Zscipy.specialr   Úutilsr   Zutils.statsr   Z_lossr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r[   rc   ri   rs   r{   r~   r�   rˆ   r‰   r’   rœ   Z_LOSSESr$   r$   r$   r%   Ú<module>   sD   4    @";I @.E Jö