1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
import numpy as N
from scipy.sandbox.models.family import links as L
from scipy.sandbox.models.family import varfuncs as V
class Family:
valid = [-N.inf, N.inf]
tol = 1.0e-05
def __init__(self, link, variance):
self.link = link
self.variance = variance
def weights(self, mu):
"""
Weights for IRLS step.
"""
return 1. / (self.link.deriv(mu)**2 * self.variance(mu))
def deviance(self, Y, mu, scale=1.):
return N.power(self.devresid(Y, mu), 2).sum() / scale
def devresid(self, Y, mu):
return (Y - mu) * N.sqrt(self.weights(mu))
def fitted(self, eta):
"""
Fitted values based on linear predictors eta.
"""
return self.link.inverse(eta)
def predict(self, mu):
"""
Linear predictors based on given mu values.
"""
return self.link(mu)
class Poisson(Family):
"""
Poisson exponential family in glm context.
"""
links = [L.log, L.identity, L.sqrt]
variance = V.mu
valid = [0, N.inf]
def __init__(self, link=L.log):
if link not in Poisson.links:
raise ValueError, 'invalid link for Poisson family'
self.variance = Poisson.variance
self.link = link
def devresid(self, Y, mu):
return N.sign(Y - mu) * N.sqrt(2 * Y * N.log(Y / mu) - 2 * (Y - mu))
class Gaussian(Family):
"""
Gaussian exponential family in glm context.
"""
links = [L.log, L.identity, L.inverse]
variance = V.constant
def __init__(self, link=L.identity):
if link not in Gaussian.links:
raise ValueError, 'invalid link for Gaussian family'
self.variance = Gaussian.variance
self.link = link
def devresid(self, Y, mu, scale=1.):
return (Y - mu) / N.sqrt(self.variance(mu) * scale)
class Gamma(Family):
"""
Gaussian exponential family in glm context.
"""
links = [L.log, L.identity, L.inverse]
variance = V.mu_squared
def __init__(self, link=L.identity):
if link not in Gamma.links:
raise ValueError, 'invalid link for Gamma family'
self.variance = Gamma.variance
self.link = link
class Binomial(Family):
"""
Binomial exponential family in glm context.
"""
links = [L.logit, L.probit, L.cauchy, L.log, L.cloglog]
variance = V.binary
def __init__(self, link=L.logit, n=1):
if link not in Binomial.links:
raise ValueError, 'invalid link for Binomial family'
self.n = n
self.variance = V.Binomial(n=self.n)
self.link = link
def devresid(self, Y, mu, scale=1.):
mu = self.link.clean(mu)
return N.sign(Y - mu) * N.sqrt(-2 * (Y * N.log(mu / self.n) + (self.n - Y) * N.log(1 - mu / self.n)))
class InverseGaussian(Family):
"""
Gaussian exponential family in glm context.
"""
links = [L.inverse_squared, L.inverse, L.identity, L.log]
variance = V.mu_cubed
def __init__(self, link=L.identity, n=1):
if link not in InverseGaussian.links:
raise ValueError, 'invalid link for InverseGaussian family'
self.n = n
self.variance = InverseGaussian.variance
self.link = link
|