原理:
重要性采样主要用于难以直接采样的数据分布上,采样是指从已知的某个分布采样一些数据进行后续运算,但是数据分布比较复杂不容易进行采样,针对这种问题使用蒙特卡罗法,例如:
复杂的概率密度函数p(x),求解随机变量基于此概率下的某个数学期望,根据蒙特卡罗法转换为
虽然p(x)比较复杂,但是我们可以对上面的公式进行一些变换,使用常见的分布采样,复杂的采样分布为p(x),另一个简单的可采样且定义域与p(x)相同的概率密度函数q(x),因此可以得到:
代码:
#encoding=utf-8 """ created on 2018-08-12 @author wt Description:重要性采样表示从某一个分布获取某些数据,并利用这些数据完成更多的运算 当某一个密度函数很复杂的时候可以采用近似他的分布代替它 """ import numpy as np import math """x服从的分布""" def gaussian(x,u,sigma): return math.exp(-(x-u)**2/(2*sigma*sigma))/math.sqrt(2*math.pi*sigma*sigma) def importance_sampling(sigma,sample_sigma): """作用相当于取f(x)""" origin = [] for i in range(100000): a = np.random.normal(1.0,sigma) origin.append(a) sample = [] for i in range(100000): """计算f(x)的值""" fx = np.random.normal(1.0,sample_sigma) """原始复杂分布为px,现找同分布的q(x)来代替""" qx = gaussian(a,1.0,sample_sigma) px = gaussian(a,1.0,sigma) sample.append(fx*px/qx) origin = np.array(origin) sample = np.array(sample) print(np.mean(origin),np.std(origin)) print(np.mean(sample),np.std(sample)) importance_sampling(1.0,1.0) importance_sampling(1.0,0.5) importance_sampling(1.0,2) xs = np.linspace(-10,10,101) y1 = [gaussian(x,1.0,1.0) for x in xs] y2 = [gaussian(x,1.0,0.5) for x in xs] y3 = [gaussian(x,1.0,2) for x in xs] import matplotlib.pyplot as plt fig = plt.figure(figsize=(8,5)) plt.plot(xs,y1,label='sigma=1.0') plt.plot(xs,y2,label='sigma=0.5',linestyle=':') plt.plot(xs,y3,label='sigma=2.0',linestyle='--') plt.legend() plt.show() 结果: 方差更应该使用1.0和2.0的分布,方差取0.5时出现采样分布不均匀情况,结果略差一些