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

原创: hxj7

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

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

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

\ldots 等等

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

指数分布抽样

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

  • 用 runif 函数模拟指数分布抽样的 \text{c.d.f.} 曲线;
  • 用R自带的 rexp 实现指数分布抽样的 \text{c.d.f.} 曲线;
  • 指数分布的理论 \text{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")

效果如下:


image

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

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

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

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

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

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

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

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

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

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

计算出的一系列 y 值就构成了我们想要的抽样样本。我们可以比较一下用这种间接方法得出的模拟 \text{c.d.f.} 曲线和理论 \text{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")

结果如下:


image

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

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

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")

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

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

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

即可以得到一个标准正态分布的抽样样本,该方法被称作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")

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

image

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

Probability Integral Transformation

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

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

补充证明

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

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

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

因此,Y\text{c.d.f.} 是:
\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}

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

也就是说,Y\text{c.d.f.} 就是F。证毕。

(公众号:生信了)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354