pymc3中的不正确,扁平的先验

时间:2015-12-30 15:19:44

标签: bayesian pymc3 stan

我正在将从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)

在stan(pystan)

 #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

在pymc3

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页)说他们主动阻止用户使用默认的比例先验,因为他们集中了太多合理后验值以外的概率(...)具有扭曲后辈的深远影响

1 个答案:

答案 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()函数,另一些是lme4lmer()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估计(具有高度优化的模型代码)后端)。