Importance Sampling (重要性采样)介绍

王 茂南 2020年6月27日07:21:0628 2539字阅读8分27秒
摘要这一篇是关于重要性抽样(importance sampling)的介绍, 包括他的背景知识, 相关的数学转换和最后的例子.

简介

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

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

  • 什么是importance sampling (什么是重要性抽样), 背景知识和数学转换;
  • importance sampling的例子, 分析方差;

 

参考资料

 

Importance Sampling简单介绍

背景介绍

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

Importance Sampling (重要性采样)介绍

我们可以使用蒙特卡洛采用的方法, 首先从分布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)的期望.

Importance Sampling (重要性采样)介绍

上式中最后的连加, 其中, 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的例子

这一部分所有的代码如链接, 重要性采样试验 (importance sampling).

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

  1. # 定义f(x)
  2. def f_x(x):
  3.     return 1/(1 + np.exp(-x))

该函数的曲线如下所示:

Importance Sampling (重要性采样)介绍

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

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

  1. # p(x)
  2. mu_target = 3.5
  3. sigma_target = 1
  4. p_x = [np.random.normal(mu_target, sigma_target) for _ in range(3000)]
  5. # q(x)
  6. mu_appro = 3
  7. sigma_appro = 1
  8. q_x = [np.random.normal(mu_appro, sigma_appro) for _ in range(3000)]

接着我们绘制出分布图.

  1. fig = plt.figure(figsize=(10,6))
  2. ax = fig.add_subplot(1,1,1)
  3. # 画出两个分布的图像
  4. sns.distplot(p_x, label="distribution $p(x)$")
  5. sns.distplot(q_x, label="distribution $q(x)$")
  6. plt.title("Distributions", size=16)
  7. plt.legend()

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

Importance Sampling (重要性采样)介绍

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

  1. # 当x~p(x)时, E[f(x)]
  2. 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)).

  1. # 当x~q(x), E[f(x)] = mean(p(x)/q(x)*f(x))
  2. p_pdf = stats.norm(mu_target, sigma_target)
  3. q_pdf = stats.norm(mu_appro, sigma_appro)
  4. 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)相差比较远

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

Importance Sampling (重要性采样)介绍

因为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)值就会比较大, 最终会导致方差比较大.

 

  • 微信公众号
  • 关注微信公众号
  • weinxin
  • QQ群
  • 我们的QQ群号
  • weinxin
王 茂南
  • 本文由 发表于 2020年6月27日07:21:06
  • 转载请务必保留本文链接:https://mathpretty.com/12375.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

评论:2   其中:访客  1   博主  1
    • fatalfeel
      fatalfeel

      plt.legend()
      plt.show() 需要加上