我目前正在研究Richard McElreath的绝妙著作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")
现在为模型。 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
如果我跑步,请按照书中的内容
plot(mod)
对于每个变量,我都应该得到一个漂亮的轨迹图,绘制两个链和。相反,我得到了错误
Error in as.double(y) :
cannot coerce type 'S4' to vector of type 'double'
问题1:我在做什么错?为什么该图不起作用?
如果我们打印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")
但是缺少多个链。从模型中采样两次
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,因为第二条黑色线与第一个(蓝色)线相同。
我们可以验证是否查看数据框
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()
函数提取不同的链样本估算呢?