Пошук способу моделювання випадкових чисел для цього розподілу


20

Я намагаюся написати програму на R, яка імітує псевдо випадкові числа з розподілу з функцією кумулятивного розподілу:

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

деa,b>0,p(0,1)

Я спробував обернути відбір проб, але зворотний не здається аналітично вирішим. Буду радий, якби ви могли запропонувати вирішення цієї проблеми


1
Не вистачає часу на повну відповідь, але ви можете перевірити алгоритми вибірки важливості, як альтернативу.
Чусе

1
це не вправа з підручником, я лише обумовив обмеження, оскільки це розумне припущення для моїх даних
Себастьян

6
Потім я здивований "чудодійній" нормалізації за допомогою (p+1)1 що перетворює розподіл на ідеальну силу Експоненціалу, але чудеса трапляються (з малою ймовірністю).
Сіань

Відповіді:


49

Існує просте (і якщо я можу додати, елегантне) рішення цієї вправи: оскільки виглядає як добуток двох розподілів виживання: розподіл - це розподіл У цьому випадку - це експоненційний розподіл, а - -th потужність експоненціального розподілу.1F(x)

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

Асоційований код R настільки ж простий, як і отримується

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

і це, безумовно, набагато швидше, ніж зворотний pdf та резолюції прийняття-відхилення:

> 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 

з незвичайно ідеальним пристосуванням:

введіть тут опис зображення


5
дійсно круте рішення!
Себастьян

14

Завжди можна чисельно вирішити обернене перетворення.

Нижче я роблю дуже простий пошук бісекції. Для заданої вхідної ймовірності (я використовую оскільки у вас вже є у вашій формулі), я починаю з і . Потім я подвоюю поки . Нарешті, я ітеративно розбиваю інтервал поки його довжина не буде коротшою, ніж а її середня точка задовольнить .qqpxL=0xR=1xRF(xR)>q[xL,xR]ϵxMF(xM)q

ECDF досить добре відповідає вашому для мого вибору і , і це досить швидко. Можливо, ви могли б прискорити це, використовуючи оптимізацію типу Ньютона замість простого пошуку бісекції.Fab

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

Існує дещо заплутане, якщо пряме вирішення шляхом прийняття-відхилення. По-перше, проста диференціація показує, що pdf розподілу По-друге, оскільки маємо верхню межу Третій, розглядаючи другий член у , прийміть зміну змінної , тобто . Тоді - якобіан зміни змінної. Якщо

f(x)=(a+bxp)exp{axbp+1xp+1}
f(x)=aeaxebxp+1/(p+1)1+bxpebxp+1/(p+1)eax1
f(x)g(x)=aeax+bxpebxp+1/(p+1)
gξ=xp+1x=ξ1/(p+1)
dxdξ=1p+1ξ1p+11=1p+1ξpp+1
Xмає щільність форми де нормалізуюча константа, то має щільність що означає, що (i) є розподілено у вигляді змінної Exponential і (ii) константа дорівнює одиниці. Отже, кінцевому підсумку дорівнює однаково зваженій суміші Експоненціального розподілу та -ої сили Експоненціальноїκbxpebxp+1/(p+1)κΞ=X1/(p+1)
κbξpp+1ebξ/(p+1)1p+1ξpp+1=κbp+1ebξ/(p+1)
ΞE(b/(p+1))κg(x)E(a)1/(p+1)E(b/(p+1))розподіл, по модулю відсутня мультиплікативна константа для обліку ваг: І прямолінійно імітувати як суміш.2
f(x)g(x)=2(12aeax+12bxpebxp+1/(p+1))
g

Таким чином, R відображення алгоритму прийняття-відхилення

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)}

і для n-вибірки:

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:

введіть тут опис зображення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.