如何理解接受拒绝采样(Acceptance-Rejection Sampling)【非原创】

一、简单介绍

接受拒绝采样用于在已知目标分布 f ( x ) f(x) f(x)的情况下,获得服从 f ( x ) f(x) f(x)分布的随机样本。
具体做法如下:

  1. 选择辅助采样分布Y,其概率密度函数 g ( x ) g(x) g(x)
  2. 计算满足概率分布 c ∗ g ( x ) ≥ f ( x ) c*g(x)\geq f(x) cg(x)f(x)的最小值 c c c
  3. 使用辅助采样分布Y生成随机变量 y y y
  4. 使用均匀分布 U ~ U n i f o r m ( 0 , 1 ) U~Uniform(0, 1) UUniform(0,1)生成随机变量 u u u
  5. 如果 u ∗ c ∗ g ( y ) ≥ f ( y ) u*c*g(y) \geq f(y) ucg(y)f(y),则接受样本 y y y,否则拒绝样本 y y y
    通过步骤3-步骤5的流程,有一定概率(接受率)能获得一个随机样本,重复该过程若干次,则可以获得满足分布 f ( x ) f(x) f(x)的随机样本。

二、如何理解该算法?

假设需采样分布的概率密度函数为 f ( x ) = ( x − 0.4 ) 4 ∫ 0 1 ( x − 0.4 ) 4 d x f(x)=\frac{(x-0.4)^4}{\int_{0}^{1} (x-0.4)^4dx} f(x)=01(x0.4)4dx(x0.4)4,使用均匀分布 g ( x ) = 1 g(x)=1 g(x)=1做为辅助采样分布;

  1. 计算 E ( x ) = c ∗ g ( x ) − f ( x ) E(x) = c*g(x)-f(x) E(x)=cg(x)f(x)的极小值点;
  2. x = 1 x=1 x=1时,函数 E ( x ) E(x) E(x)取得极小值,因此 c = f ( 1 ) / g ( 1 ) c=f(1)/g(1) c=f(1)/g(1);
  3. 使用 Y ~ U n i f o r m ( 0 , 1 ) Y~Uniform(0,1) YUniform(0,1)生成随机数 y y y
  4. 使用 U ~ U n i f o r m ( 0 , 1 ) U~Uniform(0,1) UUniform(0,1)生成随机数 u u u
  5. 如果 u ∗ c ∗ g ( y ) ≥ f ( y ) u*c*g(y) \geq f(y) ucg(y)f(y),则接受样本 y y y;

对上述过程的直观理解如下图所示,从几何上来看,我们对函数 c ∗ g ( x ) c*g(x) cg(x)下的区域随机掷点,其中均匀分布 Y Y Y用于表述样本在X轴上的随机性,均匀分布 U U U用于表述样本在Y轴上的随机性;如果点的位置在 f ( x ) f(x) f(x)下,即 u ∗ c ∗ g ( y ) ≥ f ( y ) u*c*g(y) \geq f(y) ucg(y)f(y),则接受样本;
图1

附:代码实现

import seaborn as sns
import random
import math
import matplotlib.pyplot as plt
import numpy as np

sns.set_style('darkgrid')
plt.rcParams['figure.figsize'] = (12, 8)

power = 4
t = 0.4
# 求积分
sum_ = (math.pow(1-t, power+1) - math.pow(-t, power+1)) / (power + 1)
x = np.linspace(0, 1, 101)
# c >= f(x)/g(x) 
f = lambda x: (x-t)**power/sum_
g = lambda x: 1
c = f(1)/g(1)

cc = [c for xi in x]
plt.plot(x, cc, '--', label='c*g(x)')
y = [f(xi) for xi in x]
plt.plot(x, y, label='f(x)')


# 采样10000个点
samples = []
for i in range(2000000):
    # -- 接受拒绝采样方法 --
    Y = random.uniform(0, 1)
    U = random.uniform(0, 1)
    if U*c*g(Y) <= f(Y):
        samples.append(Y)
    # --------------------

plt.hist(samples, bins=100, stacked=True, density=True, label='sampling')
plt.legend()
plt.show() 

注:本文非原创,在Tree苍苍的npy的文章“接受拒绝采样(Acceptance-Rejection Sampling)” 基础上修改得来,侵删。
原文地址:https://zhuanlan.zhihu.com/p/75264565.

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值