forked from mikedewar/EDHMM
-
Notifications
You must be signed in to change notification settings - Fork 0
/
duration.py
104 lines (88 loc) · 3.03 KB
/
duration.py
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
import numpy as np
import logging
log = logging.getLogger('duration')
class Poisson:
def __init__(self, mu, alpha, beta, support_step=1):
self.alpha = alpha
self.beta = beta
self.mu = mu
self.states = range(len(mu))
self.support_step = support_step
def likelihood(self,state,k):
assert state in self.states
return (k*np.log(self.mu[state])) - sum([np.log(ki+1) for ki in range(k)]) - self.mu[state]
def sample_d(self, state):
return np.random.poisson(self.mu[state])
def sample_mu(self, Zs):
k = dict([(i,[]) for i in self.states])
for Z in Zs:
X = [z[0] for z in Z]
now = X[0]
for s in X:
if now == s:
try:
k[now][-1] += 1
except IndexError:
# initial condition
k[now] = [1]
else:
now = s
k[now].append(1)
for i in self.states:
log.debug("state: %s"%i)
log.debug("observations: %s"%k[i])
out=[]
for i in self.states:
alpha = self.alpha[i] + sum(k[i])
beta = self.beta[i] + len(k[i])
log.debug('drawing mu from a gamma with alpha=%s and beta=%s'%(alpha,beta))
out.append(np.random.gamma(alpha, 1.0/beta))
log.debug('sampled rate parameter for state %s: %s'%(i,out[-1]))
if out[-1] > 1000:
print alpha # 1
print beta # 0.00001
return out
def update(self, Z):
self.mu = self.sample_mu(Z)
def support(self, state, threshold=0.00001):
log.info('finding support for state %s'%state)
# walk left
d, dl = int(self.mu[state]), 1
lold = self.likelihood(state,d)
while dl > threshold:
lnew = np.exp(self.likelihood(state,d))
dl = abs(lnew-lold)
lold = lnew
d -= self.support_step
left = max(1,d)
# walk right
d, dl = int(self.mu[state]), 1
lold = self.likelihood(state,d)
while dl > threshold:
d += self.support_step
lnew = np.exp(self.likelihood(state,d))
dl = abs(lnew-lold)
lold = lnew
right = max(1,d)
log.debug('support for state %s: %s to %s'%(state,int(left),int(right)))
return int(left), int(right)
if __name__ == "__main__":
import pylab as pb
Z = np.load('Z.npy')
D = Poisson(
mu = [1, 1, 1],
alpha=[1, 1, 1],
beta=[0.0001, 0.0001, 0.0001]
)
pb.figure()
for j in range(3):
mus = np.array([D.sample_mu([Z])[j] for i in range(100)])
pb.hist(mus,alpha=0.5)
pb.figure()
for j in range(3):
d = []
for i in range(1000):
D.update([Z])
d.append(D.sample_d(j))
pb.hist(d,alpha=0.5)
pb.show()