R:使用重要性采样进行蒙特卡洛集成

Raa*_*aaj 5 statistics pdf-generation r probability

我有一个整体来评估

      "x^(-0.5)" ; x in [0.01,1] 
Run Code Online (Sandbox Code Playgroud)

为此,我正在使用重要性采样MC:理论上说,必须使用近似PDF来计算期望值(几乎可以肯定地收敛到积分的均值)

在仅根据图绘制给定的积分和指数PDF之后,我选择了 rexpdexp来生成PDF-我的代码如下所示-

#Without Importance Sampling
set.seed(1909)
X <- runif(1000,0.01,1)
Y <- X^(-0.5)
c( mean(Y), var(Y) )

#Importance sampling Monte Carlo
w <- function(x) dunif(x, 0.01, 1)/dexp(x,rate=1.5)
f <- function(x) x^(-0.5)
X= rexp(1000,rate=1.5)
Y=w(X)*f(X)
c( mean(Y), var(Y) )
Run Code Online (Sandbox Code Playgroud)

有人可以确认我的想法是否正确吗?如果错了,我应该怎么做呢?请阐明-我已经了解了理论,但是实践证明对我来说是有问题的。

对于不是那么简单的积分,

1.)f(x) = [1 + sinh(2x)ln(x)] ^-1我仅在观察图后才选择正常的PDF = g(x)(均值= 0.5和SD = 5)作为近似值。我为此编写了类似的代码,但是它说NaN是在重要性抽样的情况下产生的。(这在理想情况下意味着未定义的函数,但我不知道如何解决)。

2.)f(x,y) = exp(-x ^ 4-y ^ 4)

如何为上述函数选择g(x,y)

sha*_*dow 4

一般来说,您的方法似乎是正确的,但您必须更加小心要集成的领域。在您原来的示例中,大约 20% 的值rexp(1000, 1.5)高于 1。该函数dexp(x, rate=1.5)不是区间 [0,1] 上的密度函数。你必须除以pexp(1, rate=1.5). 因此,这就是我对重要性采样示例所做的操作:

#Importance sampling Monte Carlo
w <- function(x) dunif(x, 0.01, 1)/dexp(x,rate=1.5) * pexp(1, rate=1.5)
f <- function(x) x^(-0.5)
X <- rexp(1000,rate=1.5)
X <- X[X<=1]
Y <- w(X)*f(X)
c(mean(Y), var(Y))
Run Code Online (Sandbox Code Playgroud)

在你的第二个例子中,同样的事情导致了问题。您得到负 X,因此得到 log(X) 的 NA 值。此外,您的正常函数应以 0.5 为中心,且方差较小。这是我的方法:

#Without Importance Sampling
set.seed(1909)
X <- runif(1000,0.01,1)
Y <- (1+sinh(2*X)*log(X))^(-1)
c(mean(Y), var(Y))

#Importance sampling Monte Carlo
w <- function(x) dunif(x, 0.01, 1)/dnorm(x, mean=0.5, sd=0.25) * (1-2*pnorm(0, mean=0.5, sd=0.25))
f <- function(x) (1+sinh(2*x)*log(x))^(-1)
X <- rnorm(1000, mean=0.5, sd=0.25)
Y1 <- w(X)
Y2 <- f(X)
Y <- Y1*Y2
Y <- Y[!(is.na(Y2)&Y1==0)]
c(mean(Y), var(Y))
Run Code Online (Sandbox Code Playgroud)

在你的第二个例子中,我不太明白是什么y。它只是一个常数吗?那么威布尔分布也许可行。

编辑:关于评论中的其他问题。(1) 任何概率密度函数都应该积分到 1。因此dexp(x, rate=1.5)不是区间 [0,1] 上的密度函数,它只积分到pexp(1, rate=1.5)。然而,该函数

dexp01 <- function(x, rate){
  dexp(x, rate=rate)/pexp(1, rate=rate)
}
Run Code Online (Sandbox Code Playgroud)

实际上积分为 1:

integrate(dexp, 0, 1, rate=1.5)
integrate(dexp01, 0, 1, rate=1.5)
Run Code Online (Sandbox Code Playgroud)

这就是包含概率分布函数的基本原理。如果你有不同的区间,例如[0.3,8],你必须相应地调整函数:

dexp0.3_8 <- function(x, rate){
  dexp(x, rate=rate)/(pexp(8, rate=rate)-pexp(0.3, rate=rate))
}
integrate(dexp0.3_8, 0.3, 8, rate=1.5)
Run Code Online (Sandbox Code Playgroud)

(2) 这里我选择方差,使 中大约 95% 的值rnorm(1000, .5, .25)处于 0 到 1 的区间内(有许多值超出该区间肯定会增加方差)。但是,我不确定这是否是分布函数的最佳选择。重要性函数的选择是一个我不太熟悉的问题。你可以在CrossValidated上询问。你的下一个问题也是如此。