U
    3d/                     @   s   d Z ddlmZmZ ddlmZ ddlZddlZddl	m
Z
 eddZG dd	 d	e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eeeedZdS )z$
Distribution functions used in GLM
    )ABCMetaabstractmethod)
namedtupleN)xlogyDistributionBoundary)value	inclusivec                   @   sN   e Zd ZdZdd Zedd ZedddZd	d
 ZdddZ	dddZ
dS )ExponentialDispersionModela3  Base class for reproductive Exponential Dispersion Models (EDM).

    The pdf of :math:`Y\sim \mathrm{EDM}(y_\textrm{pred}, \phi)` is given by

    .. math:: p(y| \theta, \phi) = c(y, \phi)
        \exp\left(\frac{\theta y-A(\theta)}{\phi}\right)
        = \tilde{c}(y, \phi)
            \exp\left(-\frac{d(y, y_\textrm{pred})}{2\phi}\right)

    with mean :math:`\mathrm{E}[Y] = A'(\theta) = y_\textrm{pred}`,
    variance :math:`\mathrm{Var}[Y] = \phi \cdot v(y_\textrm{pred})`,
    unit variance :math:`v(y_\textrm{pred})` and
    unit deviance :math:`d(y,y_\textrm{pred})`.

    Methods
    -------
    deviance
    deviance_derivative
    in_y_range
    unit_deviance
    unit_deviance_derivative
    unit_variance

    References
    ----------
    https://en.wikipedia.org/wiki/Exponential_dispersion_model.
    c                 C   s@   t | jtstd| jjr,t|| jjS t|| jjS dS )zReturns ``True`` if y is in the valid range of Y~EDM.

        Parameters
        ----------
        y : array of shape (n_samples,)
            Target values.
        z;_lower_bound attribute must be of type DistributionBoundaryN)	
isinstance_lower_boundr   	TypeErrorr   npZgreater_equalr   Zgreater)selfy r   B/tmp/pip-unpacked-wheel-zrfo1fqw/sklearn/_loss/glm_distribution.py
in_y_range4   s    
z%ExponentialDispersionModel.in_y_rangec                 C   s   dS )a  Compute the unit variance function.

        The unit variance :math:`v(y_\textrm{pred})` determines the variance as
        a function of the mean :math:`y_\textrm{pred}` by
        :math:`\mathrm{Var}[Y_i] = \phi/s_i*v(y_\textrm{pred}_i)`.
        It can also be derived from the unit deviance
        :math:`d(y,y_\textrm{pred})` as

        .. math:: v(y_\textrm{pred}) = \frac{2}{
            \frac{\partial^2 d(y,y_\textrm{pred})}{
            \partialy_\textrm{pred}^2}}\big|_{y=y_\textrm{pred}}

        See also :func:`variance`.

        Parameters
        ----------
        y_pred : array of shape (n_samples,)
            Predicted mean.
        Nr   r   y_predr   r   r   unit_varianceH   s    z(ExponentialDispersionModel.unit_varianceFc                 C   s   dS )  Compute the unit deviance.

        The unit_deviance :math:`d(y,y_\textrm{pred})` can be defined by the
        log-likelihood as
        :math:`d(y,y_\textrm{pred}) = -2\phi\cdot
        \left(loglike(y,y_\textrm{pred},\phi) - loglike(y,y,\phi)\right).`

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

        y_pred : array of shape (n_samples,)
            Predicted mean.

        check_input : bool, default=False
            If True raise an exception on invalid y or y_pred values, otherwise
            they will be propagated as NaN.
        Returns
        -------
        deviance: array of shape (n_samples,)
            Computed deviance
        Nr   )r   r   r   check_inputr   r   r   unit_deviance^   s    z(ExponentialDispersionModel.unit_deviancec                 C   s   d||  |  | S )a  Compute the derivative of the unit deviance w.r.t. y_pred.

        The derivative of the unit deviance is given by
        :math:`\frac{\partial}{\partialy_\textrm{pred}}d(y,y_\textrm{pred})
             = -2\frac{y-y_\textrm{pred}}{v(y_\textrm{pred})}`
        with unit variance :math:`v(y_\textrm{pred})`.

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

        y_pred : array of shape (n_samples,)
            Predicted mean.
        )r   )r   r   r   r   r   r   unit_deviance_derivativex   s    z3ExponentialDispersionModel.unit_deviance_derivative   c                 C   s   t || || S )a  Compute the deviance.

        The deviance is a weighted sum of the per sample unit deviances,
        :math:`D = \sum_i s_i \cdot d(y_i, y_\textrm{pred}_i)`
        with weights :math:`s_i` and unit deviance
        :math:`d(y,y_\textrm{pred})`.
        In terms of the log-likelihood it is :math:`D = -2\phi\cdot
        \left(loglike(y,y_\textrm{pred},\frac{phi}{s})
        - loglike(y,y,\frac{phi}{s})\right)`.

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

        y_pred : array of shape (n_samples,)
            Predicted mean.

        weights : {int, array of shape (n_samples,)}, default=1
            Weights or exposure to which variance is inverse proportional.
        )r   sumr   r   r   r   weightsr   r   r   deviance   s    z#ExponentialDispersionModel.deviancec                 C   s   ||  || S )a  Compute the derivative of the deviance w.r.t. y_pred.

        It gives :math:`\frac{\partial}{\partial y_\textrm{pred}}
        D(y, \y_\textrm{pred}; weights)`.

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

        y_pred : array, shape (n_samples,)
            Predicted mean.

        weights : {int, array of shape (n_samples,)}, default=1
            Weights or exposure to which variance is inverse proportional.
        )r   r   r   r   r   deviance_derivative   s    z.ExponentialDispersionModel.deviance_derivativeN)F)r   )r   )__name__
__module____qualname____doc__r   r   r   r   r   r   r    r   r   r   r   r	      s   

r	   )	metaclassc                   @   sF   e Zd ZdZdddZedd Zejdd Zdd	 ZdddZ	dS )TweedieDistributiona  A class for the Tweedie distribution.

    A Tweedie distribution with mean :math:`y_\textrm{pred}=\mathrm{E}[Y]`
    is uniquely defined by it's mean-variance relationship
    :math:`\mathrm{Var}[Y] \propto y_\textrm{pred}^power`.

    Special cases are:

    ===== ================
    Power Distribution
    ===== ================
    0     Normal
    1     Poisson
    (1,2) Compound Poisson
    2     Gamma
    3     Inverse Gaussian

    Parameters
    ----------
    power : float, default=0
            The variance power of the `unit_variance`
            :math:`v(y_\textrm{pred}) = y_\textrm{pred}^{power}`.
            For ``0<power<1``, no distribution exists.
    r   c                 C   s
   || _ d S Npowerr   r)   r   r   r   __init__   s    zTweedieDistribution.__init__c                 C   s   | j S r'   )_powerr   r   r   r   r)      s    zTweedieDistribution.powerc                 C   s   t |tjstd||dkr6ttj dd| _nfd|  k rJdk rXn n
t	dnDd|  krldk rn ntddd| _n|dkrtddd| _nt	|| _
d S )	Nz*power must be a real number, input was {0}r   F)r   r   z?Tweedie distribution is only defined for power<=0 and power>=1.   T)r
   numbersRealr   formatr   r   ZInfr   
ValueErrorr,   r*   r   r   r   r)      s    c                 C   s   t || jS )zCompute the unit variance of a Tweedie distribution
        v(y_	extrm{pred})=y_	extrm{pred}**power.

        Parameters
        ----------
        y_pred : array of shape (n_samples,)
            Predicted mean.
        )r   r)   r   r   r   r   r      s    	z!TweedieDistribution.unit_varianceFc                 C   s  | j }|rd|}|dk r6|dk rt|d n|dkr@nd|  k rTdk rbn n
tdnpd|  krvdk rn n&|dk  s|dk rt|d n2|dkr|dk s|dk rt|d nt|dk r>dt t|dd| d| d|   |t |d|  d|   t |d| d|    }n|dkrV|| d }n|dk rjtdn|dkrdt||| | |  }n|dkrdt|| ||  d  }nXdt |d| d| d|   |t |d|  d|   t |d| d|    }|S )	r   z>Mean Tweedie deviance error with power={} can only be used on r   zstrictly positive y_pred.r   z;Tweedie deviance is only defined for power<=0 and power>=1.r.   z,non-negative y and strictly positive y_pred.zstrictly positive y and y_pred.)r)   r1   anyr2   r   maximumr   log)r   r   r   r   pmessagedevr   r   r   r      sd    
&



 z!TweedieDistribution.unit_devianceN)r   )F)
r!   r"   r#   r$   r+   propertyr)   setterr   r   r   r   r   r   r&      s   


r&   c                       s    e Zd ZdZ fddZ  ZS )NormalDistributionz1Class for the Normal (aka Gaussian) distribution.c                    s   t  jdd d S )Nr   r(   superr+   r-   	__class__r   r   r+   W  s    zNormalDistribution.__init__r!   r"   r#   r$   r+   __classcell__r   r   r>   r   r;   T  s   r;   c                       s    e Zd ZdZ fddZ  ZS )PoissonDistributionz*Class for the scaled Poisson distribution.c                    s   t  jdd d S )Nr   r(   r<   r-   r>   r   r   r+   ^  s    zPoissonDistribution.__init__r@   r   r   r>   r   rB   [  s   rB   c                       s    e Zd ZdZ fddZ  ZS )GammaDistributionz!Class for the Gamma distribution.c                    s   t  jdd d S )Nr.   r(   r<   r-   r>   r   r   r+   e  s    zGammaDistribution.__init__r@   r   r   r>   r   rC   b  s   rC   c                       s    e Zd ZdZ fddZ  ZS )InverseGaussianDistributionz>Class for the scaled InverseGaussianDistribution distribution.c                    s   t  jdd d S )N   r(   r<   r-   r>   r   r   r+   l  s    z$InverseGaussianDistribution.__init__r@   r   r   r>   r   rD   i  s   rD   )normalZpoissongammazinverse-gaussian)r$   abcr   r   collectionsr   r/   Znumpyr   Zscipy.specialr   r   r	   r&   r;   rB   rC   rD   ZEDM_DISTRIBUTIONSr   r   r   r   <module>   s&   
   