matlab重要性采样,Importance Sampling (重要性采样)介绍 | 文艺数学君

摘要这一篇是关于重要性抽样(importance sampling)的介绍, 包括他的背景知识, 相关的数学转换和最后的例子.

简介

重要性抽样(importance sampling)是一种近似的抽样方法, 他通过一些小的数学上的变化, 使得可以对一些不好抽样的分布进行抽样和估计. 这个会在强化学习中的off-policy的方法中用到, 从一个策略进行抽样, 更新另外一个策略(关于强化学习的内容, 之后专门来讲).

在这篇文章中, 我们就着重于importance sampling, 我们将从下面的几个点进行书写:

什么是importance sampling (什么是重要性抽样), 背景知识和数学转换;

importance sampling的例子, 分析方差;

参考资料

Importance Sampling简单介绍

背景介绍

假设现在我们要计算f(x)的期望, 其中x~p(x), 那么E[f(x)]的计算如下所示:

matlab重要性采样,Importance Sampling (重要性采样)介绍 | 文艺数学君_第1张图片

我们可以使用蒙特卡洛采用的方法, 首先从分布p(x)中抽样得到x, 接着将所有的f(x)求平均, 来近似f(x), x~p(x)的期望.

存在的问题与解决方法

上面的采用方法很简单, 但可能存在一个问题, 如果我们无法从分布p(x)中抽样, 或者从中抽样的成本很高, 那么我们还可以求E[f(x)]吗.

答案是可以的, 我们可以从一个简单的分布q(x)中进行抽样得到x, 接着乘上一个系数, 就可以来近似计算f(x), x~p(x)的期望.

我们可以通过下面一个简单的数学式子来是的从分布q(x)中进行抽样的数据来估计f(x), x~p(x)的期望.

matlab重要性采样,Importance Sampling (重要性采样)介绍 | 文艺数学君_第2张图片

上式中最后的连加, 其中, x~q(x), 同时q(x)!=0. 也就是在分布q(x)中进行抽样, 接着乘上p(x)/q(x)来修正从不同分布采用的概率.

这样就完成了从分布q(x)中进行抽样, 来估计E[f(x)],x~p(x).

估计的方差

上面我们讲完了如何从分布q(x)中进行抽样, 来估计E[f(x)],x~p(x). 这里我们来说明一下估计的方差. 因为方差的计算公式是Var(x)=E[x^2]-E[x], 这里的x=f(x)*p(x)/q(x), 所以一旦p(x)/q(x)比较大(也就是两个分布的差异比较大), 那么方差也是会比较大.

当p(x)和q(x)比较接近的时候, 这个时候方差就会比较小. 我们下面来看一个例子.

Importance Sampling的例子

下面就放一些比较重要的部分. 首先我们来定义函数f(x). 定义的函数如下:

# 定义f(x)

def f_x(x):

return 1/(1 + np.exp(-x))

该函数的曲线如下所示:

matlab重要性采样,Importance Sampling (重要性采样)介绍 | 文艺数学君_第3张图片

实验一---当p(x)与q(x)比较接近

首先进行第一个实验, p(x)与q(x)比较接近. 下面我们来定义分布p(x)和q(x). 这两个分布的均值比较接近. 我们从每一个分布中抽样3000个数据.

# p(x)

mu_target = 3.5

sigma_target = 1

p_x = [np.random.normal(mu_target, sigma_target) for _ in range(3000)]

# q(x)

mu_appro = 3

sigma_appro = 1

q_x = [np.random.normal(mu_appro, sigma_appro) for _ in range(3000)]

接着我们绘制出分布图.

fig = plt.figure(figsize=(10,6))

ax = fig.add_subplot(1,1,1)

# 画出两个分布的图像

sns.distplot(p_x, label="distribution $p(x)$")

sns.distplot(q_x, label="distribution $q(x)$")

plt.title("Distributions", size=16)

plt.legend()

最终这两个分布如下所示:

matlab重要性采样,Importance Sampling (重要性采样)介绍 | 文艺数学君_第4张图片

接着我们计算E[f(x)],x~p(x). 首先我们看一下当x~p(x)的结果.

# 当x~p(x)时, E[f(x)]

np.mean([f_x(i) for i in p_x])

最终的的均值为0.9552. 接着来看一下当x~q(x)的情况下的计算, E[f(x)] = mean(p(x)/q(x) * f(x)).

# 当x~q(x), E[f(x)] = mean(p(x)/q(x)*f(x))

p_pdf = stats.norm(mu_target, sigma_target)

q_pdf = stats.norm(mu_appro, sigma_appro)

print(np.mean([p_pdf.pdf(i)/q_pdf.pdf(i) * f_x(i) for i in q_x]), np.var([p_pdf.pdf(i)/q_pdf.pdf(i) * f_x(i) for i in q_x]))

最终的结果为mean, 0.9657; var,0.32068.

实验二---当p(x)与q(x)相差比较远

总体的代码和上面的类似, 这两个分布如下图所示:

matlab重要性采样,Importance Sampling (重要性采样)介绍 | 文艺数学君_第5张图片

因为p(x)没有变, 所以如果计算E[f(x)],x~p(x), 那么均值还是约为0.9552. 接着我们来看x~q(x)的情况, 当p(x)和q(x)相差比较大的时候, 结果会怎么样.

如果采样数量是3000, 最终的结果为, mean, 0.8034; var,29.6346.

如果采样数量是5000, 最终的结果为, mean, 0.76752; var,24.0317.

如果采样数量是10000, 最终的结果为, mean, 0.87405; var,69.76793.

如果采样数量是100000, 最终的结果为, mean, 0.86416 var,79.40022.

可以看到, 当两个分布差的比较多的时候, 我们需要更多的采样, 来获得mean较准确的估计, 但是同时也可以看到估计的方差比较大.

这个方差的来源为p(x)/q(x), 因为两个分布相差比较大, 所以p(x)/q(x)值就会比较大, 最终会导致方差比较大.

你可能感兴趣的:(matlab重要性采样)