Encontrar una manera de simular números aleatorios para esta distribución


20

Estoy tratando de escribir un programa en R que simule números pseudoaleatorios de una distribución con la función de distribución acumulativa:

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

donde a,b>0,p(0,1)

Intenté el muestreo de transformación inversa pero el inverso no parece ser analíticamente solucionable. Me alegraría si pudiera sugerir una solución a este problema


1
No hay tiempo suficiente para una respuesta completa, pero puede verificar los algoritmos de Muestreo de importancia, como alternativa.
chuse

1
no es un ejercicio de libro de texto, solo estipulé la restricción porque es una suposición razonable para mis datos
Sebastian

66
Luego me sorprende la normalización "milagrosa" por (p+1)1 que convierte la distribución en un poder perfecto de un exponencial, pero los milagros suceden (con poca probabilidad).
Xi'an

Respuestas:


49

Hay una solución directa (y si puedo agregar, elegante) a este ejercicio: dado que 1F(x) aparece como un producto de dos distribuciones de supervivencia:

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

El código R asociado es tan simple como parece

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

y definitivamente es mucho más rápido que el pdf inverso y las resoluciones de aceptar-rechazar:

> 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 

con un ajuste sorprendentemente perfecto:

ingrese la descripción de la imagen aquí


55
solución realmente genial!
Sebastián

14

Siempre puede resolver numéricamente la transformación inversa.

A continuación, hago una búsqueda de bisección muy simple. Para una probabilidad de entrada dada (uso ya que ya tiene una en su fórmula), comienzo con y . Luego doblo hasta que . Finalmente, bisecciono iterativamente el intervalo hasta que su longitud es más corta que y su punto medio satisface .qqpxL=0xR=1xRF(xR)>q[xL,xR]ϵxMF(xM)q

El ECDF se ajusta a su suficientemente bien como para mis elecciones de y , y es razonablemente rápido. Probablemente podría acelerar esto usando alguna optimización de tipo Newton en lugar de la simple búsqueda de bisección.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

Existe una resolución un tanto intrincada si directa por aceptar-rechazar. Primero, una diferenciación simple muestra que el pdf de la distribución es Segundo, ya que tenemos el límite superior Tercero, considerando el segundo término en , tome el cambio de la variable , es decir, . Entonces es el jacobiano del cambio de variable. Si

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
Xtiene una densidad de la forma donde es la constante de normalización, entonces tiene la densidad que significa que (i) es distribuido como una variante exponencial y (ii) la constante es igual a uno. Por lo tanto, termina siendo igual a la mezcla igualmente ponderada de una distribución Exponencial y la potencia de una Exponencialκ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))distribución, módulo una constante multiplicativa faltante de para tener en cuenta los pesos: Y es fácil de simular como una mezcla.2
f(x)g(x)=2(12aeax+12bxpebxp+1/(p+1))
g

Una representación R del algoritmo de aceptación-rechazo es así

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

y para una muestra 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])}

Aquí hay una ilustración para a = 1, b = 2, p = 3:

ingrese la descripción de la imagen aquí

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.