将参数传递给确定性变量,pymc

时间:2013-11-05 11:28:07

标签: python pymc

我正在尝试使用PyMC实现一个非常简单的大数定律的例子。目标是生成许多不同大小的样本的样本平均值。例如,在下面的代码中,我重复拍摄5个样本组(samples_to_average = 5),计算它们的平均值,然后找到结果轨迹的95%CI。

下面的代码运行,但我想要做的是将samples_to_average修改为一个列表,以便我可以在一次通过中计算一系列不同样本大小的置信区间。

import scipy.misc
import numpy as np
import pymc as mc

samples_to_average = 5 
list_of_samples = mc.DiscreteUniform("response", lower=1, upper=10, size=1000)

@mc.deterministic
def sample_average(x=list_of_samples, n=samples_to_average):
    samples = int(n)
    selected = x[0:samples] 
    total = np.sum(selected) 
    sample_average = float(total) / samples 
    return sample_average 

def getConfidenceInterval():   
    responseModel = mc.Model([samples_to_average, list_of_samples, sample_average])
    mapRes = mc.MAP(responseModel)
    mapRes.fit() 
    mcmc = mc.MCMC(responseModel)
    mcmc.sample( 10000, 5000)
    upper = np.percentile(mcmc.trace('sample_average')[:],95)
    lower = np.percentile(mcmc.trace('sample_average')[:],5)
    return (lower, upper)     


print getConfidenceInterval()

我见过的大多数使用确定性装饰器的例子都使用全局随机变量。但是,为了实现我的目标,我认为我需要做的是在getConfidenceInterval()中创建一个随机变量(正确长度),并将其传递给sample_average(而不是使用globals / default参数提供sample_average)。

如何将getConfidenceInterval()中创建的变量传递给sample_average(),或者,使用不同的samples_to_average值评估多个模型的另一种方法是什么?如果可能的话,我想避免使用全局变量。

1 个答案:

答案 0 :(得分:2)

在解决你的问题之前,我想简化sample_average的编写方式,使其更紧凑,更易于理解。

sample_average = mc.Lambda('sample_average', lambda x=list_of_samples, n=samples_to_average: np.mean(x[:n]))

现在您可以将其概括为samples_to_average是参数数组的情况:

samples_to_average = np.arange(5, 25, 5)

sample_average = mc.Lambda('sample_average', lambda x=list_of_samples, n=samples_to_average: [np.mean(x[:t]) for t in n])

getConfidenceInterval函数也必须如下所示进行更改:

def getConfidenceInterval():
    responseModel = mc.Model([samples_to_average, list_of_samples, sample_average])
    mapRes = mc.MAP(responseModel)
    mapRes.fit()
    mcmc = mc.MCMC(responseModel)
    mcmc.sample( 10000, 5000)
    average = np.vstack((t for t in mcmc.trace('sample_average')))
    upper = np.percentile(average, 95, axis = 0)
    lower = np.percentile(average, 5, axis = 0)
    return (lower, upper)

我使用vstack将样本平均值聚合为2D数组,然后在Numpy的百分位数函数中使用轴选项来计算每列的百分位数。