本文介绍了如何变换均匀分布以便对特定分布进行抽样。

如果你要进行随机抽样,R语言提供了诸多现成的函数供你使用,比如:

  • runif: 均匀分布抽样
  • rbinom: 二项分布抽样
  • rpois: 泊松分布抽样
  • rnorm: 正态分布抽样
  • rexp: 指数分布抽样
  • rgamma: 伽马分布抽样

…\ldots… 等等

那么,如果不用现成的函数,我们能自己实现抽样功能吗?比如,我们是否可以不用 rexp 函数而实现指数分布抽样?答案是肯定的,只需对均匀分布进行适当地变换即可。

指数分布抽样

下面的例子是对一个指数分布进行抽样,并绘制了三条 c.d.f.\text{c.d.f.}c.d.f. 曲线,分别是:

  • 用 runif 函数模拟指数分布抽样的 c.d.f.\text{c.d.f.}c.d.f. 曲线;
  • 用R自带的 rexp 实现指数分布抽样的 c.d.f.\text{c.d.f.}c.d.f. 曲线;
  • 指数分布的理论 c.d.f.\text{c.d.f.}c.d.f. 曲线。

代码如下:

# Q1
N <- 100000
lambda <- 1   # 指数分布参数
set.seed(123)
x <- runif(N, 0, 1)
y <- log(1 - x) / -lambda   # 用runif模拟指数分布抽样
ey <- ecdf(y)
set.seed(123)
r <- rexp(N, lambda)     # R自带的rexp抽样函数
er <- ecdf(r)
plot(ey, xlim = c(0,3), col="red", main="Generating Pseudo-Random Numbers Having\na Exponential Distribution with lambda=1",ylab="Cum prob F(x)")   # runif模拟抽样的c.d.f.曲线
lines(er, xlim=c(0,3), col="green")    # rexp模拟的c.d.f.曲线
curve(1 - exp(-lambda * x), from=0, to=3, add=T, col="blue")  # 指数分布的理论c.d.f.曲线
legend("bottomright", legend=c("simulative (using runif)", "simulative (using rexp)", "theoretical"),col=c("red", "green", "blue"), lty=1, bty="n")

效果如下:

可以看出,三条曲线几乎完全重合,说明用 runif 实现模拟指数分布抽样是可行的。实际上:

假设我们想要根据某个特定的概率分布(我们已经知道该分布的 c.d.f.\text{c.d.f.}c.d.f. 是FFF)进行抽样,可以这样:首先我们对一个在[0,1][0,1][0,1]上服从均匀分布的变量XXX进行随机抽样,得到x1,x2,…,xnx_1, x_2, \ldots, x_nx1​,x2​,…,xn​;然后我们构造一个变量Y=F−1(X)Y=F^{-1}(X)Y=F−1(X),并据此计算得到 y1,y2,…,yny_1, y_2, \ldots, y_ny1​,y2​,…,yn​。那么,y1,y2,…,yny_1, y_2, \ldots, y_ny1​,y2​,…,yn​就是我们想要的抽样样本。因为实际上可以证明 YYY 的 c.d.f.\text{c.d.f.}c.d.f. 就是FFF(证明过程在文末)。
上面F−1F^{-1}F−1其实就是 quantile 函数,值得注意的是当有很多个值F(x1)=F(x2)=⋯=F(xn)=yF(x_1)=F(x_2)=\cdots=F(x_n)=yF(x1​)=F(x2​)=⋯=F(xn​)=y时,F−1(y)=min⁡{x1,x2,…,xn}F^{-1}(y)=\min\{x_1,x_2,\ldots,x_n\}F−1(y)=min{x1​,x2​,…,xn​}。

也就是说,我们可以通过一种间接的方法,即变换均匀分布来对特定分布进行抽样。为什么要这样拐弯抹角呢?因为有时候我们碰到的分布不是很常见,R语言并没有提供相应的函数,这时候我们就可以用上述间接的方法自己写函数实现抽样。

变换均匀分布对一种特定分布抽样

比如,如果我们想要对下面这一个分布进行抽样,其p.d.f.\text{p.d.f.}p.d.f.是:
f(x)={2x0≤x≤1,0otherwise.f(x) = \begin{cases} 2x \quad & 0 \le x \le 1, \\ 0 & \text{otherwise.} \end{cases}f(x)={2x0​0≤x≤1,otherwise.​

R语言并没有提供一个现成的函数可以对上面的分布进行抽样。但是我们可以自行编写代码实现:

首先我们知道上面分布的 c.d.f.\text{c.d.f.}c.d.f.是:
F(x)={0x<0,x20≤x≤1,1x>1.F(x) = \begin{cases} 0 \quad & x < 0, \\ x^2 \quad & 0 \le x \le 1, \\ 1 & x > 1. \end{cases}F(x)=⎩⎪⎨⎪⎧​0x21​x<0,0≤x≤1,x>1.​
那么:
F−1(x)=x12for 0≤x≤1.F^{-1}(x) = x^{\frac{1}{2}} \quad \text{for $0 \le x \le 1.$} F−1(x)=x21​for 0≤x≤1.
按照上面的间接方法,我们首先对[0,1][0, 1][0,1]上的均匀分布进行抽样,得到一系列 xxx 值:

N <- 100000     # 抽样的样本大小
set.seed(123)
x <- runif(N, 0, 1)

然后根据Y=F−1(X)Y=F^{-1}(X)Y=F−1(X)计算出相应的 yyy 值:

y <- sqrt(x)    # 用runif模拟实现特定分布抽样

计算出的一系列 yyy 值就构成了我们想要的抽样样本。我们可以比较一下用这种间接方法得出的模拟 c.d.f.\text{c.d.f.}c.d.f. 曲线和理论 c.d.f.\text{c.d.f.}c.d.f. 曲线相差多少:

ey <- ecdf(y)
plot(ey, xlim = c(0,1), col="red", main="Generating Pseudo-Random Numbers Having\na Specified Distribution",ylab="Cum prob F(x)")   # 模拟抽样的c.d.f.曲线
curve(x ^ 2, from=0, to=1, add=T, col="blue")  # 上述特定分布的理论曲线
legend("bottomright", legend=c("simulative", "theoretical"),col=c("red", "blue"), lty=1, bty="n")

结果如下:

从图中可以看出,模拟曲线和理论曲线几乎完全重合,也就是说我们的间接方法的确很好地模拟了特定分布抽样。

上述特定分布的完整代码如下:

N <- 100000     # 抽样的样本大小
set.seed(123)
x <- runif(N, 0, 1)
y <- sqrt(x)    # 用runif模拟实现特定分布抽样
ey <- ecdf(y)
plot(ey, xlim = c(0,1), col="red", main="Generating Pseudo-Random Numbers Having\na Specified Distribution",ylab="Cum prob F(x)")   # 模拟抽样的c.d.f.曲线
curve(x ^ 2, from=0, to=1, add=T, col="blue")  # 上述特定分布的理论曲线
legend("bottomright", legend=c("simulative", "theoretical"),col=c("red", "blue"), lty=1, bty="n")

我们用两个例子说明了可以用一种间接抽样的方法对特定分布进行抽样,不过这种方法是有前提的,即我们要知道FFF的解析表达式,以及FFF要存在一个反函数。由于这些限制,该方法在实际应用中有诸多限制。

Box-Muller方法:变换均匀分布对标准正态分布抽样

上面只是对一个均匀分布变量进行变换,我们也可以对多个均匀分布变量进行变换。比如,如果要对标准正态分布抽样,我们可以对[0,1][0,1][0,1]上的两个均匀分布变量XXX和YYY做如下变换:
Z=cos⁡(2πX)log⁡(1Y2)Z = \cos(2\pi X)\sqrt{\log(\frac{1}{Y^2})}Z=cos(2πX)log(Y21​)​

即可以得到一个标准正态分布的抽样样本,该方法被称作Box-Muller方法

具体代码如下:

N <- 100000     # 抽样的样本大小
set.seed(123)
x <- runif(N, 0, 1)
y <- runif(N, 0, 1)
z <- cos(2 * pi * x) * sqrt(log(1 / y ^ 2))    # 用runif模拟实现标准正态分布抽样
ez <- ecdf(z)
set.seed(123)
r <- rnorm(N, 0, 1)     # 用rnorm模拟实现标准正态分布抽样
er <- ecdf(r)
plot(ez, col="red", main="Generating Pseudo-Random Numbers Having\na Standard Normal Distribution",ylab="Cum prob F(x)")   # runif模拟抽样的c.d.f.曲线
lines(er, col="blue")   # 用rnorm模拟抽样的c.d.f.曲线
legend("bottomright", legend=c("simulative (using runif)", "simulative (using rnorm)"),col=c("red", "blue"), lty=1, bty="n")

c.d.f.\text{c.d.f.}c.d.f. 曲线的结果如下:

可以看出,两条曲线几乎完全重叠,说明变换的效果是成功的。

Probability Integral Transformation

最后,我们简单介绍一下Probability Integral Transformation,就是将上述间接方法的过程反过来,以实现一种伪随机数生成工具。具体来说,就是:

如果一个连续型变量XXX的c.d.f.\text{c.d.f.}c.d.f.是FFF,那么变量Y=F(x)Y=F(x)Y=F(x)在[0,1][0,1][0,1]上服从均匀分布。

补充证明

最后,我们给出上文的一个结论的证明:

假设我们想要根据某个特定的概率分布(我们已经知道该分布的 c.d.f.\text{c.d.f.}c.d.f. 是FFF)进行抽样,可以这样:首先我们对一个在[0,1][0,1][0,1]上服从均匀分布的变量XXX进行随机抽样,得到x1,x2,…,xnx_1, x_2, \ldots, x_nx1​,x2​,…,xn​;然后我们构造一个变量Y=F−1(X)Y=F^{-1}(X)Y=F−1(X),并据此计算得到 y1,y2,…,yny_1, y_2, \ldots, y_ny1​,y2​,…,yn​。那么,y1,y2,…,yny_1, y_2, \ldots, y_ny1​,y2​,…,yn​就是我们想要的抽样样本。因为实际上可以证明 YYY 的 c.d.f.\text{c.d.f.}c.d.f. 就是FFF。
上面F−1F^{-1}F−1其实就是 quantile 函数,值得注意的是当有很多个值F(x1)=F(x2)=⋯=F(xn)=yF(x_1)=F(x_2)=\cdots=F(x_n)=yF(x1​)=F(x2​)=⋯=F(xn​)=y时,F−1(y)=min⁡{x1,x2,…,xn}F^{-1}(y)=\min\{x_1,x_2,\ldots,x_n\}F−1(y)=min{x1​,x2​,…,xn​}。

证明:
因为XXX在[0,1][0,1][0,1]上服从均匀分布,所以其c.d.f.\text{c.d.f.}c.d.f. 是:
G(x)=Pr⁡(X≤x)=xG(x) = \Pr(X \le x) = x G(x)=Pr(X≤x)=x

因此,YYY 的 c.d.f.\text{c.d.f.}c.d.f. 是:
H(y)=Pr⁡(Y≤y)=Pr⁡[F−1(X)≤y]=Pr⁡[F(F−1(X))≤F(y)]=Pr⁡[X≤F(y)]=G(F(y))=F(y)\begin{aligned} H(y) & = \Pr(Y \le y) \\ & = \Pr[F^{-1}(X) \le y] \\ & = \Pr[F(F^{-1}(X)) \le F(y)] \\ & = \Pr[X \le F(y)] \\ & = G(F(y)) \\ & = F(y) \end{aligned}H(y)​=Pr(Y≤y)=Pr[F−1(X)≤y]=Pr[F(F−1(X))≤F(y)]=Pr[X≤F(y)]=G(F(y))=F(y)​

注意,从第二个等式到第三个等式成立是因为FFF是一个c.d.f.\text{c.d.f.}c.d.f.,所以FFF是一个单调不减函数,再加上F−1F^{-1}F−1 quantile 函数的特点,因此两个等式是等价的。

也就是说,YYY 的 c.d.f.\text{c.d.f.}c.d.f. 就是FFF。证毕。

(公众号:生信了)

R-概率统计与模拟(三)变换均匀分布对特定分布进行抽样相关推荐

  1. 曲线均匀分布_R——概率统计与模拟(三) 变换均匀分布对特定分布进行抽样

    原创:hxj7 本文介绍了如何变换均匀分布以便对特定分布进行抽样. 如果你要进行随机抽样,R语言提供了诸多现成的函数供你使用,比如: runif: 均匀分布抽样 rbinom: 二项分布抽样 rpoi ...

  2. 概率统计:第三章 多维随机变量及其分布

    第三章    多维随机变量及其分布 内容提要: 一. 二维随机变量 1.二维随机变量的定义:设E是一个随机试验,它的样本空间是, 是定义在S上的随机变量,则叫做二维随机向量或二维随机变量. 2.二维随 ...

  3. 机器学习和概率统计的关系

    机器学习和概率统计的关系 ​ 机器学习是一个比较宽泛的概念,主要包括有监督学习,无监督学习,强化学习等,每个分类又有很多不同的算法,在使用时需要根据不同的场景进行选择,这个将会在后续的博客中涉及,这里 ...

  4. 概率统计(三)常见分布与假设检验

    常见分布与假设检验 一.一般随机变量 二.常见分布 1.离散型分布 (1)二项分布 (2)泊松分布 (3)几何分布 (4)负二项分布 (5)超几何分布 2.连续型分布 (1)均匀分布 (2)正态分布 ...

  5. 概率统计16——均匀分布、先验与后验

    相关阅读: 最大似然估计(概率10) 重要公式(概率4) 概率统计13--二项分布与多项分布 贝叶斯决策理论(1)基础知识 | 数据来自于一个不完全清楚的过程-- 均匀分布 简单来说,均匀分布是指事件 ...

  6. 概率统计及其应用第三章知识总结_2020考研数学概率论与数理统计:各章节考试重点分析...

    考研数学有两大重点,基础要打好,练习要多做,错题要巩固.下面来看下有关概率论与数理统计相关复习内容,一起来学习吧! 一.概率与数理统计学科的特点 (1)研究对象是随机现象 高数是研究确定的现象,而概率 ...

  7. 数组变换-Java-牛客模拟三

    package 模拟三;import java.util.Scanner;/*** 题目描述:牛牛有一个数组,里面的数可能不相等,现在他想把数组变为:所有的数都相等.问是否可行.* 牛牛可以进行的操作 ...

  8. 读书笔记:程序员的数学 概率统计

    读书笔记:程序员的数学 概率统计 特点 内容 第一.二章 概率定义 多随机变量 第三.四章 离散.连续分布 第五章 协方差矩阵与多元正态分布 第六.七章 估计与检验 伪随机数 第八章 各类应用 体会 ...

  9. MADlib——基于SQL的数据挖掘解决方案(9)——数据探索之概率统计

    样本是随机变量,统计量作为样本的函数自然也是随机变量.当用它们去推断总体时,有多大的可靠性与统计量的概率分布有关.本篇学习概率统计的基本知识,以及在此基础上的统计推论.MADlib提供了概率函数和统计 ...

最新文章

  1. CSS0 -- 静态、自适应、流式、响应式
  2. AngularJS recursive(递归)
  3. test1 3-15 模拟赛1
  4. 关于HTML Button点击自动刷新页面的问题解决
  5. python入门——P34异常处理:你不可能总是对的2
  6. 使用免费ip代理进行投票
  7. golang学习和使用经验总结
  8. 一个很好的反选的例子
  9. 面向对象-java控制台计算器简单实现[50行]
  10. python 实现dcmtk关联pacs功能 推送下拉影像
  11. 079冒险岛mysql解封账号_Win7系统玩冒险岛079单机版输入账号密码后出现error38如何解决?...
  12. Outlook html 图片白色空白,outlook签名设置_解决Outlook中的签名和邮件图片都显示空白的办法_outlook邮件空白...
  13. cox(Quaro)对设计的崭新定义,改变我的人生
  14. vs2012 visual studio 2012安装失败管道正在关闭解决方法
  15. 互联网公司 概率面试题整理
  16. Python全栈编程
  17. 关于mysql百万100W数据查询优化
  18. ie浏览器打不开计算机二级页面,是什么情况?
  19. 对 Android 重力感应器的初步认识
  20. IIS管理器和文件流

热门文章

  1. Java关键字注意事项
  2. linux系统weblogic10.3.6(jar) 下载安装
  3. 用户故事与敏捷方法-第一章问题答案
  4. 微信app清空群聊天消息的方法
  5. API接口自动化测试框架搭建(十三)-优化operate_conf.py并创建用户数据目录data
  6. 【安装库】Pycharm安装Qt platform
  7. m认知无线电信号检测算法matlab仿真,能量检测,循环平稳检测以及自相关检测
  8. JavaFX开发桌面,移动端,嵌入式权威指南(一)—— JavaFX桌面入门小项目
  9. 晶闸管有很多种,最开始发明的是可控硅整流管
  10. vb.net 教程 3-10 窗体编程 datagridview控件 1 初步