5.1.2 采样

什么是采样?

采样(sampling)指的是从一个概率分布中抽取样本的过程

  1. 采出来的样本对应的是概率分布的x轴

  2. 采出来很多样本之后,画histogram的图,应该近似概率分布

采样方法

一般来说,我们在python或matlab等语言中可以很轻松的借助内置函数来从一些常见分布中采样:

from scipy.stats import norm,gamma
a = norm.rvs() # 从高斯分布中采样
print(a)
b = gamma.rvs(1) # 从伽马分布中采样
print(b)

但关键问题是:假如不允许使用这些函数,我们又该如何采样呢?

接下来我们以高斯采样的例子介绍几种常见的采样方法。

问题:只给定均匀分布[0,1][0,1]的样本,如何利用该均匀分布从一个高斯分布中采样?

方法1:逆变化采样(Inverse Transform Sampling)

算法:

  1. 从均匀分布[0,1][0,1]采样得到uu

  2. 从高斯分布的累积分布函数的反函数x=F1(u)x = F^{-1}(u), xx就是需要获得的样本

几乎所有的已知分布都可以用这种方法采样(matlab和python内部就是这么做的)。

方法2:接受-拒绝采样(Accept-Reject Sampling)

采样前的准备:

  1. 先找一个提议分布(proposed distribution)GG,概率密度函数g(x)g(x)已知,可以是任意分布(例如高斯分布)

  2. 再找一个常数CC,使得对于任意的xx,都有Cg(x)p(x)C \cdot g(x) \geq p(x)

算法:

  1. 从提议分布GG中进行采样,获取采样样本xx

  2. [0,1][0, 1]的均匀分布中进行采样一个数值uu

  3. 如果up(x)Cg(x) u \leq \frac{p(x)}{C \cdot g(x)} ,那么我们就接受这个样本xx,保存下来;如果不满足,就拒绝并丢弃这个采样值,重来

以下是代码示例:

首先,设置目标采样分布的概率密度函数:

选定CC值和提议分布函数g(x)g(x),并画出分布。

现在我们来采样:

完成之后画出分布:

以上采样过程还可以写成矩阵形式

方法3:Metropolis-Hasting采样

算法:

  1. 从任意一个x0x_0开始

  2. 根据当前的样本xtx_t构建一个提议分布g(xxt)g(x | x_t) (例如高斯分布),然后采样得到xx^*

  3. 然后计算接受率 α=min[1,p(x)g(xtx)p(xt)g(xxt)]\alpha = \min \left[ 1, \frac{p(x^*) \cdot g(x_t \mid x^*)}{p(x_t) \cdot g(x^* \mid x_t)} \right]

  4. [0,1][0,1]采样一个值uu,

    - 如果 u<αu< \alpha, 接受该样本 xt+1=xx_{t+1} = x^*

    - 否则,继续维持原来的样本 xt+1=xt x_{t+1} = x_t

  5. 重复2-4步直到达到设定的样本总数

MCMC的证明中会详细介绍该算法并解释它为什么成立,在这里,我们先来看看代码如何实现。

首先,设置目标分布的概率密度函数:

最后更新于