Bu dağıtım için rasgele sayıları simüle etmenin bir yolunu bulma


20

Kümülatif dağıtım işlevi ile bir dağıtımdan sahte rasgele sayılar simüle R bir program yazmaya çalışıyorum:

F(x)=1exp(axbp+1xp+1),x0

buradaa,b>0,p(0,1)

Ters dönüşüm örneklemeyi denedim ama tersi analitik olarak çözülebilir görünmüyor. Bu soruna bir çözüm önerebilirseniz sevinirim


1
Tam bir cevap için yeterli zaman yok, ancak Alternatif Örnekleme algoritmalarını alternatif olarak kontrol edebilirsiniz.
chuse

1
bir ders kitabı alıştırması değil, sadece kısıtlamayı şart koştum çünkü verilerim için makul bir varsayım
Sebastian

6
Daha sonra dağılımı bir Üstel'in mükemmel bir gücüne dönüştüren tarafından "mucizevi" normalleşmeye şaşırdım , ancak mucizeler gerçekleşir (küçük olasılıkla). (p+1)1
Xi'an

Yanıtlar:


49

Bu egzersize basit (ve ekleyebilirsem, zarif) bir çözüm var: iki hayatta kalma dağılımının bir ürünü gibi göründüğünden: dağıtımı , Bu durumda , Üstel dağılımı ve , -th Üstel dağılımının gücü .1F(x)

(1F(x))=exp{axbp+1xp+1}=exp{ax}1F1(x)exp{bp+1xp+1}1F2(x)
F
X=min{X1,X2}X1~F1,X2~F2
F1E(bir)F21/(p+1)E(b/(p+1))

İlişkili R kodu alabildiği kadar basit

x=pmin(rexp(n,a),rexp(n,b/(p+1))^(1/(p+1))) #simulating an n-sample

ve ters pdf ve kabul-reddetme kararlarından kesinlikle çok daha hızlıdır:

> n=1e6
> system.time(results <- Vectorize(simulate,"prob")(runif(n)))
utilisateur     système      écoulé 
    89.060       0.072      89.124 
> system.time(x <- simuF(n,1,2,3))
utilisateur     système      écoulé 
     1.080       0.020       1.103 
> system.time(x <- pmin(rexp(n,a),rexp(n,b/(p+1))^(1/(p+1))))
utilisateur     système      écoulé 
     0.160       0.000       0.163 

şaşırtıcı derecede mükemmel uyum ile:

resim açıklamasını buraya girin


5
gerçekten harika bir çözüm!
Sebastian

14

Ters dönüşümü her zaman sayısal olarak çözebilirsiniz.

Aşağıda çok basit bir ikiye arama yapıyorum. Belirli bir girdi olasılığı ( formülünüzde zaten bir bulunduğundan kullanıyorum ), ve ile . Sonra olana kadar ikiye . Son olarak, yinelemeli aralığını iki eşit parçaya böler uzunluğu daha kısa olan kadar ve orta nokta tatmin .qqpxL=0xR,=1xR,F(xR,)>q[xL,xR,]εxMF(xM)q

ECDF senin uyan benim seçimler için yeterli iyi ve ve makul hızlı. Bunu basit ikiye ayırma yerine Newton tipi bir optimizasyon kullanarak hızlandırabilirsiniz.Fbirb

aa <- 2
bb <- 1
pp <- 0.1

cdf <- function(x) 1-exp(-aa*x-bb*x^(pp+1)/(pp+1))

simulate <- function(prob,epsilon=1e-5) {
    left <- 0
    right <- 1
    while ( cdf(right) < prob ) right <- 2*right

    while ( right-left>epsilon ) {
        middle <- mean(c(left,right))
        value_middle <- cdf(middle)
        if ( value_middle < prob ) left <- middle else right <- middle
    }

    mean(c(left,right))
}

set.seed(1)
results <- Vectorize(simulate,"prob")(runif(10000))
hist(results)

xx <- seq(0,max(results),by=.01)
plot(ecdf(results))
lines(xx,cdf(xx),col="red")

ECDF


10

Kabul etme-reddetme yoluyla doğrudan çözümleme durumunda biraz kıvrıktır. İlk olarak, basit bir farklılaşma dağılımın İkinci olarak, üst var Üçüncüsü, ikinci terimi göz önünde bulundurarak değişkenini alın , yani, . Sonra , değişken değişiminin Jacobian'ıdır. Eğer

f(x)=(bir+bxp)exp{-birx-bp+1xp+1}
f(x)=bire-birxe-bxp+1/(p+1)1+bxpe-bxp+1/(p+1)e-birx1
f(x)g(x)=bire-birx+bxpe-bxp+1/(p+1)
gξ=xp+1x=ξ1/(p+1)
dxdξ=1p+1ξ1p+1-1=1p+1ξ-pp+1
X şeklinde bir yoğunluğa sahiptir, burada normalleştirme sabiti, daha sonra yoğunluğu , (i), bu araçların olduğu Üstel değişkeni olarak dağıtılır ve (ii) sabit bire eşittir. Bu nedenle, , Üstel dağılımının ve Üstel -th gücünün eşit ağırlıklı karışımına eşit olur.κbxpe-bxp+1/(p+1)κΞ=X1/(p+1)
κbξpp+1e-bξ/(p+1)1p+1ξ-pp+1=κbp+1e-bξ/(p+1)
ΞE(b/(p+1))κg(x)E(bir)1/(p+1)E(b/(p+1))dağılım, ağırlıkları hesaba katmak için eksik çarpma sabiti modulo : Ve bir karışım olarak simüle etmek kolaydır.2
f(x)g(x)=2(12bire-birx+12bxpe-bxp+1/(p+1))
g

Kabul et reddetme algoritmasının R oluşturması

simuF <- function(a,b,p){
  reepeat=TRUE
  while (reepeat){
   if (runif(1)<.5) x=rexp(1,a) else
      x=rexp(1,b/(p+1))^(1/(p+1))
   reepeat=(runif(1)>(a+b*x^p)*exp(-a*x-b*x^(p+1)/(p+1))/
      (a*exp(-a*x)+b*x^p*exp(-b*x^(p+1)/(p+1))))}
  return(x)}

ve bir n-numunesi için:

simuF <- function(n,a,b,p){
  sampl=NULL
  while (length(sampl)<n){
   x=u=sample(0:1,n,rep=TRUE)
   x[u==0]=rexp(sum(u==0),b/(p+1))^(1/(p+1))
   x[u==1]=rexp(sum(u==1),a)
   sampl=c(sampl,x[runif(n)<(a+b*x^p)*exp(-a*x-b*x^(p+1)/(p+1))/
      (a*exp(-a*x)+b*x^p*exp(-b*x^(p+1)/(p+1)))])
   }
  return(sampl[1:n])}

A = 1, b = 2, p = 3 için bir örnek:

resim açıklamasını buraya girin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.