'Weights for calculating Hessian
Parameters
params : ndarray
parameter at which Hessian is evaluated
scale : None or float
If scale is None, then the default scale will be calculated.
Default scale is defined by `self.scaletype` and set in fit.
If scale is not None, then it is used as a fixed scale.
observed : bool
If True, then the observed Hessian is returned. If false then the
expected information matrix is returned.
Returns
hessian_factor : ndarray, 1d
A 1d weight vector used in the calculation of the Hessian.
The hessian is obtained by `(exog.T * hessian_factor).dot(exog)`'

def hessian_factor(self, params, scale=None, observed=True):

    mu = self.predict(params)
    if (scale is None):
        scale = self.estimate_scale(mu)
    eim_factor = (1 / ((self.family.link.deriv(mu) ** 2) * self.family.variance(mu)))
    eim_factor *= (self.iweights * self.n_trials)
    if (not observed):
        if (not (scale == 1)):
            eim_factor /= scale
        return eim_factor
    score_factor = self.score_factor(params, scale=1.0)
    if ((eim_factor.ndim > 1) or (score_factor.ndim > 1)):
        raise RuntimeError('something    wrong')
    tmp = (self.family.variance(mu) * self.family.link.deriv2(mu))
    tmp += (self.family.variance.deriv(mu) * self.family.link.deriv(mu))
    tmp = ((score_factor * eim_factor) * tmp)
    tmp /= self.iweights
    oim_factor = (eim_factor * (1 + tmp))
    if (tmp.ndim > 1):
        raise RuntimeError('something    wrong')
    if (not (scale == 1)):
        oim_factor /= scale
    return oim_factor
