这可能是一个愚蠢的问题。
我正在尝试使用PyMC中的MCMC评估将数据拟合到一个非常奇怪的PDF中。对于这个例子,我只想弄清楚如何适应正常分布,我手动输入普通PDF。我的代码是:
data = [];
for count in range(1000): data.append(random.gauss(-200,15));
mean = mc.Uniform('mean', lower=min(data), upper=max(data))
std_dev = mc.Uniform('std_dev', lower=0, upper=50)
# @mc.potential
# def density(x = data, mu = mean, sigma = std_dev):
# return (1./(sigma*np.sqrt(2*np.pi))*np.exp(-((x-mu)**2/(2*sigma**2))))
mc.Normal('process', mu=mean, tau=1./std_dev**2, value=data, observed=True)
model = mc.MCMC([mean,std_dev])
model.sample(iter=5000)
print "!"
print(model.stats()['mean']['mean'])
print(model.stats()['std_dev']['mean'])
我发现的例子都使用了像mc.Normal,或者mc.Poisson或者诸如此类的东西,但是我想要符合注释掉的密度函数。
任何帮助都将不胜感激。
答案 0 :(得分:10)
一种简单的方法是使用随机装饰器:
import pymc as mc
import numpy as np
data = np.random.normal(-200,15,size=1000)
mean = mc.Uniform('mean', lower=min(data), upper=max(data))
std_dev = mc.Uniform('std_dev', lower=0, upper=50)
@mc.stochastic(observed=True)
def custom_stochastic(value=data, mean=mean, std_dev=std_dev):
return np.sum(-np.log(std_dev) - 0.5*np.log(2) -
0.5*np.log(np.pi) -
(value-mean)**2 / (2*(std_dev**2)))
model = mc.MCMC([mean,std_dev,custom_stochastic])
model.sample(iter=5000)
print "!"
print(model.stats()['mean']['mean'])
print(model.stats()['std_dev']['mean'])
请注意,我的custom_stochastic函数返回对数似然,而不是可能性,并且它是整个样本的对数似然。
还有一些其他方法可以创建自定义随机节点。这个doc提供了更多细节,这个gist包含一个使用pymc.Stochastic创建一个带有内核密度估算器的节点的例子。