Comment puis-je échantillonner à partir d'une distribution avec CDF incomputable?

8

Problème lié à la simulation semi-informatique ici.

J'ai une distribution où

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

pour certaines constantes b et n, et x est un entier tel que .0xn

Maintenant, je dois échantillonner à partir de cette distribution. Il a un CDF inversible, il est donc possible de le faire directement en théorie. Le problème est que les nombres impliqués sont GRANDS. En fait, ils sont tellement volumineux qu'ils débordent tous les deux de formats conventionnels et prennent au moins quelques minutes (à un moment donné, j'ai abandonné ...) pour calculer en utilisant des formats de précision arbitraires. Fondamentalement, le CDF inverse implique toujours un terme de , pour . Malgré cela, les numéros de sortie seront toujours compris entre , il semble donc qu'il devrait y avoir un moyen de le faire.eb(n+1)350<n<35000n

Ce que je recherche, c'est un moyen approximatif d'échantillonnage de cette distribution qui soit calculable. Existe-t-il d'autres méthodes d'échantillonnage? Que sont-ils?

John Doucette
la source
2
Avez-vous envisagé de normaliser ou de mettre à l'échelle vos données d'une manière ou d'une autre pour réduire le domaine?
EngrStudent

Réponses:

7

Le CDF est facilement inversible. Une formule pour l'inversion conduit à ce qui doit être l'une des solutions les plus simples et les plus rapides possibles.

Commençons par observer que la probabilité du résultat , , est proportionnelle à . Ainsi, si nous générons une valeur uniforme comprise entre et = , il suffit de trouver le plus grand pour lequelk0knebkq0qmax=k=0nebk(1eb(n+1))/(1eb)k

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

L'algèbre simple donne la solution

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

Voici une Rimplémentation construite comme tous les autres générateurs de nombres aléatoires: son premier argument spécifie le nombre de valeurs iid à générer et le reste des arguments nomme les paramètres ( as et 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))
}

À titre d'exemple de son utilisation, générons un million de variations aléatoires selon cette distribution:

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

( seconde était nécessaire.)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)

Histogramme

( été ajouté à chaque valeur afin de créer un meilleur histogramme: la procédure de a une idiosyncrasie (= bug) dans laquelle la première barre est trop haute lorsque le point d'extrémité gauche est réglé à zéro.) La courbe rouge est la distribution de référence que cette simulation tente de reproduire. Évaluons la qualité de l'ajustement avec un test du chi carré:1Rhist

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

La valeur de p est de : un bel ajustement.0.84

whuber
la source
3
Excellente solution. Je ne savais pas qu'on pouvait échantillonner de cette façon (c'est-à-dire en s'appuyant sur des échantillons d' au lieu d' ), mais c'est évident rétrospectivement. Uni(0,k),k>1Uni(0,1)
Cam.Davidson.Pilon
6

Vous avez affaire à une distribution géométrique tronquée avec . Il existe différentes manières d'aborder ce problème.p=1eb

Je conseillerais différentes options dans différentes situations; certaines options impliqueraient de simuler à partir d'une géométrie et de se régénérer lorsqu'elle est en dehors de la plage, en prenant la partie entière d'une exponentielle tronquée appropriée ( comme ici ), ou en utilisant l'une quelconque de plusieurs techniques rapides adaptées à des distributions discrètes sur une plage finie. Étant donné que est grand, la prise de parole d'une exponentielle tronquée est susceptible d'être relativement rapide, mais son choix dépend également de .nb

Voici une question connexe sur math.SE

Avant d'essayer des suggestions spécifiques, quelle est une plage typique de valeurs pour ?b

Glen_b -Reinstate Monica
la source
Merci pour votre réponse! b ~ ln (1 + epsilon), où epsilon est un paramètre supplémentaire> 0.
John Doucette
1
Vous avez donc converti ma question sur la plage typique de b en une sur la plage typique de ε. Avant d'essayer des suggestions spécifiques, quelle est une plage typique de valeurs pour ε?
Glen_b -Reinstate Monica
La raison pour laquelle je demande est quelle approche particulière est plus efficace dépend des caractéristiques de la situation. Il semble que vous soyez déjà satisfait de l'autre réponse, alors peut-être que cela ne vaut pas la peine de vous soucier de l'efficacité potentielle supplémentaire.
Glen_b -Reinstate Monica
@JohnDoucette: Si b est presque nul, alors votre distribution est presque uniforme sur donc vous pouvez utiliser l'uniforme comme une proposition dans un algorithme de rejet d'acceptation car la limite supérieure ne devrait pas être terrible. {0,,n\]
Xi'an
1
@ Xi'an Il faudrait assez petit plutôt que avant qu'il ne soit approprié d'utiliser une distribution uniforme, car le taux d'acceptation est , qui sera inefficacement bas lorsque . nbb0(1e(n+1)b)/((n+1)(1eb)) (1exp(nb))/(nb)nb1
whuber
4

Notons tout d'abord que qui, si était continu, serait lié à une distribution exponentielle. Ensuite, ce que vous pouvez faire est de simuler à partir d'une distribution exponentielle tronquée et de prendre la (partie entière) des observations.P(x)ebxxfloor()

Le cdf d'une exponentielle tronquée est

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

Ensuite, si nous faisons , nous obtenons que . Si est grand, alors qui suggère d'approximer .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)
La personne
la source
Je pense que c'est essentiellement ce que je cherchais. bn est toujours très large, un échantillonnage proportionné a du sens. N'était pas au courant de la cartographie, bien que cela soit clair rétrospectivement. Merci!
John Doucette
Je suis heureux de voir que cela a aidé. Je pense que je n'ai pas expliqué correctement, mais cette approche produit des échantillons à partir de la distribution cible exacte. À votre santé.
Personne
@ Xi'an Les poids ne sont-ils pas les mêmes si l'on utilise la valeur et prend la partie entière? ebn
Personne
@ Xi'an Je pense que ce terme apparaît dans le numérateur de , jusqu'à une factorisation ...P(x)
Personne
1
@ Xi'an En fait, ce travail fourni rweirdpest modifié pour passer nà n+1. (Comme indiqué ici, il ne renverra jamais une valeur égale à n: c'est l'effet de l'approximation.) Une analyse un peu plus rigoureuse est donnée dans ma réponse. Bien que j'obtienne une formule d'apparence différente, elle est équivalente à celle (plus simple!) Donnée ici, une fois la modification n-> n+1effectuée.
whuber
4

Un moyen d'échantillonner à partir de la distribution cible est dep(k)exp{bk}

  1. exécuter une expérience Metropolis-Hastings pour déterminer le support (intéressant) de la distribution, c'est-à-dire dans quel sous-ensemble de il se concentre;{0,1,,n}

    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. Utilisez le support ainsi déterminé, disons, pour calculer les probabilités exactes comme pour éviter les débordements.{k0,,k1}p(k)exp{bk+bk0}

Mise à jour: En y réfléchissant davantage, puisque diminue en k, le support effectif de la distribution commencera toujours à . Si est assez grand, ce support se terminera très rapidement, auquel cas importe peu car les grandes valeurs de ne seront jamais visitées. Si est très petit, le pdf est presque plat, ce qui signifie que l'on peut utiliser une distribution uniforme sur comme proposition d'acceptation-rejet. Et utilisez les journaux dans l'étape d'acceptation pour éviter les débordements.p()k0=0bnkb{0,1,,n}

Xi'an
la source