¿Cómo puedo muestrear de una distribución con CDF no computable?

8

Problema relacionado con la simulación de semi-informática aquí.

Tengo una distribución donde

P (x) =(eb1)eb(nx)ebn+b1

para algunas constantes byn, yx es un número entero tal que .0xn

Ahora, necesito probar de esta distribución. Tiene un CDF invertible, por lo que es posible hacer esto directamente en teoría. El problema es que los números involucrados son GRANDES. Tan grande, de hecho, que ambos desbordan las variables formateadas convencionalmente, y toman al menos minutos (en algún momento me di por vencido ...) para calcular usando formatos de precisión arbitrarios. Básicamente, el CDF inverso todavía implica un término de , para . A pesar de esto, los números de salida seguirán en el rango , por lo que parece que debería haber una forma de hacerlo.eb(n+1)350<n<35000n

Lo que estoy buscando es una forma de muestreo aproximadamente de esta distribución que sea computable. ¿Existen métodos alternativos de muestreo? ¿Qué son?

John Doucette
fuente
2
¿Has considerado normalizar o escalar tus datos de alguna manera para reducir el dominio?
EngrStudent

Respuestas:

7

El CDF es fácilmente invertible. Una fórmula para la inversión conduce a lo que tiene que ser una de las soluciones más simples y convenientes posibles.

Comience observando que la probabilidad del resultado , , es proporcional a . Por lo tanto, si generamos un valor uniforme entre y = , solo necesitamos encontrar la más grande para la cualk0knebkq0qmax=k=0nebk(1eb(n+1))/(1eb)k

qi=0kebi=1e(k+1)b1eb.

Álgebra simple da la solución

k=ceiling(log(1q(1eb))b).

Aquí hay una Rimplementación construida como todos los otros generadores de números aleatorios: su primer argumento especifica cuántos valores de iid generar y el resto de los argumentos nombran los parámetros ( as y as ):bbnn.max

rgeom.truncated <- function(n=1, b, n.max) {
  a <- 1 - exp(-b)
  q.max <- (1 - exp(-b*(n.max+1))) / a
  q <- runif(n, 0, q.max)
  return(-ceiling(log(1 - q*a) / b))
}

Como ejemplo de su uso, generemos un millón de variantes aleatorias de acuerdo con esta distribución:

b <- 0.001
n.max <- 3500
n.sim <- 10^6
set.seed(17)
system.time(sim <- rgeom.truncated(n.sim, b,n.max))

( Se necesitaron segundos).0.10

h <- hist(sim+1, probability=TRUE, breaks=50, xlab="Outcome+1")
pmf <- exp(-b * (0: n.max)); pmf <- pmf / sum(pmf)
lines(0:n.max, pmf, col="Red", lwd=2)

Histograma

( Se agregó a cada valor para crear un mejor histograma: el procedimiento tiene una idiosincrasia (= error) en la que la primera barra es demasiado alta cuando el punto final izquierdo se establece en cero). La curva roja es la distribución de referencia que esta simulación intenta reproducir. Vamos a evaluar la bondad del ajuste con una prueba de chi-cuadrado:1Rhist

observed <- table(sim)
expected <- n.sim * pmf
chi.square <- (observed-expected)^2 / expected
pchisq(sum(chi.square), n.max, lower.tail=FALSE)

El valor p es : un ajuste hermoso.0.84

whuber
fuente
3
Gran solución Nunca supe que se podría muestrear de esta manera (es decir, confiar en muestras de lugar de ), pero es obvio en retrospectiva. Uni(0,k),k>1Uni(0,1)
Cam.Davidson.Pilon
6

Se trata de una distribución geométrica truncada con . Hay una variedad de formas de abordar esto.p=1eb

Aconsejaría diferentes opciones en diferentes situaciones; Algunas opciones implicarían simular a partir de una geometría y regeneración cuando está fuera del rango, tomar la parte entera de un exponencial truncado apropiado ( como aquí ), o usar cualquiera de varias técnicas rápidas adaptadas a distribuciones discretas en un rango finito. Dado que es grande, tomar el piso de un exponencial truncado probablemente sea relativamente rápido, pero si es la mejor opción también depende de .nb

Aquí hay una pregunta relacionada con las matemáticas.

Antes de intentar sugerencias específicas, ¿cuál es un rango típico de valores para ?b

Glen_b -Reinstate a Monica
fuente
¡Gracias por tu respuesta! b ~ ln (1 + epsilon), donde epsilon es un parámetro adicional> 0.
John Doucette
1
Entonces, convertiste mi pregunta sobre el rango típico de b en una sobre el rango típico de ε. Antes de intentar sugerencias específicas, ¿cuál es un rango típico de valores para ε?
Glen_b -Reinstate a Mónica el
La razón por la que pregunto es qué enfoques particulares son más eficientes depende de las características de la situación. Parece que ya está satisfecho con la otra respuesta, por lo que tal vez no valga la pena preocuparse por la eficiencia potencial adicional.
Glen_b: reinstala a Mónica el
@JohnDoucette: si b es casi cero, entonces su distribución es casi uniforme sobre por lo tanto, puede usar el uniforme como propuesta en un algoritmo de aceptación y rechazo, ya que el límite superior no debería ser terrible. {0,,n\]
Xi'an
1
@ Xi'an Necesitaría bastante pequeño en lugar de antes de que sea apropiado usar una distribución uniforme, porque la tasa de aceptación es , que será ineficientemente bajo cuando . nbb0(1e(n+1)b)/((n+1)(1eb)) (1exp(nb))/(nb)nb1
whuber
4

Primero, tenga en cuenta que que, si fuera continuo, estaría relacionado con una distribución exponencial. Entonces, lo que puede hacer es simular a partir de una distribución exponencial truncada y tomar la (parte entera) de las observaciones.P(x)ebxxfloor()

El cdf de un exponencial truncado es

F(x;n,b)=1ebx1ebn.

Entonces, si hacemos , obtenemos que . Si es grande, entonces que sugiere aproximar .F(x;n,b)=ux=1blog[1u(1ebn)]bnebn0x1blog[1u]

rweirdp <- function(ns,n,b){
u <- runif(ns)
samp <- - log(1-u*(1-exp(-n*b)))/b
return(floor(samp))
}

rweirdp(1000,10,1)
Persona
fuente
Creo que esto es básicamente lo que estaba buscando. bn siempre es muy grande, el muestreo proporcional tiene sentido. No estaba al tanto del mapeo, aunque es claro en retrospectiva. ¡Gracias!
John Doucette
Me alegra ver que eso ayudó. Creo que no lo expliqué correctamente, pero este enfoque produce muestras de la distribución objetivo exacta. Salud.
Persona
@ Xi'an ¿No son los pesos iguales si uno usa el valor ebny tomar la parte entera?
Persona
@ Xi'an Creo que ese término aparece en el numerador de P(x), hasta una factorización ...
Persona
1
@ Xi'an En realidad, este trabajo siempre rweirdpse modifica para cambiar na n+1. (Como se indica aquí, nunca devolverá un valor igual a n: ese es el efecto de la aproximación). En mi respuesta se da un análisis un poco más riguroso. Aunque obtengo una fórmula de apariencia diferente, es equivalente a la (¡más simple!) Dada aquí, una vez que se realiza la modificación n-> n+1.
whuber
4

Una forma de tomar muestras de la distribución objetivo p(k)exp{bk} Es para

  1. ejecutar un experimento Metropolis-Hastings para determinar el soporte (interesante) de la distribución, es decir, en qué subconjunto de {0,1,,n} se concentra;

    metro=function(N,b,n){
    x=sample(0:n,N,rep=TRUE)
    for (t in 2:N){
      x[t]=prop=x[t-1]+sample(c(-1,1),1)
    
      if ((prop<0)||(prop>n)||(log(runif(1))>b*(x[t]-prop)))
          x[t]=x[t-1]
      }
    return(x)
    }
    
  2. Utilice el soporte así determinado, {k0,,k1} decir, para calcular las probabilidades exactas como p(k)exp{bk+bk0} para evitar desbordamientos.

Actualización: al pensar más en ello, ya quep() está disminuyendo en k, el soporte efectivo de la distribución siempre comenzará en k0=0. Sib es bastante grande, este soporte terminará muy rápidamente, en cuyo caso n no importa tanto como valores grandes de kNunca será visitado. Sib es muy pequeño, el pdf es casi plano, lo que significa que se puede usar una distribución uniforme en {0,1,,n}como una propuesta de aceptar-rechazar. Y use registros en el paso de aceptación para evitar desbordamientos.

Xi'an
fuente