关于正态分布均值的贝叶斯推断的玩具R代码[降雪量数据]

jos*_*ya7 3 statistics plot r normal-distribution bayesian

我有一些降雪观测:

x <- c(98.044, 107.696, 146.050, 102.870, 131.318, 170.434, 84.836, 154.686,
       162.814, 101.854, 103.378, 16.256)
Run Code Online (Sandbox Code Playgroud)

我被告知它遵循正态分布,已知标准偏差为25.4,但未知均值mu.我必须推断mu使用贝叶斯公式.

这是关于之前的信息 mu

mean of snow |  50.8  | 76.2  | 101.6 | 127.0 |  152.4 | 177.8  
---------------------------------------------------------------
probability  |   0.1  | 0.15  | 0.25  |0.25   |  0.15  |  0.1 
---------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

以下是我到目前为止所尝试的内容,但最后一行post无法正常工作.得到的图只是给出一条水平线.

library(LearnBayes)
midpts <- c(seq(50.8, 177.8, 30))
prob <- c(0.1, 0.15, 0.25, 0.25, 0.15, 0.1)
p <- seq(50, 180, length = 40000)
histp <- histprior(p, midpts, prob)
plot(p, histp, type = "l")

# posterior density
post <- round(histp * dnorm(x, 115, 42) / sum(histp * dnorm(x, 115, 42)), 3)
plot(p, post, type = "l")
Run Code Online (Sandbox Code Playgroud)

李哲源*_*李哲源 15

我的第一个建议是,确保你了解这背后的统计数据.当我看到你的时候

post <- round(histp * dnorm(x, 115, 42) / sum(histp * dnorm(x, 115, 42)), 3)
Run Code Online (Sandbox Code Playgroud)

我估计你搞砸了几个概念.这似乎是贝叶斯公式,但你有可能的错误代码.正确的似然函数是

## likelihood function: `L(obs | mu)`
## standard error is known (to make problem easy) at 25.4
Lik <- function (obs, mu) prod(dnorm(obs, mu, 25.4))
Run Code Online (Sandbox Code Playgroud)

注意,mu是未知的,所以它应该是这个函数的变量; 此外,可能性是观察时所有个体概率密度的乘积.现在,我们可以例如评估可能性,在mu = 100通过

Lik(x, 100)
# [1] 6.884842e-30
Run Code Online (Sandbox Code Playgroud)

对于成功的R实现,我们需要一个矢量化的函数版本Lik.也就是说,一个可以在矢量输入上进行评估的函数mu,而不仅仅是标量输入.我将sapply用于矢量化:

vecLik <- function (obs, mu) sapply(mu, Lik, obs = obs)
Run Code Online (Sandbox Code Playgroud)

我们试试吧

vecLik(x, c(80, 90, 100))
# [1] 6.248416e-34 1.662366e-31 6.884842e-30
Run Code Online (Sandbox Code Playgroud)

现在是时候获得先前的分配mu.原则上这是一个连续函数,但看起来我们想要使用histpriorR包来对它进行离散逼近LearnBayes.

## prior distribution for `mu`: `prior(mu)`
midpts <- c(seq(50.8, 177.8, 30))
prob <- c(0.1, 0.15, 0.25, 0.25, 0.15, 0.1)
mu_grid <- seq(50, 180, length = 40000)  ## a grid of `mu` for discretization
library(LearnBayes)
prior_mu_grid <- histprior(mu_grid, midpts, prob)  ## discrete prior density
plot(mu_grid, prior_mu_grid, type = "l")
Run Code Online (Sandbox Code Playgroud)

事先分配

在应用Baye公式之前,我们首先计算出NC分母上的归一化常数.这将是一个不可或缺的一部分Lik(obs | mu) * prior(mu).但是由于我们有离散近似prior(mu),我们使用黎曼和逼近这个积分.

delta <- mu_grid[2] - mu_grid[1]    ## division size
NC <- sum(vecLik(x, mu_grid) * prior_mu_grid * delta)    ## Riemann sum
# [1] 2.573673e-28
Run Code Online (Sandbox Code Playgroud)

很棒,一切准备就绪,我们可以使用贝叶斯公式:

posterior(mu | obs) = Lik(obs | mu) * prior(mu) / NC
Run Code Online (Sandbox Code Playgroud)

同样,prior(mu)离散化posterior(mu)也是离散化的.

post_mu <- vecLik(x, mu_grid) * prior_mu_grid / NC
Run Code Online (Sandbox Code Playgroud)

哈哈,让我们草拟后面的内容mu,看看推断结果:

plot(mu_grid, post_mu, type = "l")
Run Code Online (Sandbox Code Playgroud)

后密度

哇,这太美了!