使用PyMC估计随机变量的参数,该随机变量是均匀随机变量的总和

时间:2014-06-24 06:36:31

标签: statistics pymc

我正在尝试使用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

2 个答案:

答案 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)是一种很有前途的方法,适用于明确计算对数似然性的工作量过多的情况。

这是a notebook collecting this all up

答案 1 :(得分:1)

我将继续并指出一些您可能感兴趣的事情。

模型的参数不是identifiable。您可以使用封闭形式的密度来记下可能性。我使用Mathematica在一分钟内计算它并避免一些繁琐的计算。您可以将下面的结果看作z的函数(Z的实现:= X + Y)。Closed-form density

一旦你有了z的值,这个密度原则上可以在数值上最大化。在实践中,虽然你可以对(b - a)和(d - c)的上界进行简单估计,但没有进一步的结构,你就无法得出任何精确的结论。实际上,注意{a = 2,b = 3,c = -2,d = -1}会导致密度与{a = 0,b = 1,c = 0时的密度相同,d = 1}。如果您有兴趣,请阅读可识别性。

最后,虽然总的来说我会强烈主张采用贝叶斯方法,如果你不熟悉我所指出的问题,你可能会用不准确/不相关的估计来欺骗自己。相比之下,通过ML的频率论方法将会失败并将问题放在你面前。