我想模拟非标准密度函数的数据。我已经找到以下链接(How do I best simulate an arbitrary univariate random variate using its probability function?)。然而,这给出了奇怪的结果。不知何故,这个累积密度函数(cdf())不能很好地工作。从某些值来看,它给出了非常奇怪的结果。例如,请查看以下代码:
density=function(x)(25*200.7341^25/x^26*exp(-(200.7341/x)^25))
cdf<-function(x) integrate(density,1,x)[[1]]
cdf(9701)
[1] 1
cdf(9702)
[1] 6.33897e-05
所以我的问题是,如何创建一个“好”的CDF功能?或者更直接地说,我如何模拟PDF中的数据?
答案 0 :(得分:5)
正如@pjs所指出,我们可以使用Rejection sampling(查看维基详情)。
以下是此方法的一种实现方式。
最重要的步骤是找到我们可以从中采样并且从中存在M的分布g,使得M * g> 1。 f为所有点
f <- function(x) (25 * 200.7341^25 / x^26 * exp(-(200.7341/x)^25))
g <- function(x) dnorm(x, mean = 200.7341, sd = 40)
M <- 5
curve(f, 0, 500)
curve(M * g(x), 0, 500, add = TRUE, lty = "dashed")
现在,我们可以执行算法
set.seed(42)
k <- 1
count <- 0
res <- vector(mode = "numeric", length = 1000)
while(k < 1001) {
z <- rnorm(n = 1, mean = 200.7341, sd = 40)
R <- f(z) / (M * g(z))
if (R > runif(1)) {
res[k] <- z
k <- k + 1
}
count <- count + 1
}
(accept_rate <- (k / count) * 100)
## [1] 19.7086
require(MASS) ## for truehist
truehist(res)
curve(f, 0, 250, add = TRUE)
接受率不高。您可以尝试找到更好的信封功能或使用Metropolis Hasting算法。
答案 1 :(得分:4)
如果积分间隔非常大,
密度的峰值很难找到:integrate
很容易错过它,
并认为你所整合的功能(几乎)无处不在。
如果你知道峰值在哪里,你可以将积分切成三个: 在高峰期,之前和之后。
# Density
A <- 200.7341
f <- function(x) 25*A^25 / x^26 * exp( -(A/x)^25 )
a <- 150
b <- 400
# Numeric integration
F1 <- function(x) {
if( x < a ) integrate(f, 1, x)[[1]]
else if( x < b ) integrate(f, 1, a)[[1]] + integrate(f, a, x)[[1]]
else integrate(f, 1, a)[[1]] + integrate(f, a, b)[[1]] + integrate(f, b, x)[[1]]
}
# Compare with the actual values
F2 <- function(x) exp( -(A/x)^25 )
F1(200); F2(200)
F1(1e4); F2(1e4)
F1(1e5); F2(1e5) # Imprecise if b is too low...
在检查您的间隔是否足够大之后,您可以删除之前的&#34;&#34; &#34;&#34;&#34;&#34;间隔:他们的贡献是零。
F1 <- function(x) {
if( x < a ) 0
else if( x < b ) integrate(f, a, x)[[1]]
else 1
}
答案 2 :(得分:0)
当我玩你的CDF时,很快就会出现大部分动作是在180到350之间的x,我通过绘制该范围内的密度来确认。
我很确定x = 9702时的结果反映了当你涉及第25和第26次幂时计算的数值不稳定性。如果你不相信你的CDF或者它不可逆,那么另一个基于pdf的选项是acceptance/rejection。您应该能够使用一个简单的三角形,其中min = 180,最大值约为300,模式约为200作为边界函数g(x),并遵循维基百科上描述的算法以获得相当不错的结果。
一般情况下,如果反转不适用于任意分布,那么您的其他选择是1)基于pdf相对于边界函数的接受/拒绝,2)组合(可以将您的分布解构为更易于生成的组件)并使用条件概率选择合适的组件,或3)“特殊技巧” - 是否存在卷积或参数化给出分布等价的情况(例如,N(0,1)^ 2 =卡方(1),卡方(k)= k个独立卡方(1)的总和,exp(2)=卡方(2)等...)。有关您的选项的综合处理,请参阅非均匀随机变量生成的Luc Devroye's book。