I am trying to model the below State Space Model
Below is the model for it-
with pm.Model() as model:
mu1 = np.zeros(latent_var_size)
sd_dist = pm.Exponential.dist(1.0, shape=latent_var_size)
chol1, corr, stds = pm.LKJCholeskyCov('chol_cov1', n=latent_var_size, eta=2,
sd_dist=sd_dist, compute_corr=True)
A = pm.MvNormal('A', mu=mu1, chol=chol1, shape=(latent_var_size,latent_var_size))
mu2 = np.zeros(num_features)
chol2, corr, stds = pm.LKJCholeskyCov('chol_cov2', n=num_features, eta=2,
sd_dist=sd_dist, compute_corr=True)
#B = tt.as_tensor([tt.inv(tt.mul(Ri,Ci))*dT, tt.mul(Aw,tt.inv(Ci))*dT, tt.inv(Ci) *dT])
B = pm.MvNormal('B', mu=mu2, chol=chol2, shape=(latent_var_size,num_features))
x_init = pm.Normal('x_init', mu = 2, sigma = 2, shape=(num_samples,1,latent_var_size))
Tau = pm.Gamma('tau', alpha=1e-5, beta=1e-5)
X = StateSpaceModel('x', A=A, B=B, u=u, tau = Tau, x0 = x_init, exo = True, shape=(num_samples, N, 2))
C = pm.HalfNormal('C', sigma = 0.2, shape=(latent_var_size,1))
Tau_o = pm.Gamma('tau_o', alpha=1e-5, beta=1e-5)
Y = pm.Poisson('y', mu= (tt.tensordot(pm.math.exp(X),C,axes=1).T), observed=y.T, shape=(num_samples, N))
with model:
inference = pm.ADVI()
tracker = pm.callbacks.Tracker(
mean= inference.approx.mean.eval, # callable that returns mean
std= inference.approx.std.eval # callable that returns std
)
approx = pm.fit(n= 100000, method=inference, callbacks=[tracker])
traceTi = approx.sample(5000)
Below is the state space model class
from pymc3 import Normal, Flat, Continuous
import theano.tensor as T
class StateSpaceModel(Continuous):
def __init__(self, tau=None, sd=None, A=None, B=None, u=None, x0 = None, exo = None, init=Flat.dist(), *args, **kwargs):
super(StateSpaceModel, self).__init__(*args, **kwargs)
self.tau = tau
self.sd = sd
self.A = A
self.B = B
self.u = u
self.init = init
self.mean = x0
self.exo = exo
def logp(self, x):
tau = self.tau
sd = self.sd
A = self.A
B = self.B
u = self.u
init = self.init
# x[0,:] = init
x_im1 = x[:,:-1,:]
x_i = x[:,1:,:]
print(T.tensordot(A,x.T,axes=1))
if self.exo == True:
u_im1 = u[:,:-1,:]
innov_like = Normal.dist(mu=T.tensordot(A,x_im1.T,axes=1)+T.tensordot(B,u_im1.T,axes=1) , tau=tau, sd=sd).logp(x_i.T)
else:
innov_like = Normal.dist(mu=T.tensordot(A,x_im1.T,axes=1), tau=tau, sd=sd).logp(x_i.T)
return T.sum(init.logp(x[:,0,:])) + T.sum(innov_like)
It takes more than one hour to run the above model with number of samples = 500 and time points = 100. I am not sure why it is taking so much time. Even after the model completes learning process, the parameters have very large standard deviation. Any suggestions on what is wrong with the above model?