我正在研究Richard McElreath的 Statistical Rethinking ,并对他在p.84上使用的某些代码的工作方式感到困惑。该代码使用贝叶斯网格逼近来推导两个模型参数mu
和sigma
,以估计样本中高度的分布。
这是代码
首先,我们列出候选mu
值
mu.list <- seq(from = 140, to = 160, length.out = 200)
然后列出sigma
个候选值
sigma.list <- seq(from = 4, to = 9, length.out = 200) # grid of candidate sigma values
然后,我们使用mu
和sigma
的每种可能组合制作一个数据帧。
post <- expand.grid(mu = mu.list, sigma = sigma.list) # expand grid so every mu is matched with every sigma
这是一个具有40000行的数据集。
nrow(post)
[1] 40000
现在说我们有一个测量高度的样本,其中包含5个测量值。
heights <- c(151.76, 139.70, 136.52, 156.84, 145.41)
对于我不了解的部分,现在有一个合理的复杂sapply
循环,该循环基于mu
和sigma
的40000个候选组合中的每一个计算对数似然五个高度测量值的样本。
postVec <- sapply(1:nrow(post), function (i) sum( dnorm(
heights, # vector of heights
mean = post$mu[i], # candidate mean height value from corresponding position in grid
sd = post$sigma[i], # candidate sigma value from corresponding position in the grid
log = TRUE) ) # make values logs
)
我们从中得到的是一个循环,该循环是一个长度为40000个值的向量,post
数据帧的每一行都有一个值。
length(postVec)
[1] 40000
我不明白的是,如果我们将dnorm()
从循环中取出,并使用均值和sd的单个值,但是在第一个参数中传递相同的高度的5值样本矢量,像这样
dnorm( heights, mean = 140, sd = 4, log = TRUE )
我们得到五个值
[1] -6.627033 -2.308045 -2.683683 -11.167283 -3.219861
所以我的问题是:为什么将sapply循环传递到 postVec
上面的向量会产生40000个值,而不是5 x 40000 = 200000个值? < / p>
为什么dnorm()
函数在sapply()
循环之外返回五个值,但(似乎)在其中只返回一个值?
答案 0 :(得分:2)
您在sum
之前缺少dnorm
:在这40000种情况中,每种情况都将这5个值相加,以计算整个heights
的对数似然性,而不仅仅是单个观察值。
例如,我们只有两个组合而没有sum
,
sapply(1:2, function (i) dnorm(
heights,
mean = post$mu[i],
sd = post$sigma[i],
log = TRUE)
)
# [,1] [,2]
# [1,] -6.627033 -6.553479
# [2,] -2.308045 -2.310245
# [3,] -2.683683 -2.705858
# [4,] -11.167283 -11.061820
# [5,] -3.219861 -3.186194
在使用sum
时,我们得到上述矩阵的列总和:
sapply(1:2, function (i) sum(dnorm(
heights,
mean = post$mu[i],
sd = post$sigma[i],
log = TRUE)
))
# [1] -26.00591 -25.81760