如何从字典中创建先前的变量?

时间:2017-02-13 17:49:54

标签: python-3.5 pymc3

我有很多可以放入字典的先验。为简单起见,让我们使用以下仅包含3个先验的示例:

d = {'a1':{'name':'a1','lower':0,'upper':10},\
'a2':{'name':'a2','lower':0,'upper':10},\
'a3':{'name':'a3','lower':0,'upper':10}}

我可以使用以下方法手动创建这些变量:

import pymc3
model = pymc3.Model()
with model:
    a1 = pymc3.Uniform('a1',lower=0,upper=10)
    a2 = pymc3.Uniform('a2',lower=0,upper=10)
    a3 = pymc3.Uniform('a3',lower=0,upper=10)

但我所拥有的先验数量使这种方法变得痛苦。有没有一种正确的方法来从pymc3中的字典中定义先验?到目前为止,我发现的唯一自动解决方案是:

list_prior_names = ['a1','a2','a3']
for prior_name in list_prior_names:
    exec(prior_name+"=pymc3.Uniform(prior_name,lower=d[prior_name]['lower'],upper=d[prior_name]['upper'])")

还有更好的方法吗?

同样,我有一本字典,给出了这些先验和其他变量之间的关系。为简单起见,让我们使用以下示例来定义先验和这些新变量之间的线性关系:

relations = {'a1':{'b1':2,'b2:4},'a2':{'b1':1},'a3':{'b3':5}}

再次,我可以使用以下代码手动创建b1,b2和b3:

b1 = 2*a1 + a2
b2 = 4*a1
b3 = 5*a3

我可以使用类似于另一个的解决方案,但我认为这里有更好的方法来创建b1,b2,b3。

我目前使用的代码是:

import pymc3
model = pymc3.Model()

obs1,obs2,obs3 = 2,4,5

d = {'a1':{'name':'a1','lower':0,'upper':10},\
'a2':{'name':'a2','lower':0,'upper':10},\
'a3':{'name':'a3','lower':0,'upper':10}}

with model:
    list_prior_names = ['a1','a2','a3']
    for prior_name in list_prior_names:
        exec(prior_name+"=pymc3.Uniform(prior_name,lower=d[prior_name]['lower'],upper=d[prior_name]['upper'])")

    b1 = 2*a1 + a2
    b2 = 4*a1
    b3 = 5*a3

    m1 = pymc3.Normal('M1',mu=b1,sd=0.1,observed=obs1)
    m2 = pymc3.Normal('M2',mu=b2,sd=0.1,observed=obs2)
    m3 = pymc3.Normal('M3',mu=b3,sd=0.1,observed=obs3)

    trace = pymc3.sample(1000)

如果有人知道如何正确创建a1,a2,a3,b1,b2和b3,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

实际上,pymc3可以使用字典中定义的变量进行计算。因此,我编写了以下代码来解决我的问题。我在这里给出,万一有人有一天可以处理同样的问题。

import pymc3
model = pymc3.Model()

obs1,obs2,obs3 = 2,4,5

d = {'a1':{'name':'a1','lower':0,'upper':10},
     'a2':{'name':'a2','lower':0,'upper':10},
     'a3':{'name':'a3','lower':0,'upper':10}}

relations = {'b1':{'a1':2,'a2':1},'b2':{'a1':4},'b3':{'a3':5}}

correspondances_dict = {'b1':{'random_var_name':'m1','observation':obs1},
                        'b2':{'random_var_name':'m2','observation':obs2},
                        'b3':{'random_var_name':'m3','observation':obs3}}

with model:
    priors={prior_name:pymc3.Uniform(prior_name,lower=d[prior_name]['lower'],
            upper=d[prior_name]['upper']) for prior_name in list(d.keys())}

    intermediate_vars = {intermediate_var:sum([relations[intermediate_var][prior_name]*priors[prior_name]
        for prior_name in list(relations[intermediate_var].keys())])
        for intermediate_var in list(relations.keys())}

    observed_vars = {correspondances_dict[intermediate_var]['random_var_name']:
                    pymc3.Normal(correspondances_dict[intermediate_var]['random_var_name'],
                                 mu=intermediate_vars[intermediate_var],
                                 sd=0.1,
                                 observed=correspondances_dict[intermediate_var]['observation'])
                    for intermediate_var in list(intermediate_vars.keys())}

    trace = pymc3.sample(1000)