File: family.py

package info (click to toggle)
python-scipy 0.5.2-0.1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 33,888 kB
  • ctags: 44,231
  • sloc: ansic: 156,256; cpp: 90,347; python: 89,604; fortran: 73,083; sh: 1,318; objc: 424; makefile: 342
file content (130 lines) | stat: -rw-r--r-- 3,272 bytes parent folder | download
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