/
distributions.py
166 lines (135 loc) · 3.68 KB
/
distributions.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
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
"""
Distributions
------------------
Implementation of Mixture Density Networks in Keras.
Summary
-------
Contains all methods associated with the output of the model including sampling
from the model distribution and generating statistics
"""
import numpy as np
import math
from keras import backend as K
import tensorflow as tf
import tensorflow.contrib.distributions as dist
def gamma(x):
return K.exp(tf.lgamma(x))
def tf_normal(y, mu, sigma):
'''
pdf of normal density for _n_ data points and _m_ mixtures.
Parameters
----------
y : array (n,)
data
mu : array (,m)
mean
sigma : array (,m)
variance
Returns
-------
pdf : array (n,m)
probability for each data point and mixture
'''
oneDivSqrtTwoPI = 1 / math.sqrt(2*math.pi)
result = y - mu #broadcasting converts this to two-dimensional array.
#result = K.permute_dimensions(result, [2,1,0])
result = result * (1 / (sigma + 1e-8))
result = -K.square(result)/2
result = K.exp(result) * (1/(sigma + 1e-8))*oneDivSqrtTwoPI
#result = K.prod(result, axis=[0]) #should be (,m) array
return result
def tf_gamma(y,alpha,beta):
'''
pdf of gamma density for _n_ data points and _m_ mixtures.
Parameters
----------
y : array (n,)
data
alpha : array (,m)
gamma shape parameter
beta : array (,m)
gamma shape parameter
Returns
-------
pdf : array (n,m)
probability for each data point and mixture
'''
#Z = gamma(alpha) * K.pow(beta,alpha)
#return K.pow(y,(alpha - 1)) * K.exp(-y * beta) / Z
return dist.Gamma(concentration=alpha, rate=beta).prob(y)
def tf_beta(y,alpha,beta):
'''
pdf of beta distribution for _n_ data points and _m_ mixtures
Parameters
----------
y : array (n,)
data
alpha : array (,m)
beta shape parameter
beta : array (,m)
beta shape parameter
Returns
-------
pdf : array (n,m)
probability for each data point and mixture
'''
#Z = gamma(alpha) * gamma(beta) / gamma(alpha + beta)
#return y**(alpha - 1) * (1 - y)**(beta - 1) / Z
return dist.Beta(alpha,beta).prob(y)
def tf_poisson(y,lbda,_):
'''
pmf of poisson density for _n_ data points and _m_ mixtures.
Parameters
----------
y : array (n,)
data
lbda : array (,m)
Poisson rate parameter
Returns
-------
pdf : array (n,m)
probability for each data point and mixture
Notes
-----
As other distributions take in three parameters we include a redundant third
parameter. This would need refactoring.
'''
#Z = gamma(alpha) * gamma(beta) / gamma(alpha + beta)
#return y**(alpha - 1) * (1 - y)**(beta - 1) / Z
return dist.Poisson(lbda).prob(y)
def tf_binomial(y,n,p):
'''
pdf of binomial distribution for _n_ data points and _m_ mixtures
Parameters
----------
y : array (n,)
data
n : array (,m)
n size parameter
p : array (,m)
p probability parameter
Returns
-------
pdf : array (n,m)
probability for each data point and mixture
'''
#Z = gamma(alpha) * gamma(beta) / gamma(alpha + beta)
#return y**(alpha - 1) * (1 - y)**(beta - 1) / Z
return dist.Binomial(n,p).prob(y)
def gen_tf_binomial(n):
'''
generates function for
pdf of binomial distribution for _n_ data points and _m_ mixtures
Parameters
----------
n : float32
n size parameter
Returns
-------
f : function
Similar form to tf_ functions
'''
# TODO Fix hack
def f(y,p,_):
return dist.Binomial(total_count=n,probs=p).prob(y)
return f