How to model a mixture of 3 Normals in PyMC? -


there a question on crossvalidated on how use pymc fit 2 normal distributions data. answer of cam.davidson.pilon use bernoulli distribution assign data 1 of 2 normals:

size = 10 p = uniform( "p", 0 , 1) #this fraction come mean1 vs mean2 ber = bernoulli( "ber", p = p, size = size) # produces 1 proportion p. precision = gamma('precision', alpha=0.1, beta=0.1)  mean1 = normal( "mean1", 0, 0.001 ) mean2 = normal( "mean2", 0, 0.001 )  @deterministic def mean( ber = ber, mean1 = mean1, mean2 = mean2):     return ber*mean1 + (1-ber)*mean2 

now question is: how three normals?

basically, issue can't use bernoulli distribution , 1-bernoulli anymore. how then?


edit: cdp's suggestion, wrote following code:

import numpy np import pymc mc  n = 3 ndata = 500  dd = mc.dirichlet('dd', theta=(1,)*n) category = mc.categorical('category', p=dd, size=ndata)  precs = mc.gamma('precs', alpha=0.1, beta=0.1, size=n) means = mc.normal('means', 0, 0.001, size=n)  @mc.deterministic def mean(category=category, means=means):     return means[category]  @mc.deterministic def prec(category=category, precs=precs):     return precs[category]  v = np.random.randint( 0, n, ndata) data = (v==0)*(50+ np.random.randn(ndata)) \        + (v==1)*(-50 + np.random.randn(ndata)) \        + (v==2)*np.random.randn(ndata) obs = mc.normal('obs', mean, prec, value=data, observed = true)  model = mc.model({'dd': dd,               'category': category,               'precs': precs,               'means': means,               'obs': obs}) 

the traces following sampling procedure well. solved!

mcmc = mc.mcmc( model ) mcmc.sample( 50000,0 ) mcmc.trace('means').gettrace()[-1,:] 

there mc.categorical object this.

p =  [0.2, 0.3, .5] t = mc.categorical('test', p ) t.random() #array(2, dtype=int32) 

it returns int between 0 , len(p)-1. model 3 normals, make p mc.dirichlet object (it accepts k length array hyperparameters; setting values in array same setting prior probabilities equal). rest of model identical.

this generalization of model suggested above.


update:

okay, instead of having different means, can collapse them 1:

means = normal( "means", 0, 0.001, size=3 )  ...  @mc.deterministic def mean(categorical=categorical, means = means):    return means[categorical] 

Comments

Popular posts from this blog

c# - How Configure Devart dotConnect for SQLite Code First? -

java - Copying object fields -

c++ - Clear the memory after returning a vector in a function -