接受/拒绝采样和重要性采样应用在高维(变量多的)分布上的时候效率比较低。这种情况下可以使用马可夫链蒙特卡洛(Markov Chain Monte Carlo)采样方法,简称 MCMC。
马可夫是?马可夫(Andrey Markov)是俄国的一位数学家。他在二十世纪初研究了一类随机过程(现在叫做马可夫随机过程),这种随机过程的特点是:要预判系统下次的可能状态只需知道当前状态,不需要知道历史状态,或者说知道历史状态并不能对预判提供额外帮助。
比如,整数随机漫步(Random walk)就属于马可夫随机过程。假设开始的时候你处在数轴的原点(0),然后每隔一秒你往左或者右走一步(一个单位),每一步的方向都是随机选择的,各有 50% 的概率。这样经过了一段时间后,假设你处在 +8 的位置上。这个时候我们知道,你下一个可能的位置是 +7 和 +9,各有 50% 的可能性。而知道你之前究竟是经过 +6、+7 到达 +8 还是经过 +10、+9 到达 +8 并不能对下一个位置的判断提供额外帮助。
那相对应的,如果历史状态能够对预判提供帮助就不是马可夫随机过程。比如(参考 wiki),你包里有 5¥、10¥、20¥ 纸币各 4 张,然后每次随机从包里取出一张,取出的现金总额形成一个序列 $X$,$X_0=0$。假如你从中依次取出了全部 4 张 5¥ 和 2 张 20¥ 纸币,现在 $X_6 = 60$。基于这个过程(知道历史状态就能推出过程)你知道 $X_7$ 是一定不会比 70 小的,因为 5¥ 的纸币已经没有了。但是如果你只知道 $X_6=60$,而不清楚之前的过程,那 $X_7$ 小于 70 的可能性还是有的,因为之前的过程可能是 5¥、5¥、10¥,10¥,10¥,20¥(对应状态 5, 10, 20, 30, 40, 60),所以取出 5¥ 的可能性还有。这就是说历史状态对下次可能状态的预判提供了额外的信息。所以这个序列 $X$ 是非马可夫随机过程。
实际的马可夫随机过程例子还包括布朗运动(微小颗粒的无规则运动)等等。由于系统下次状态的判断只跟当前状态有关,用节点表示某一时刻的状态,用连线表示依赖关系,这类系统的状态转换(运动)可以表示下图:
,如链状,所以叫马可夫链。
但是研究这种随机过程有什么用呢?
因为存在随机性,要准确预判系统在某一时刻的状态是不可能的,但是系统未来的状态在统计意义上的特性却可以预判到。事实是,当这类过程满足一些条件的时候,随机过程将达到(收敛到)一个稳定的分布,即每个可能状态出现的概率不再改变。
有了这个性质,我们就可以设计马可夫链,以保证它会收敛到目标分布,然后再模拟(运行)这个随机过程。在模拟的过程中产生的样本自然就符合目标分布。
一般定义这类过程时主要包括(离散情况下),状态空间 $S$,状态转换概率 $p_{ij}$,表示从状态 $i$ 转换到 $j$ 的概率,并且有:
$$ \sum_{j}p_{ij} = 1 $$ ,表示状态 $i$ 转换到所有其他状态的概率之和是 1。
对应到上面的整数随机漫步,$S$ 是所有整数,$p_{ij}$ 是当前位置的左右两个整数概率各位 0.5,其余整数概率为 0。
在设计马可夫链之前需要先知道,符合什么样的条件可以保证这个随机过程会收敛到稳定分布。
稳定分布是指,存在一个向量 $\pi$,其中的元素代表各个状态的概率,且满足:
\begin{align} 0 \leq \pi_{i} \leq 1\\ \sum_{i \in S}\pi_{i} = 1\\ \pi_{i} = \sum_{j \in S}\pi_{j}p_{ji} \end{align} . 其中 $p_{ji}$ 即上面提到的,从状态 $j$ 转换到状态 $i$ 的概率。
上面的条件说明这个随机过程趋于稳定:各个状态出现的概率是确定的,每一次的状态转换并不会改变各个状态总体的概率,即 $\pi$.
那如何设计转换过程($p_{ij}$)才能满足上面的条件呢?一个方法是保证 $\pi_{i}p_{ij}=\pi_{j}p_{ji}$. 因为:
$$ \sum_{j}\pi_{j}p_{ji} = \sum_{j}\pi_{i}p_{ij} = \pi_{i}\sum_{j}p_{ij} = \pi_{i} $$ ,满足上面稳定分布的条件(注意第二步的替换,第三步与 $j$ 无关的 $\pi$ 的提取,第四步用到转换概率的和为 1)。
这个 $\pi_{i}p_{ij}=\pi_{j}p_{ji}$ 的方法叫 detailed balance,它强调了每一对(detailed)状态转换之间的对称性:意思是说系统处于状态 $i$ 并且下次转换到了 $j$ 的概率与系统处于状态 $j$ 并且下次转换到了 $i$ 的概率相等。这是一个比较严格的要求,可以保证收敛到稳定分布,是个充分条件(但不是必要条件),后面的马可夫链的设计也是基于这个条件。
另外一个要提到的问题是,系统可能会有不止一个稳定分布,而我们希望无论系统的初始状态是什么,最后都能收敛到同一个稳定分布。这个要求可以通过附加两个条件来满足,即:(1) 系统的每个状态都可以在有限的时间(步数)内被重新访问到(或者在任意足够大的有限的时间范围内,系统的所有状态都能被访问到);(2) 没有某个状态会以固定的间隔被访问到。简单的理解是说系统内的状态不能存在孤岛和半岛,并且状态转换完全随机。有了这两个条件,系统最终收敛到的唯一的稳定分布叫做均衡分布。
蒙特卡洛(Monte Carlo)是摩纳哥的一个赌场。蒙特卡洛方法是指使用随机模拟的方法解决一些其它方法(比如数学分析)难以解决的问题。这个方法存在很久了,但是这个叫法始于美国曼哈顿计划(原子弹项目),其中他们使用随机模拟的办法研究中子扩散问题(不懂,具体可以参考 wiki)。
而一个直观的例子是,使用随机点数的方法近似求得 $\pi$。
![]()
(图来自 wiki)
上面正方形边长和园的半径是 1,正方形的面积是 1,1/4 圆的面积是 $\frac{\pi}{4}$,面积之比是 $\frac{\pi}{4}$。我们均匀的在正方形中随机撒一些点,然后数一下距离圆心距离小于 1 的点,这个数目和点的总数之比就是 $\frac{\pi}{4}$ 的近似值。所以 $\pi$ 近似等于点数之比乘以 4。可以看到,随机的点数越多,这个近似值越精确。
蒙特卡洛方法的应用还有很多,以后慢慢研究。而这篇介绍的采样方法正是使用随机模拟的方式去逼近目标分布。
上面提到,使用 MCMC 方法对目标分布采样的主要工作是设计一个状态转换过程 $p_{ij}$,使得 detailed balance 条件得到满足:$\pi_{i}p_{ij} = \pi_{j}p_{ji}$,$\pi$ 是目标分布。
Metropolis-Hastings 算法的方案是:使用一个已知的条件分布 $q(x^{*} \mid x)$ 作为提议分布(proposal distribution),然后新样本的接受概率为
$$ A(x^{*}, x^{(t)}) = min(1, \frac{\widetilde{\pi}(x^{*})q(x^{(t)} \mid x^{*})}{\widetilde{\pi}(x^{(t)})q(x^{*} \mid x^{(t)})}) $$ ,其中 $\widetilde{\pi}$ 是概率 $\pi$ 的未归一化(unnormalized)版本:$\pi(x) = \frac{\widetilde{\pi}(x)}{Z_{\pi}}$。
下面看一下,这个方案如何满足 detailed balance 条件:
\begin{align} \pi(x)q(x^{*} \mid x)A(x^{*}, x) & = min(\pi(x)q(x^{*} \mid x), \pi(x^{*})q(x \mid x^{*}))\\ & = min(\pi(x^{*})q(x \mid x^{*}), \pi(x)q(x^{*} \mid x))\\ & = \pi(x^{*})q(x \mid x^{*})A(x, x^{*}) \end{align} (第一步是带入 A,第二步是交换位置,第三步是提取出 A)。
转换概率 $p_{ij}$ 可以认为是:$q(x_j \mid x_i)A(x_j, x_i) = min(q(x_j \mid x_i), q(x_i \mid x_j)\frac{\pi_{j}}{\pi_{i}})$.
下面验证一下从状态 $i$ 转换到所有状态的概率之和是否等于 1:$\sum_{j}q(x_j \mid x_i)A(x_j, x_i) = \sum_{j}min(q(x_j \mid x_i), q(x_i \mid x_j)\frac{\pi_{j}}{\pi_{i}})$。先假设 $q$ 是对称的,即 $q(x^{'} \mid x) = q(x \mid x^{'})$,则上面的等式等于 $\sum_{j}q(x_j \mid x_i)min(1, \frac{\pi_{j}}{\pi_{i}})$。由于 $\sum_{j}q(x_j \mid x_i) = 1$ 而 $min(1, \frac{\pi_{j}}{\pi_{i}}) \leq 1$,所以 $\sum_{j}q(x_j \mid x_i)A(x_j, x_i) \leq 1$,就是说转换到所有状态的概率之和并不一定等于 1。
上面的问题是因为 Meropolis-Hastings 算法中有一步没有提到,即如果新提议的 $x^{*}$ 没有被接受,则前一步的 $x$ 会被拷贝一份保留下来。所以:
\begin{align} p_{ii} & = q(x_i \mid x_i) + \sum_{j \neq i}q(x_j \mid q_i)(1 - min(1, \frac{\pi_{j}}{\pi_{i}})) \\ & = q(x_i \mid x_i) + \sum_{j \neq i}q(x_j \mid q_i)max(0, 1 - \frac{\pi_j}{\pi_i}) \end{align}.
有了上面等式中的弥补项 $\sum_{j \neq i}{\cdots}$,可以保证转换到所有状态的概率之和 $\sum_{j}p_{ij}$ 为 1。
所以这个算法的步骤是:
下面看一下效果。
目标分布是前面 Importance Sampling 中用到的高斯混合分布,提议分布 $q(x^{*} \mid x)$ 是以上个样本为中心、标准方差为 2 的高斯分布。
实际的目标分布:
library(ggplot2)
ptilde = function(x) {
p = 0.3 * dnorm(x, mean=4, sd=1) + 0.7 * dnorm(x, mean=7, sd=0.5)
return(p)
}
x=seq(0,10,length=1000)
df = data.frame(x=x, y=ptilde(x))
ggplot(df, color=variable)+geom_point(aes(x,y, col='p(x)'))
采样过程:
n = 20000
x0 = 2 # last x
xs = c()
mhq = function(x) {
return(rnorm(1, mean=x, sd=2))
}
mhdq = function(x1, x2) {
return(dnorm(x1, mean=x2, sd=2))
}
for (i in seq(0, 1, length=n)) {
q = mhq(x0)
A = min(1, (ptilde(q)*mhdq(x0,q))/(ptilde(x0)*mhdq(q, x0)))
u = runif(1, min=0, max=1)
if (u <= A) {
x0 = q
}
xs = append(xs, x0)
}
采样数据的直方图:
df = data.frame(x=xs)
ggplot(df, color=variable)+geom_histogram(aes(x, col='sample'), binwidth=0.05)
可以看出采样出的样本大致符合目标分布。
由于高斯分布是对称的,所以 $DensityNormal(x^{*}, mean=x) = DensityNormal(x, mean=x^{*})$(标准方差相同),上面采样步骤中的 mhdq 可以省略。
多维度的例子在后面 Gibbs Sampling 方法里一起看。