从自定义分布生成随机数
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()
包和函数从经验分布中抽取。
我正在尝试从自定义分布生成随机数,我已经发现了这个问题: 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()
包和函数从经验分布中抽取。