![](/img/trans.png)
[英]how do you generate samples from the logistic CDF using the inverse-CDF method
[英]Trying to simulate Poisson samples using inverse CDF method but my R function produces wrong results
我寫了一些R代碼來模擬泊松分布中的隨機樣本,基於算法的描述(見附圖)。 但是我的代碼似乎無法正常工作,因為生成的隨機樣本與R的內置rpois()
函數生成的隨機樣本具有不同的模式。 誰能告訴我我做錯了什么以及如何修復我的功能?
r.poisson <- function(n, l=0.5)
{
U <- runif(n)
X <- rep(0,n)
p=exp(-l)
F=p
for(i in 1:n)
{
if(U[i] < F)
{
X[i] <- i
} else
{
p=p*l/(i+1)
F=F+p
i=i+1
}
}
return(X)
}
r.poisson(50)
輸出與rpois(50, lambda = 0.5)
非常不同。 我遵循的算法是:
(謝謝您的提問。現在我知道如何模擬泊松隨機變量了。)
你誤會了。 您引用的逆 CDF 方法(使用遞歸計算)用於生成單個泊松隨機樣本。 所以你需要修復這個函數來產生一個數字。 這是正確的功能,注釋以幫助您遵循每個步驟。
rpois1 <- function (lambda) {
## step 1
U <- runif(1)
## step 2
i <- 0
p <- exp(-lambda)
F <- p
## you need an "infinite" loop
## no worry, it will "break" at some time
repeat {
## step 3
if (U < F) {
X <- i
break
}
## step 4
i <- i + 1
p <- lambda * p * i
F <- F + p
## back to step 3
}
return(X)
}
現在要獲取n
樣本,您需要調用此函數n
次。 R有一個很好的函數,稱為replicate
,可以多次重復一個函數。
r.poisson <- function (n, lambda) {
## use `replicate()` to call `rpois1` n times
replicate(n, rpois1(lambda))
}
現在我們可以與R自己的rpois
進行合理的比較。
x1 <- r.poisson(1000, lambda = 0.5)
x2 <- rpois(1000, lambda = 0.5)
## set breaks reasonably when making a histogram
xmax <- max(x1, x2) + 0.5
par(mfrow = c(1, 2))
hist(x1, main = "proof-of-concept-implementation", breaks = seq.int(-0.5, xmax))
hist(x2, main = "R's rpois()", breaks = seq.int(-0.5, xmax))
矢量化版本將比使用replicate
的非矢量化函數運行得快得多。 這個想法是隨着i
的增加迭代地丟棄均勻的隨機樣本。
r.poisson1 <- function(n, l = 0.5) {
U <- runif(n)
i <- 0L
X <- integer(n)
p <- exp(-l)
F <- p
idx <- 1:n
while (length(idx)) {
bln <- U < F
X[idx[bln]] <- i
p <- l*p/(i <- i + 1L)
F <- F + p
idx <- idx[!bln]
U <- U[!bln]
}
X
}
@Zheyuan Li 的非向量化函數:
rpois1 <- function (lambda) {
## step 1
U <- runif(1)
## step 2
i <- 0
p <- exp(-lambda)
F <- p
## you need an "infinite" loop
## no worry, it will "break" at some time
repeat {
## step 3
if (U < F) {
X <- i
break
}
## step 4
i <- i + 1
p <- lambda * p * i
F <- F + p
## back to step 3
}
return(X)
}
r.poisson2 <- function (n, lambda) {
## use `replicate()` to call `rpois1` n times
replicate(n, rpois1(lambda))
}
基准:
microbenchmark::microbenchmark(r.poisson1(1e5),
r.poisson2(1e5, 0.5),
rpois(1e5, 0.5))
#> Unit: milliseconds
#> expr min lq mean median uq max neval
#> r.poisson1(1e+05) 3.063202 3.129151 3.782200 3.225402 3.734600 18.377700 100
#> r.poisson2(1e+05, 0.5) 217.631002 244.816601 269.692648 267.977001 287.599251 375.910601 100
#> rpois(1e+05, 0.5) 1.519901 1.552300 1.649026 1.579551 1.620451 7.531401 100
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.