如何在PyMC的Metropolis采样器中传入确定性变量?
问题:PyMC中使用Metropolis采样确定性变量报错
我在调试《Probabilistic-Programming-and-Bayesian-Methods-for-Hackers》第2章末尾的代码(验证后验分布模拟数据与原始数据匹配),使用PyMC而非PyMC3,运行代码时出现报错。
原代码
N = 10000 with pm.Model() as model: beta = pm.Normal("beta", mu=0, tau=0.001, testval=0) alpha = pm.Normal("alpha", mu=0, tau=0.001, testval=0) p = pm.Deterministic("p", 1.0/(1. + tt.exp(beta*temperature + alpha))) observed = pm.Bernoulli("bernoulli_obs", p, observed=D) # pytensor.config.compute_test_value = "warn" simulated = pm.Bernoulli("bernoulli_sim", p,shape= p.shape ) step = pm.Metropolis(vars=[p]) trace = pm.sample(N, step=step)
报错信息
ValueError Traceback (most recent call last) Cell In[32], line 10 7 # pytensor.config.compute_test_value = "warn" 9 simulated = pm.Bernoulli("bernoulli_sim", p,shape= p.shape ) ---> 10 step = pm.Metropolis(vars=[p]) 11 trace = pm.sample(N, step=step) File ~\.conda\envs\bayes_course\Lib\site-packages\pymc\step_methods\metropolis.py:168, in Metropolis.__init__(self, vars, S, proposal_dist, scaling, tune, tune_interval, model, mode, **kwargs) 166 vars = model.value_vars 167 else: ---> 168 vars = get_value_vars_from_user_vars(vars, model) 170 initial_values_shape = [initial_values[v.name].shape for v in vars] 171 if S is None: File ~\.conda\envs\bayes_course\Lib\site-packages\pymc\util.py:480, in get_value_vars_from_user_vars(vars, model) 477 notin = list(map(get_var_name, notin)) 478 # We mention random variables, even though the input may be a wrong value variable 479 # because most users don't know about that duality ---> 480 raise ValueError( 481 "The following variables are not random variables in the model: " + str(notin) 482 ) 484 return value_vars ValueError: The following variables are not random variables in the model: ['p']
解决方法
核心原因
p是通过pm.Deterministic定义的确定性变量,它的取值完全由alpha和beta计算而来,本身不是模型中的随机变量。Metropolis采样器只能对模型的随机变量(如alpha、beta)进行采样,无法直接作用于确定性变量。
修改步骤
指定正确的采样变量:将
step = pm.Metropolis(vars=[p])改为采样模型的随机变量alpha和beta:step = pm.Metropolis(vars=[alpha, beta])或者直接省略
vars参数,PyMC会自动识别并采样所有随机变量:step = pm.Metropolis()保留确定性变量的记录:
pm.Deterministic定义的p会自动被记录到采样后的trace中,后续可以通过trace["p"]获取其所有采样值,无需额外操作。可选:使用默认采样器:新版本PyMC推荐使用NUTS采样器(默认),如果你的数据适合(比如连续型参数),可以直接去掉
step参数,让PyMC自动选择最优采样器:trace = pm.sample(N)
修改后的完整代码示例
N = 10000 with pm.Model() as model: beta = pm.Normal("beta", mu=0, tau=0.001, testval=0) alpha = pm.Normal("alpha", mu=0, tau=0.001, testval=0) p = pm.Deterministic("p", 1.0/(1. + tt.exp(beta*temperature + alpha))) observed = pm.Bernoulli("bernoulli_obs", p, observed=D) simulated = pm.Bernoulli("bernoulli_sim", p, shape=p.shape) # 采样随机变量alpha和beta,而非确定性变量p step = pm.Metropolis(vars=[alpha, beta]) trace = pm.sample(N, step=step)
内容的提问来源于stack exchange,提问作者ranbir agarwal
相关产品推荐
相关产品推荐

