从2-D之前绘制,仅作为pymc2中的样本

时间:2015-04-24 22:43:29

标签: pymc

我试图玩贝叶斯更新,并且在某种情况下,我使用之前运行的后验作为先验。这是alphabeta上的2D优先,我有跟踪alphatracebetatrace。所以我将它们堆叠起来并使用从https://gist.github.com/jcrudy/5911624采用的代码来创建基于KDE的随机数。

#from https://gist.github.com/jcrudy/5911624
def KernelSmoothing(name, dataset, bw_method=None,  observed=False, value=None):
    '''Create a pymc node whose distribution comes from a kernel smoothing density estimate.'''
    density = gaussian_kde(dataset, bw_method)

    def logp(value):
        #print "VAL", value
        d = density(value)
        if d == 0.0:
            return float('-inf')
        return np.log(d)

    def random():
        result = None
        sample=density.resample(1)
        #print sample, sample.shape
        result = sample[0][0],sample[1][0]
        return result

    if value == None:
        value = random()

    dtype = type(value)

    result = pymc.Stochastic(logp = logp,
                             doc = 'A kernel smoothing density node.',
                             name = name,
                             parents = {},
                             random = random,
                             trace = True,
                             value = None,
                             dtype = dtype,
                             observed = observed,
                             cache_depth = 2,
                             plot = True,
                             verbose = 0)
    return result

请注意,这里的关键是从关节前获得2个值:这就是为什么我需要2-D先验而不是2个1-D先验。

模型本身就是这样:

ctrace=np.vstack((alphatrace, betatrace))
cnew=KernelSmoothing("cnew", ctrace)
@pymc.deterministic
def alphanew(cnew=cnew, name='alphanew'):
    return cnew[0]
@pymc.deterministic
def betanew(cnew=cnew, name='betanew'):
    return cnew[1]
newtheta=pymc.Beta("newtheta", alphanew, betanew)
newexp = pymc.Binomial('newexp', n=[14], p=[newtheta], value=[4], observed=True)
model3=pymc.Model([cnew, alphanew, betanew, newtheta, newexp])
mcmc3=pymc.MCMC(model3)
mcmc3.sample(20000,5000,5)

如果您想知道,这是在Gelman的BDA第5章的分层Rat Tumor例子中进行的第71次实验。 "先前"我使用的是70次实验后的α和β后验。

但是,当我抽样时,事情会因错误而爆炸:

ValueError: Maximum competence reported for stochastic cnew is <= 0... you may need to write a custom step method class.

它不是cnew我关心的是随机更新,而是alphanewbetanew。我应该如何构建代码以使此错误消失?

编辑:初始模型,它给了我希望用作前面的后代:

tumordata="""0 20 
0 20 
0 20 
0 20 
0 20 
0 20 
0 20 
0 19 
0 19 
0 19 
0 19 
0 18 
0 18 
0 17 
1 20 
1 20 
1 20 
1 20 
1 19 
1 19 
1 18 
1 18 
3 27 
2 25 
2 24 
2 23 
2 20 
2 20 
2 20 
2 20 
2 20 
2 20 
1 10 
5 49 
2 19 
5 46 
2 17 
7 49 
7 47 
3 20 
3 20 
2 13 
9 48 
10 50 
4 20 
4 20 
4 20 
4 20 
4 20 
4 20 
4 20 
10 48 
4 19 
4 19 
4 19 
5 22 
11 46 
12 49 
5 20 
5 20 
6 23 
5 19 
6 22 
6 20 
6 20 
6 20 
16 52 
15 46 
15 47 
9 24 
"""
tumortuples=[e.strip().split() for e in tumordata.split("\n")]
tumory=np.array([np.int(e[0].strip()) for e in tumortuples if len(e) > 0])
tumorn=np.array([np.int(e[1].strip()) for e in tumortuples if len(e) > 0])
N = tumorn.shape[0]

mu = pymc.Uniform("mu",0.00001,1., value=0.13)
nu = pymc.Uniform("nu",0.00001,1., value=0.01)

@pymc.deterministic
def alpha(mu=mu, nu=nu, name='alpha'):
    return mu/(nu*nu)

@pymc.deterministic
def beta(mu=mu, nu=nu, name='beta'):
    return (1.-mu)/(nu*nu)


thetas=pymc.Container([pymc.Beta("theta_%i" % i, alpha, beta) for i in range(N)])
deaths = pymc.Binomial('deaths', n=tumorn, p=thetas, value=tumory, size=N, observed=True)

我使用此模型的联合后验对alpha,beta作为&#34;新模型的输入&#34;在顶部。这也引出了一个问题,如果我应该在顶部的模型中包括theta1..theta70,因为它们将与alpha和beta一起更新,这要归功于新数据,即n = 14,y = 4的二项式。但我甚至无法获得只有一个先前作为2d样本数组工作的小模型: - (

1 个答案:

答案 0 :(得分:1)

我发现了你的问题,因为我遇到了类似的问题。根据pymc.StepMethod.competence的文档,问题是没有内置的采样器处理与随机变量相关的dtype。

我不确定要真正解决这个问题需要做些什么。也许可以扩展其中一个采样器方法来处理特殊类型?

希望有更多pymc mojo的人能够了解需要做的事情。

def competence(s):
    """
    This function is used by Sampler to determine which step method class
    should be used to handle stochastic variables.

    Return value should be a competence
    score from 0 to 3, assigned as follows:

    0:  I can't handle that variable.
    1:  I can handle that variable, but I'm a generalist and
        probably shouldn't be your top choice (Metropolis
        and friends fall into this category).
    2:  I'm designed for this type of situation, but I could be
        more specialized.
    3:  I was made for this situation, let me handle the variable.

    In order to be eligible for inclusion in the registry, a sampling
    method's init method must work with just a single argument, a
    Stochastic object.

    If you want to exclude a particular step method from
    consideration for handling a variable, do this:

    Competence functions MUST be called 'competence' and be decorated by the
    '@staticmethod' decorator. Example:

        @staticmethod
        def competence(s):
            if isinstance(s, MyStochasticSubclass):
                return 2
            else:
                return 0

    :SeeAlso: pick_best_methods, assign_method
    """