Metropolis–Hastings算法是一种具体的MCMC方法,而吉布斯采样(Gibbs Sampling)是Metropolis–Hastings算法的一种特殊形式。二者在机器学习中具有重要作用,Bishop在他的机器学习经典之作PRML中也专门用了一章的篇幅来介绍随机采样方法。本文将结合R语言实例来探讨这两种算法的相关话题。本文是这个系列文章的最后一篇,主要介绍MCMC中的Metropolis–Hastings算法和吉布斯采样(Gibbs Sampling)方面的内容。
作为本系列文章的组成部分,也作为你阅读本文所必须的预备知识,希望各位读者确认已经对如下文章所谈之话题了然于心:
欢迎关注白马负金羁的CSDN博客 http://blog.csdn.net/baimafujinji,为保证公式、图表得以正确显示,强烈建议你从该地址上查看原版博文。本博客主要关注方向包括:数字图像处理、算法设计与分析、数据结构、机器学习、数据挖掘、统计分析方法、自然语言处理。
In statistics, the Metropolis–Hastings algorithm is a MCMC method for obtaining a sequence of random samples from a probability distribution for which direct sampling is difficult.
听到Metropolis–Hastings这个名字,有没有点似曾相识,或者在其他地方也听过。如果你做过数学建模,或者学过优化算法方面的内容,那么在研究模拟退火算法时就应该听过Metropolis–Hastings算法这个名字。本质上来说,模拟退火中的Metropolis–Hastings和MCMC中的Metropolis–Hastings确实是一回事。The original algorithm used in simulated annealing and MCMC’s is due to Metropolis. Later generalized by Hastings. Hastings showed that it is not necessary to use a symmetric proposal distribution, and proposed that the proposed new state can be generated from any q(y | x) . Of course, the speed with which we reach the equilibrium distribution will depend on the choice of the proposal function.
Metropolis–Hastings算法的执行步骤如下,注意其中的q就是前面文字描述中的P,即后验概率:
既然已经从理论上证明Metropolis–Hastings算法的确实可行,下面我们举一个简单的例子来看看实际中Metropolis–Hastings算法的效果。稍微有点不一样的地方是,我们这里并未出现 π(x)P(x′ | x) 这样的后验概率形式,作为一个简单的示例,我们只演示从柯西分布中进行采样的做法。
柯西分布也叫作柯西-洛伦兹分布,它是以奥古斯丁·路易·柯西与亨德里克·洛伦兹名字命名的连续概率分布,其概率密度函数为
rm(list=ls()) ## 清除全部对象
set.seed(201912)
reps=40000
# target density: the cauchy distribution
cauchy<-function(x, x0=0, gamma=1){
out<-1/(pi*gamma*(1+((x-x0)/gamma)^2))
return(out)
}
chain<-c(0)
for(i in 1:reps){
proposal<-chain[i]+runif(1, min=-1, max=1)
accept<-runif(1)<cauchy(proposal)/cauchy(chain[i])
chain[i+1]<-ifelse(accept==T, proposal, chain[i])
}
# plot over time
plot(chain, type="l")
plot(density(chain[1000:reps]), xlim=c(-5,5), ylim=c(0,0.4), col="red")
den<-cauchy(seq(from=-5, to=5, by=0.1), x=0, gamma=1)
lines(den~seq(from=-5, to=5, by=0.1), lty=2, col="blue")
下图是每次采样点的数值分布情况。
rm(list=ls()) ## 清除全部对象
f <- function(x, sigma) {
if (any(x < 0)) return (0)
stopifnot(sigma > 0)
return((x / sigma^2) * exp(-x^2 / (2*sigma^2)))
}
m <- 40000
sigma <- 4
x <- numeric(m)
x[1] <- rchisq(1, df=1)
k <- 0
u <- runif(m)
for (i in 2:m) {
xt <- x[i-1]
y <- rchisq(1, df = xt)
num <- f(y, sigma) * dchisq(xt, df = y)
den <- f(xt, sigma) * dchisq(y, df = xt)
if (u[i] <= num/den) x[i] <- y else {
x[i] <- xt
k <- k+1 #y is rejected
}
}
然后我们要验证一下,我的生产的采样数据是否真的符合瑞利分布。注意在R中使用瑞利分布的相关函数,需要加装VGAM包。下面的代码可以让我们直观地感受到采样结果的分布情况。
> curve(drayleigh(x, scale = 4, log = FALSE), from = -1, to = 15, xlim=c(-1,15), ylim=c(0,0.2),
+ lty = 2, col="blue",xlab = "", ylab="")
> par(new=TRUE)
> plot(density(x[1000:m]) , xlim=c(-1,15), ylim=c(0,0.2),col="red")
从下图中不难看出,我们的采样点分布确实符合预期。当然,这仅仅是一个演示用的小例子。显然,它并不高效。Œ因为我们采用自由度为 Xt 的卡方分布来作为proposal function,大约有40%的采样点都被拒绝掉了。如果换做其他更加合适proposal function,可以大大提升采样的效率。
In statistics, Gibbs sampling is a MCMC algorithm for obtaining a sequence of observations which are approximated from a specified multivariate probability distribution, when direct sampling is difficult. 吉布斯采样 can be seen as a special case of the Metropolis-Hastings algorithm. 而这个特殊之处就在于,我们在使用吉布斯采样时,通常是对多变量分布进行采样的。比如说,现在我们有一个分布 p(z1,z2,z3) ,可见它是定义在三个变量上的分布。这种分布很多,比如一维的正态分布也是关于其均值和方差这两个变量的分布。在算法的第 t 步,我们选出了三个值 z(t)1,z(t)2,z(t)3 。这时既然 z(t)2 和 z(t)3 是已知的,那么我们可以由此获得一个新的 z(t+1)1 ,并用这个新的值替代原始的 z(t)1 ,而新的 z(t+1)1 可以由下面这个条件分布来获得
[1] 本文中的英文定义来自于维基百科
[2] http://zhfuzh.blog.163.com/blog/static/1455393872012822854853/
[3] 悉尼科技大学徐亦达博士的机器学习公开课授课材料
[4] 莱斯大学Justin Esarey助理教授(http://jee3.web.rice.edu/index.htm)的公开课资料(https://www.youtube.com/watch?v=j4nEAqUUnVw)
[5] http://staff.ustc.edu.cn/~zwp/teach/Stat-Comp/Lec8.R
[6] Christopher Bishop, Pattern Recognition and Machine Learning, Springer, 2007