Comment puis-je convertir une distribution uniforme (comme le produisent la plupart des générateurs de nombres aléatoires, par exemple entre 0,0 et 1,0) en une distribution normale? Et si je veux une moyenne et un écart type de mon choix?
106
Réponses:
L' algorithme Ziggurat est assez efficace pour cela, bien que la transformation Box-Muller soit plus facile à implémenter à partir de zéro (et pas trop lente).
la source
Il existe de nombreuses méthodes:
la source
Changer la distribution d'une fonction à une autre implique l'utilisation de l'inverse de la fonction souhaitée.
En d'autres termes, si vous visez une fonction de probabilité p (x) spécifique, vous obtenez la distribution en l'intégrant dessus -> d (x) = intégrale (p (x)) et en utilisant son inverse: Inv (d (x)) . Utilisez maintenant la fonction de probabilité aléatoire (qui ont une distribution uniforme) et transtypez la valeur du résultat via la fonction Inv (d (x)). Vous devez obtenir des valeurs aléatoires avec distribution en fonction de la fonction que vous avez choisie.
Il s'agit de l'approche mathématique générique - en l'utilisant, vous pouvez maintenant choisir n'importe quelle fonction de probabilité ou de distribution que vous avez, à condition qu'elle ait une approximation inverse ou bonne.
J'espère que cela a aidé et merci pour la petite remarque sur l'utilisation de la distribution et non de la probabilité elle-même.
la source
Voici une implémentation javascript utilisant la forme polaire de la transformation Box-Muller.
la source
Utilisez l' entrée de mathworld du théorème de limite centrale de wikipedia à votre avantage.
Générez n des nombres uniformément distribués, additionnez-les, soustrayez n * 0,5 et vous obtenez la sortie d'une distribution approximativement normale avec une moyenne égale à 0 et une variance égale à
(1/12) * (1/sqrt(N))
(voir wikipedia sur les distributions uniformes pour cette dernière)n = 10 vous donne quelque chose à moitié décent rapidement. Si vous voulez quelque chose de plus qu'à moitié décent, optez pour la solution tylers (comme indiqué dans l' entrée wikipedia sur les distributions normales )
la source
J'utiliserais Box-Muller. Deux choses à ce sujet:
En règle générale, vous mettez en cache une valeur et renvoyez l'autre. Lors de l'appel suivant pour un échantillon, vous renvoyez la valeur mise en cache.
Vous devez ensuite mettre à l'échelle le score Z par l'écart type et ajouter la moyenne pour obtenir la valeur complète dans la distribution normale.
la source
Où R1, R2 sont des nombres uniformes aléatoires:
DISTRIBUTION NORMALE, avec SD de 1: sqrt (-2 * log (R1)) * cos (2 * pi * R2)
C'est exact ... pas besoin de faire toutes ces boucles lentes!
la source
Il semble incroyable que je puisse ajouter quelque chose à cela après huit ans, mais pour le cas de Java, je voudrais diriger les lecteurs vers la méthode Random.nextGaussian () , qui génère une distribution gaussienne avec une moyenne de 0,0 et un écart type de 1,0 pour vous.
Une simple addition et / ou multiplication changera la moyenne et l'écart type selon vos besoins.
la source
Le module de bibliothèque Python standard random a ce que vous voulez:
Pour l'algorithme lui-même, jetez un œil à la fonction dans random.py dans la bibliothèque Python.
La saisie manuelle est ici
la source
Voici mon implémentation JavaScript de l' algorithme P ( méthode polaire pour les écarts normaux ) de la section 3.4.1 du livre de Donald Knuth The Art of Computer Programming :
la source
Je pense que vous devriez essayer ceci dans EXCEL:
=norminv(rand();0;1)
. Cela produira les nombres aléatoires qui devraient être normalement distribués avec la moyenne zéro et unir la variance. "0" peut être fourni avec n'importe quelle valeur, de sorte que les nombres soient de la moyenne désirée, et en changeant "1", vous obtiendrez la variance égale au carré de votre entrée.Par exemple:
=norminv(rand();50;3)
donnera les nombres normalement distribués avec MEAN = 50 VARIANCE = 9.la source
Q Comment puis-je convertir une distribution uniforme (comme le produisent la plupart des générateurs de nombres aléatoires, par exemple entre 0,0 et 1,0) en une distribution normale?
Pour l'implémentation logicielle, je connais quelques noms de générateurs aléatoires qui vous donnent une séquence aléatoire pseudo uniforme dans [0,1] (Mersenne Twister, Linear Congruate Generator). Appelons-le U (x)
C'est un domaine mathématique qui a appelé la théorie de la probabilité. Première chose: si vous voulez modéliser rv avec une distribution intégrale F, vous pouvez simplement essayer d'évaluer F ^ -1 (U (x)). En théorie, il a été prouvé qu'une telle RV aura une distribution intégrale F.
L'étape 2 peut être applicable pour générer rv ~ F sans utiliser aucune méthode de comptage lorsque F ^ -1 peut être dérivé analytiquement sans problème. (par exemple exp.distribution)
Pour modéliser la distribution normale, vous pouvez cacculer y1 * cos (y2), où y1 ~ est uniforme dans [0,2pi]. et y2 est la distribution relei.
Q: Que faire si je veux une moyenne et un écart type de mon choix?
Vous pouvez calculer sigma * N (0,1) + m.
On peut montrer qu'un tel décalage et mise à l'échelle conduit à N (m, sigma)
la source
Il s'agit d'une implémentation Matlab utilisant la forme polaire de la transformation Box-Muller :
Fonction
randn_box_muller.m
:Et en invoquant
histfit(randn_box_muller(10000000),100);
ceci est le résultat:De toute évidence, il est vraiment inefficace par rapport au randn intégré de Matlab .
la source
J'ai le code suivant qui pourrait peut-être vous aider:
la source
Il est également plus facile d'utiliser la fonction implémentée rnorm () car elle est plus rapide que d'écrire un générateur de nombres aléatoires pour la distribution normale. Voir le code suivant comme preuve
la source
la source