我正在尝试使用PyMC来估计模型的参数。但是,我无法理解如何估计模型的参数,这些参数不是标准分布,而是可能是某些其他分布的总和或函数。
实施例: 假设我有一个过程产生的数据“数据”,该过程是2个随机变量X和Y的总和,它们分别从带有参数(a,b)和(c,d)的均匀分布中得出。我想使用PyMC对此进行建模,并估计参数a,b,c和d。我能够设置参数的先验,但不知道如何指定观察到的变量并将其绑定到观察到的数据。
如果观察变量的分布是标准的(比如说O)我会这样做:
obs = pm.DistO(params, observed= True, value=data)
但事实并非如此。我可以在PyMC中对此场景进行建模吗?
我在下面使用的Python代码:
import numpy as np
import pymc as pm
# Generate the synthetic data
a = 2.0
b = 8.0
c = 6.0
d = 10.0
d1 = np.random.uniform(a, b, 100)
d2 = np.random.uniform(c, d, 100)
data = d1 + d2
# Now lets try to recover the parameters.
#Setup the priors
# data is observed. Now lets recover the params
p_a = pm.Normal("pa", 0.0, 10.0)
p_b = pm.Normal("pb", 0.0, 10.0)
p_c = pm.Normal("pc", 0.0, 10.0)
p_d = pm.Normal("pd", 0.0, 10.0)
p_d1 = pm.Uniform("pd1", p_a, p_b)
p_d2 = pm.Uniform("pd2", p_c, p_d)
# Here is where I am confused ?
# p_data = p_d1 + p_d2
# How to now specify that p_data's value is observed (the observations are in "data")
#TODO: Use MCMC to sample and obtain traces
答案 0 :(得分:2)
您可以在PyMC2中对此场景进行建模,从某种意义上讲,它很容易实现。但这也很难做到,所以我将展示一个模型特殊情况的解决方案,其中$ b-a = d-c $。
我说这很容易,因为PyMC2可以使用observed
装饰器将任意函数用作数据对象似然。例如:
@pm.observed
def pdata(value=data, pa=pa, pb=pb, pc=pc, pd=pd):
logpr = 0.
# code to calculate logpr from data and parameters
return logpr
这并不容易,因为你必须提出计算logpr的代码,而且我发现这种情况很复杂且容易出错,例如两件制服的总和。此代码也将位于MCMC的内部循环中,因此效率非常重要。
如果数据来自具有未知支持的单一制服,您可以使用装饰器方法,如下所示:
@pm.observed
def pdata(value=data, pa=pa, pb=pb, pc=pc, pd=pd):
return pm.uniform_like(value, pa, pb)
在模型的特殊情况下,制服具有相同的宽度,数据可能性与三角形分布成比例,并且您只需要适度的疼痛即可将其写出来:
@pm.observed
def pdata(value=data, pa=pa, pb=pb, pc=pc, pd=pd):
pd = pc + (pb - pa) # don't use pd value
# make sure order is acceptible
if pb < pa or pd < pc:
return -np.inf
x = value
pr = \
np.where(x < pa+pc, 0,
np.where(x <= (pa+pb+pc+pd)/2, x - (pa+pc),
np.where(x <= (pb+pd), (pb+pd) - x,
0))) \
/ (.5 * ((pb+pd) - (pa+pc)) * ((pb-pa) + (pd-pc))/2)
return np.sum(np.log(pr))
对于你发布的一般两件制服,分布是梯形的,写出来的工作比我更多。 Approximate Bayesian Computation(ABC)是一种很有前途的方法,适用于明确计算对数似然性的工作量过多的情况。
答案 1 :(得分:1)
我将继续并指出一些您可能感兴趣的事情。
模型的参数不是identifiable。您可以使用封闭形式的密度来记下可能性。我使用Mathematica在一分钟内计算它并避免一些繁琐的计算。您可以将下面的结果看作z的函数(Z的实现:= X + Y)。
一旦你有了z的值,这个密度原则上可以在数值上最大化。在实践中,虽然你可以对(b - a)和(d - c)的上界进行简单估计,但没有进一步的结构,你就无法得出任何精确的结论。实际上,注意{a = 2,b = 3,c = -2,d = -1}会导致密度与{a = 0,b = 1,c = 0时的密度相同,d = 1}。如果您有兴趣,请阅读可识别性。
最后,虽然总的来说我会强烈主张采用贝叶斯方法,如果你不熟悉我所指出的问题,你可能会用不准确/不相关的估计来欺骗自己。相比之下,通过ML的频率论方法将会失败并将问题放在你面前。