从自定义分布生成随机数

Generate random number from custom distribution

我正在尝试从自定义分布生成随机数,我已经发现了这个问题: Simulate from an (arbitrary) continuous probability distribution 但不幸的是,它对我没有帮助,因为那里建议的方法需要分布函数的公式。我的分布是多个均匀分布的组合,基本上分布函数看起来像直方图。一个例子是:

f(x) = { 
    0     for  x < 1
    0.5   for  1 <= x < 2
    0.25  for  2 <= x < 4
    0     for  4 <= x
}

你只需要逆 CDF 方法:

samplef <- function (n) {
  x <- runif(n)
  ifelse(x < 0.5, 2 * x + 1, 4 * x)
  }

自己计算 CDF 以验证:

F(x) = 0                 x < 1
       0.5 * x - 0.5     1 < x < 2
       0.25 * x          2 < x < 4
       1                 x > 4

所以它的倒数是:

invF(x) = 2 * x + 1      0 < x < 0.5
          4 * x          0.5 < x < 1

您可以将各种有效的方法结合起来,从 discrete distributions 中抽取连续均匀的样本。

也就是说,从变量的整数部分 Y=[X] 进行模拟,它具有离散分布,概率等于每个区间中的概率(例如通过 table 方法 - a.k.a. 别名方法),然后简单地添加一个随机均匀 [0,1$, X = Y+U.

在您的示例中,您让 Y 以 0.5、0.25 和 0.25 的概率取值 1、2、3(相当于以相等的概率采样 1、1、2、3),然后添加随机制服.

如果您的 "histogram" 确实很大,这可能是一种非常快速的方法。

在 R 中,你可以通过

做一个简单的(如果不是特别有效的话)版本
sample(c(1,1,2,3))+runif(1)

sample(c(1,1,2,3),n,replace=TRUE)+runif(n)

更一般地说,您可以使用 sample 中的概率权重参数。

如果您需要比这更快的速度(对于某些应用程序,尤其是直方图和样本量非常大的应用程序),您可以使用 [= 中提到的方法大大加快离散部分的速度35=],并用低级语言(比如 C 语言)对该函数的主力部分进行编程。

就是说,即使只是使用上面的代码和相当大的 "bigger" 直方图——几十到几百个箱子——这种方法似乎——即使在我相当不起眼的笔记本电脑上——也能产生一百万不到一秒的随机值,所以对于许多应用程序来说,这会很好。

如果您从中抽取随机数的自定义分布是由经验观察定义的,那么您也可以使用 fishmethods::remp() 包和函数从经验分布中抽取。

https://rdrr.io/cran/fishmethods/man/remp.html