'Deviance function for either Bernoulli or Binomial data.
Parameters
endog : array-like
Endogenous response variable (already transformed to a probability
if appropriate).
mu : array
Fitted mean response variable
iweights : array-like
1d array of weights. The default is 1.
scale : float, optional
An optional scale argument. The default is 1.
Returns
deviance : float
The deviance function as defined below
Notes
Binomial in general:
.. math::
D = 2 * \sum_i iweights * (Y_i * \log(Y_i / \mu_i)
+ (n_i - Y_i) * \log((n_i - Y_i) / (n_i - \mu_i))) / scale
Since :math:`Y_i` and :math:`\mu_i` are transformed to :math:`[0,1]`
in Binomial.initialize, the following version is implemented:
.. math::
D = 2 * \sum_i iweights n_i * (Y_i * \log(Y_i / \mu_i)
+ (1 - Y_i) * \log((1 - Y_i) / (1 - \mu_i))) / scale'

def deviance(self, endog, mu, iweights=1, scale=1.0):

    endog_mu = self._clean((endog / mu))
    n_endog_mu = self._clean(((1.0 - endog) / (1.0 - mu)))
    return ((2 * np.sum(((iweights * self.n) * ((endog * np.log(endog_mu)) + ((1.0 - endog) * np.log(n_endog_mu)))))) / scale)
