Skip to content

Instantly share code, notes, and snippets.

@psinger
Created March 18, 2018 14:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save psinger/efafe93b600498579c387663a38020e8 to your computer and use it in GitHub Desktop.
Save psinger/efafe93b600498579c387663a38020e8 to your computer and use it in GitHub Desktop.
from pymc import Normal, Uniform, MvNormal, Exponential
from numpy.linalg import inv, det
from numpy import log, pi, dot
import numpy as np
from scipy.special import gammaln
def _model(data, robust=False):
# priors might be adapted here to be less flat
mu = Normal('mu', 0, 0.000001, size=2)
sigma = Uniform('sigma', 0, 1000, size=2)
rho = Uniform('r', -1, 1)
# we have a further parameter (prior) for the robust case
if robust == True:
nu = Exponential('nu',1/29., 1)
# we model nu as an Exponential plus one
@pymc.deterministic
def nuplus(nu=nu):
return nu + 1
@pymc.deterministic
def precision(sigma=sigma,rho=rho):
ss1 = float(sigma[0] * sigma[0])
ss2 = float(sigma[1] * sigma[1])
rss = float(rho * sigma[0] * sigma[1])
return inv(np.mat([[ss1, rss], [rss, ss2]]))
if robust == True:
# log-likelihood of multivariate t-distribution
@pymc.stochastic(observed=True)
def mult_t(value=data.T, mu=mu, tau=precision, nu=nuplus):
k = float(tau.shape[0])
res = 0
for r in value:
delta = r - mu
enum1 = gammaln((nu+k)/2.) + 0.5 * log(det(tau))
denom = (k/2.)*log(nu*pi) + gammaln(nu/2.)
enum2 = (-(nu+k)/2.) * log (1 + (1/nu)*delta.dot(tau).dot(delta.T))
result = enum1 + enum2 - denom
res += result[0]
return res[0,0]
else:
mult_n = MvNormal('mult_n', mu=mu, tau=precision, value=data.T, observed=True)
return locals()
def analyze(data, robust=False, plot=True):
model = pymc.MCMC(_model(data,robust))
model.sample(50000,25000)
print
if plot:
pymc.Matplot.plot(model)
return model
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment