PyMC中两个正态分布的拟合模型


10

由于我是一名试图学习更多统计信息的软件工程师,因此我什至在开始之前就必须原谅我,所以这是一个严重的问题。

我一直在学习PyMC,并通过一些(非常)简单的示例进行研究。我无法使用(并且无法找到任何相关示例)的一个问题是将模型拟合到由两个正态分布生成的数据。

假设我有1000个值;从a生成Normal(mean=100, stddev=20)500个,从a生成另一个500个Normal(mean=200, stddev=20)

如果我想对它们拟合模型,即使用PyMC确定两个均值和单个标准差。我知道这有点像...

mean1 = Uniform('mean1', lower=0.0, upper=200.0)
mean2 = Uniform('mean2', lower=0.0, upper=200.0)
precision = Gamma('precision', alpha=0.1, beta=0.1)

data = read_data_from_file_or_whatever()

@deterministic(plot=False)
def mean(m1=mean1, m2=mean2):
    # but what goes here?

process = Normal('process', mu=mean, tau=precision, value=data, observed=True)

也就是说,生成过程是正常的,但是mu是两个值之一。我只是不知道如何表示值来自m1还是之间的“决定” m2

也许我只是完全采用了错误的方法来对此建模?谁能给我指出一个例子?我可以读BUGS和JAGS,所以真的没事。

Answers:


11

您是否绝对确定其中一半来自一个发行版,另一半来自另一个发行版?如果不是,我们可以将比例建模为随机变量(这是非常贝叶斯的事情)。

以下是我会做的事情,其中​​嵌入了一些技巧。

from pymc import *

size = 10
p = Uniform( "p", 0 , 1) #this is the fraction that come from mean1 vs mean2

ber = Bernoulli( "ber", p = p, size = size) # produces 1 with proportion p.

precision = Gamma('precision', alpha=0.1, beta=0.1)

mean1 = Normal( "mean1", 0, 0.001 ) #better to use normals versus Uniforms (unless you are certain the value is  truncated at 0 and 200 
mean2 = Normal( "mean2", 0, 0.001 )

@deterministic
def mean( ber = ber, mean1 = mean1, mean2 = mean2):
    return ber*mean1 + (1-ber)*mean2


#generate some artificial data   
v = np.random.randint( 0, 2, size)
data = v*(10+ np.random.randn(size) ) + (1-v)*(-10 + np.random.randn(size ) )


obs = Normal( "obs", mean, precision, value = data, observed = True)

model = Model( {"p":p, "precision": precision, "mean1": mean1, "mean2":mean2, "obs":obs} )

2
无耻推广:我刚写了一篇贝叶斯和pyMC博客新闻字面上 1分钟你张贴在此之前,所以我请你检查出来。贝叶斯的强大力量-第1部分
Cam.Davidson.Pilon 2012年

太棒了!这种将两种方式混合使用的方法恰好是我试图引起注意的方法。
mat kelcey 2012年

我不确定我是否完全理解说均值1和均值2是正态分布而不是均匀分布的真正建模优势(老实说,精确度是一样的,因为“别人这么做”,所以我一直在使用Gamma)。我有很多东西要学:)
mat kelcey 2012年

如原始示例中那样,使用Uniform意味着您可以绝对确定地知道平均值不超过某个值。这有点病态。最好使用法线,因为这样可以考虑所有实数。
Cam.Davidson.Pilon

1
伽玛的选择有数学上的原因。伽玛是精度的共轭先验,请参见此处的
Cam.Davidson.Pilon 2012年

6

与以上讨论有关的几点:

  1. 除非是(a)您担心共轭,否则您将使用法线,或者(b)有合理的机会将真实值排除在制服的端点之外,是选择弥散法线还是制服是很学术的。有了PyMC,除非您特别想使用Gibbs采样器,否则没有理由担心共轭。

  2. 对于在方差/精度参数之前没有信息的情况,伽马实际上不是一个好选择。您可能最终会获得更多信息。更好的选择是在标准偏差上放一个均匀的先验,然后用平方反比对其进行变换。有关详细信息,请参见Gelman 2006


1
啊,fonnesbeck是pymc的核心开发者之一!您能否向我们展示如何编码第2点的示例?
Cam.Davidson.Pilon

谢谢fonnesbeck,是的,请!到第2点的快速
示例

1
事实上,我猜您是按照... gist.github.com/4404631的意思吗?
mat kelcey 2012年

对,就是这样。您可以更简洁地进行转换:tau = std_dev**-2
fonnesbeck 2013年

在哪里可以找到有关precision和std_dev之间的这种关系来自何处的正确位置?
user979 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.