我正在将从Stan的书中选定的模型“翻译”到pymc3 (我希望很快将它们发布在Github上)我对“不正确的先验”提出了一个问题。
我知道Stan默认是在参数上使用统一的先验。如果无界,则表示均匀(-inf,+ inf)
我的问题是:有没有在pymc3中指定这样的先验?
以下是一个示例来说明问题以及我到目前为止所尝试的内容。
import numpy as np
import pymc3 as pm
light_speed <- np.array(28, 26, 33, 24, 34, -44, 27, 16, 40, -2, 29, 22, 24, 21, 25,
30, 23, 29, 31, 19, 24, 20, 36, 32, 36, 28, 25, 21, 28, 29,
37, 25, 28, 26, 30, 32, 36, 26, 30, 22, 36, 23, 27, 27, 28,
27, 31, 27, 26, 33, 26, 32, 32, 24, 39, 28, 24, 25, 32, 25,
29, 27, 28, 29, 16, 23)
#the model in pystan as specified in stan arm examples
model_string = '''
data {
int<lower=0> N;
vector[N] y;
}
parameters {
vector[1] beta;
real<lower=0> sigma;
}
model {
y ~ normal(beta[1],sigma);
}
'''
# Stan object
StanDSO = ps.StanModel(model_code = model_string)
# data
data = dict(N = len(light_speed),
y = light_speed
)
#fit and verify model results
fit_model = StanDSO.sampling(data=data, iter = 5000, chains = 2, thin = 1)
print fit_model
model_1= pm.Model()
with model_1:
#priors as specified in stan model
mu = pm.Uniform('mu', lower = -np.inf, upper= np.inf)
sigma = pm.Uniform('sigma', lower = 0, upper= np.inf)
#using vague priors works
#mu = pm.Uniform('mu', lower = light_speed.std()/1000.0, upper= light_speed.std()*1000.0)
#sigma = pm.Uniform('sigma', lower = light_speed.std()/1000.0, upper= light_speed.std()*1000.0)
# define likelihood
y_obs = pm.Normal('Y_obs', mu = mu, sd = sigma, observed = light_speed)
# inference fitting the model
# I have to use slice because the following command
#trace = pm.sample(5000)
# produce the error
# ValueError: Cannot construct a ufunc with more than 32 operands
#(requested number were: inputs = 51 and outputs = 1)valueerror
xstart = pm.find_MAP()
xstep = pm.Slice()
trace = pm.sample(5000, xstep, xstart, random_seed = 123, progressbar= True)
pm.summary(trace)
我查看了glm的源代码,似乎它使用模糊的先验作为默认值 Krutschke和许多BUGS示例也推荐了这种做法,并且它有效(见上文)。 但是,参考手册(第52页)说他们主动阻止用户使用默认的比例先验,因为他们集中了太多合理后验值以外的概率(...)具有扭曲后辈的深远影响。
答案 0 :(得分:2)
在Stan的参数支持下定义了统一先验。因此,如果您声明参数real<lower=0> sigma;
,声明sigma
在正值上具有统一的先验。它通过将sigma
对数转换为(-inf,inf)然后计算雅可比行列来做到这一点;我相信PyMC3可以做同样的事情。如果后路正确,斯坦允许不正确的先验。除了为变量指定的默认统一值之外的任何其他先验都会相乘(在对数刻度上添加),因此它们的行为与预期一致(默认的均匀分布无效)。
话虽如此,我们建议在Stan手册中至少使用信息量较弱的先验,如果不是更强大的先验。查看Gelman在回归部分引用的论文中对先验的讨论,看看先验如何变得偏斜。而且它的前辈不仅太模糊了;通常在封闭区间内的均匀先验(如许多BUGS示例中所示)将对后验产生强烈影响---您可以根据截断似然函数对此进行可视化。所有这些都会导致计算问题,具体取决于模型的后部几何形状(而不仅仅是HMC ---也适用于Gibbs或Metropolis)。
我们在GitHub上的Gelman和Hill回归书籍示例(ARM)不符合Stan当前的建模标准---它们只是直接从ARM代码转换而来。修改所有这些是我们2016年的待办事项清单(以及BUGS示例)。一些ARM示例是从本书中的示例翻译为R lm()
或glm()
函数,另一些是lme4
包lmer()
和glmer()
create_table "friendships", force: :cascade do |t|
t.integer "user_id"
t.integer "friend_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
函数,其中没有一个接受先验。我们即将发布RStanARM软件包,它将接受R的回归(以及lme4的多级回归)符号,并允许MLE(有错误)或HMC估计(具有高度优化的模型代码)后端)。