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