1.反变换法
设需产生分布函数为F(x)的连续随机数X。若已有[0,1]区间均匀分布随机数R,则产生X的反变换公式为:
F(x)=r, 即x=F-1(r)
反函数存在条件:如果函数y=f(x)是定义域D上的单调函数,那么f(x)一定有反函数存在,且反函数一定是单调的。分布函数F(x)为是一个单调递增函数,所以其反函数存在。从直观意义上理解,因为r一一对应着x,而在[0,1]均匀分布随机数R≤r的概率P(R≤r)=r。 因此,连续随机数X≤x的概率P(X≤x)=P(R≤r)=r=F(x)
即X的分布函数为F(x)。
例子:下面的代码使用反变换法在区间[0, 6]上生成随机数,其概率密度近似为P(x)=e-x
import numpy as np import matplotlib.pyplot as plt # probability distribution we're trying to calculate p = lambda x: np.exp(-x) # CDF of p CDF = lambda x: 1-np.exp(-x) # invert the CDF invCDF = lambda x: -np.log(1-x) # domain limits xmin = 0 # the lower limit of our domain xmax = 6 # the upper limit of our domain # range limits rmin = CDF(xmin) rmax = CDF(xmax) N = 10000 # the total of samples we wish to generate # generate uniform samples in our range then invert the CDF # to get samples of our target distribution R = np.random.uniform(rmin, rmax, N) X = invCDF(R) # get the histogram info hinfo = np.histogram(X,100) # plot the histogram plt.hist(X,bins=100, label=u'Samples'); # plot our (normalized) function xvals=np.linspace(xmin, xmax, 1000) plt.plot(xvals, hinfo[0][0]*p(xvals), 'r', label=u'p(x)') # turn on the legend plt.legend() plt.show()
一般来说,直方图的外廓曲线接近于总体X的概率密度曲线。
2.舍选抽样法(Rejection Methold)
用反变换法生成随机数时,如果求不出F-1(x)的解析形式或者F(x)就没有解析形式,则可以用F-1(x)的近似公式代替。但是由于反函数计算量较大,有时也是很不适宜的。另一种方法是由Von Neumann提出的舍选抽样法。下图中曲线w(x)为概率密度函数,按该密度函数产生随机数的方法如下:
基本的rejection methold步骤如下:
1. Draw x uniformly from [xmin xmax]
2. Draw x uniformly from [0, ymax]
3. if y < w(x),accept the sample, otherwise reject it
4. repeat
即落在曲线w(x)和X轴所围成区域内的点接受,落在该区域外的点舍弃。
例子:下面的代码使用basic rejection sampling methold在区间[0, 10]上生成随机数,其概率密度近似为P(x)=e-x
# -*- coding: utf-8 -*- ''' The following code produces samples that follow the distribution P(x)=e^"text-align: center">3.推广的舍取抽样法
从上图中可以看出,基本的rejection methold法抽样效率很低,因为随机数x和y是在区间[xmin xmax]和区间[0 ymax]上均匀分布的,产生的大部分点不会落在w(x)曲线之下(曲线e-x的形状一边高一边低,其曲线下的面积占矩形面积的比例很小,则舍选抽样效率很低)。为了改进简单舍选抽样法的效率,可以构造一个新的密度函数q(x)(called a proposal distribution from which we can readily draw samples),使它的形状接近p(x),并选择一个常数k使得kq(x)≥w(x)对于x定义域内的值都成立。对应下图,首先从分布q(z)中生成随机数z0,然后按均匀分布从区间[0 kq(z0)]生成一个随机数u0。 if u0 > p(z0) then the sample is rejected,otherwise u0 is retained. 即下图中灰色区域内的点都要舍弃。可见,由于随机点u0只出现在曲线kq(x)之下,且在q(x)较大处出现次数较多,从而大大提高了采样效率。显然q(x)形状越接近p(x),则采样效率越高。
根据上述思想,也可以表达采样规则如下:
1. Draw x from your proposal distribution q(x)
2. Draw y uniformly from [0 1]
3. if y < p(x)/kq(x) , accept the sample, otherwise reject it
4. repeat
下面例子中选择函数p(x)=1/(x+1)作为proposal distribution,k=1。曲线1/(x+1)的形状与e-x相近。
import numpy as np import matplotlib.pyplot as plt p = lambda x: np.exp(-x) # our distribution g = lambda x: 1/(x+1) # our proposal pdf (we're choosing k to be 1) CDFg = lambda x: np.log(x +1) # generates our proposal using inverse sampling # domain limits xmin = 0 # the lower limit of our domain xmax = 10 # the upper limit of our domain # range limits for inverse sampling umin = CDFg(xmin) umax = CDFg(xmax) N = 10000 # the total of samples we wish to generate accepted = 0 # the number of accepted samples samples = np.zeros(N) count = 0 # the total count of proposals # generation loop while (accepted < N): # Sample from g using inverse sampling u = np.random.uniform(umin, umax) xproposal = np.exp(u) - 1 # pick a uniform number on [0, 1) y = np.random.uniform(0, 1) # Do the accept/reject comparison if y < p(xproposal)/g(xproposal): samples[accepted] = xproposal accepted += 1 count +=1 print count, accepted # get the histogram info hinfo = np.histogram(samples,50) # plot the histogram plt.hist(samples,bins=50, label=u'Samples'); # plot our (normalized) function xvals=np.linspace(xmin, xmax, 1000) plt.plot(xvals, hinfo[0][0]*p(xvals), 'r', label=u'p(x)') # turn on the legend plt.legend() plt.show()>
24051 10000
可以对比基本的舍取法和改进的舍取法的结果,前者产生符合要求分布的10000个随机数运算了99552步,后者运算了24051步,可以看到效率明显提高。
总结
以上就是本文关于Python编程产生非均匀随机数的几种方法代码分享的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:
Python数据可视化编程通过Matplotlib创建散点图代码示例
Python编程实现使用线性回归预测数据
Python数据可视化正态分布简单分析及实现代码
如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]