无法使用重新考虑软件包中的map2stan函数绘制单独的MCMC链

时间:2019-05-08 02:37:03

标签: r stan

我目前正在研究Richard McElreath的绝妙著作。我在第8章上。我有2个麻烦源(下面解释)。请注意,您需要安装stan软件包才能起作用。

首先创建一些数据以进行建模和查看。这个简单的回归具有截距10和斜率2。

df <- data.frame(x = 1:100,
                 noise = rnorm(100, 0, 20))
df$y <- 10 + df$x*2 + df$noise

ggplot(df, aes(x, y)) + geom_point() + geom_smooth(method = "lm")

enter image description here

现在为模型。 map2stan函数是stan的包装器。下面的模型

library(rethinking)
mod <- map2stan(
  alist(
    y ~ dnorm(mu, sigma),
    mu <- a + b*x,
    a ~ dnorm(0, 100),
    b ~ dnorm(0, 10),
    sigma ~ dunif(0,10)
  ), data = df, chains = 2, iter = 4000, warmup = 1000)

检查模型是否返回了正确的参数

precis(mod)

#       Mean StdDev lower 0.89 upper 0.89 n_eff Rhat
# a     7.68   2.00       4.41      10.79  2612    1
# b     1.94   0.03       1.88       1.99  2543    1
# sigma 9.96   0.04       9.90      10.00  3980    1

问题1

如果我跑步,请按照书中的内容

plot(mod)

对于每个变量,我都应该得到一个漂亮的轨迹图,绘制两个链。相反,我得到了错误

Error in as.double(y) : 
  cannot coerce type 'S4' to vector of type 'double'

问题1:我在做什么错?为什么该图不起作用?

问题2

如果我们打印mod对象

mod

它告诉我们

map2stan model fit
6000 samples from 2 chains

我们 可以通过从map2stan模型中提取和绘制样本来解决上述问题(这仅提取了a截距参数。

dfSamp1 <- data.frame(chain1 = extract.samples(mod, n=4e3)$a,
                      row = 1:4e3)

ggplot(dfSamp1, aes(x = row, y = chain1, group = 1)) + geom_line(colour = "skyblue")

enter image description here

但是缺少多个链。从模型中采样两次

dfSamp2 <- data.frame(chain1 = extract.samples(mod, n=4e3)$a,
                      chain2 = extract.samples(mod, n=4e3)$a,
                      row = 1:4e3)

但是两个链中的样本完全相同。

ggplot(dfSamp2) + 
       geom_line(aes(x = row, y = chain1, group = 1), colour = "skyblue") + 
       geom_line(aes(x = row, y = chain2, group = 1), colour = "black")

在该曲线图上应该有两种颜色可见。但是只有1,因为第二条黑色线与第一个(蓝色)线相同。

enter image description here

我们可以验证是否查看数据框

dfSamp2[1:10,]

      chain1    chain2 row
1   5.738354  5.738354   1
2   4.934791  4.934791   2
3   5.701355  5.701355   3
4   9.701134  9.701134   4
5   6.123426  6.123426   5
6  11.769974 11.769974   6
7   7.675946  7.675946   7
8   8.858765  8.858765   8
9   6.279705  6.279705   9
10  5.805226  5.805226  10

完全 相同:不是从两个单独的随机游走中得到的。

问题2:那么,如何从map2stan对象中提取2条链,或者如何使用extract.samples()函数提取不同的链样本估算呢?

0 个答案:

没有答案