Как создать предыдущие переменные из словаря?

У меня есть большое количество приоров, которые можно поместить в словарь. Для простоты, давайте использовать следующий пример, содержащий только 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 ответ

Фактически, 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)
Другие вопросы по тегам