繁体   English   中英

R 中分布的随机抽样速度

[英]Speed of random sampling from distribution in R

我试图研究一个概率分布,其矩是加泰罗尼亚数,并想出了

qcatmo <- function(p, k=4){ (qbeta(p/2+1/2, 3/2, 3/2)*2 - 1)^2 * k } 
colMeans(outer(qcatmo(ppoints(10^6)), 0:10, "^"))
#      1     1     2     5    14    42   132   429  1430  4862 16796

效果很好。 But then I tried to generate random values from this distribution, and found three possible approaches (A using the quantile function I already knew worked applied to runif , B slightly more direct using the built-in rbeta function, and C using a form of rejection使用runif进行采样)在大样本上使用时速度明显不同:

rcatmoA <- function(n, k=4){ qcatmo(runif(n), k) }
rcatmoB <- function(n, k=4){ (rbeta(n, 3/2, 3/2)*2 - 1)^2 * k }
rcatmoC <- function(n, k=4){
             n0 <- ceiling(n*4/pi + 7*sqrt(n) + 35)
             x0 <- runif(n0)^2 
             y0 <- runif(n0)^2 
             x0[x0 + y0 < 1][1:n] * k
             }

当进行基准测试时给出

library(microbenchmark)
n <- 10^4
microbenchmark(
  rcatmoA(n,4),
  rcatmoB(n,4),
  rcatmoC(n,4)
  ) 
#Unit: microseconds
#          expr     min       lq      mean   median       uq     max neval cld
# rcatmoA(n, 4) 22817.2 23014.95 23259.688 23186.95 23322.80 25128.9   100   c
# rcatmoB(n, 4)  1526.5  1534.40  1615.255  1541.30  1607.15  4952.1   100  b 
# rcatmoC(n, 4)   781.5   788.70   884.339   795.00   813.80  7266.2   100 a  

我的问题是:

  • 为什么B版比A版快那么多?
  • 如果 B 版本更快,因为它避免将 function 应用于runif数据,为什么 C 版本更快?
  • 在这种情况下如何最好地制作随机样本有什么一般性建议吗?

正如您所发现的,有不同的方法可以执行相同分布的随机变量生成(在这种情况下为 beta 分布)。

  1. 我认为 A 版本最慢,因为 beta 分布的分位数没有封闭形式,因此qbeta必须求助于数值反转(因为 beta 分布的 CDF,正则化 beta function,通常只被称为积分,所以变得更加困难) . 实际上,正如qbeta的源代码所示,分位数 function 远非微不足道。 查看 R 源代码
  2. B 版本所依赖的rbeta的源代码使用 Cheng (1978) 的 beta 分布算法。 在这种特殊情况下,使用了算法 BB,它采用了拒绝采样器(并且每次迭代也至少需要两个对数)。 相比之下,C 版本采用更简单的拒绝条件。 Cheng 的算法是多年来针对 beta 分布提出的众多算法之一,L. Devroye 在非均匀随机变量生成中提到了 1986 年及更早的算法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM