Como posso converter uma distribuição uniforme (como a maioria dos geradores de números aleatórios produzem, por exemplo, entre 0,0 e 1,0) em uma distribuição normal? E se eu quiser uma média e um desvio padrão de minha escolha?
106
Respostas:
O algoritmo Zigurate é bastante eficiente para isso, embora a transformação Box-Muller seja mais fácil de implementar do zero (e não muito lenta).
fonte
Existem muitos métodos:
fonte
Alterar a distribuição de qualquer função para outra envolve o uso do inverso da função desejada.
Em outras palavras, se você almeja uma função de probabilidade específica p (x), você obtém a distribuição integrando-a -> d (x) = integral (p (x)) e usa seu inverso: Inv (d (x)) . Agora use a função de probabilidade aleatória (que tem distribuição uniforme) e lance o valor do resultado por meio da função Inv (d (x)). Você deve obter valores aleatórios lançados com distribuição de acordo com a função escolhida.
Esta é a abordagem matemática genérica - ao usá-la agora você pode escolher qualquer probabilidade ou função de distribuição que você tenha, desde que tenha uma aproximação inversa ou boa.
Espero que tenha ajudado e obrigado pelo pequeno comentário sobre o uso da distribuição e não a probabilidade em si.
fonte
Aqui está uma implementação de javascript usando a forma polar da transformação Box-Muller.
fonte
Use o teorema do limite central, entrada da Wikipédia, entrada mathworld a seu favor.
Gere n dos números uniformemente distribuídos, some-os, subtraia n * 0,5 e você terá a saída de uma distribuição aproximadamente normal com média igual a 0 e variância igual a
(1/12) * (1/sqrt(N))
(ver wikipedia sobre distribuições uniformes para esse último)n = 10 dá a você algo meio decente rápido. Se você quiser algo mais da metade decente, vá para a solução Tylers (conforme observado no entrada Wikipédia em distribuições normais )
fonte
Eu usaria o Box-Muller. Duas coisas sobre isso:
Normalmente, você armazena em cache um valor e retorna o outro. Na próxima chamada para uma amostra, você retorna o valor em cache.
Você deve então dimensionar a pontuação Z pelo desvio padrão e adicionar a média para obter o valor total na distribuição normal.
fonte
Onde R1, R2 são números uniformes aleatórios:
DISTRIBUIÇÃO NORMAL, com SD de 1: sqrt (-2 * log (R1)) * cos (2 * pi * R2)
Isso é exato ... não há necessidade de fazer todos aqueles loops lentos!
fonte
Parece incrível que eu pudesse adicionar algo a isso depois de oito anos, mas para o caso de Java, gostaria de apontar aos leitores o método Random.nextGaussian () , que gera uma distribuição gaussiana com média 0,0 e desvio padrão 1,0 para você.
Uma simples adição e / ou multiplicação mudará a média e o desvio padrão de acordo com suas necessidades.
fonte
O módulo de biblioteca Python padrão aleatório tem o que você deseja:
Para o algoritmo em si, dê uma olhada na função em random.py na biblioteca Python.
A entrada manual está aqui
fonte
Esta é minha implementação JavaScript do Algoritmo P ( Método Polar para desvios normais ) da Seção 3.4.1 do livro de Donald Knuth, The Art of Computer Programming :
fonte
Acho que você deve tentar isso no EXCEL:
=norminv(rand();0;1)
. Isso produzirá os números aleatórios que devem ser normalmente distribuídos com a média zero e a variância unitária. "0" pode ser fornecido com qualquer valor, de modo que os números tenham a média desejada e, mudando "1", você obterá a variância igual ao quadrado de sua entrada.Por exemplo:
=norminv(rand();50;3)
resultará em números normalmente distribuídos com MEAN = 50 VARIANCE = 9.fonte
P Como posso converter uma distribuição uniforme (como a maioria dos geradores de números aleatórios produzem, por exemplo, entre 0,0 e 1,0) em uma distribuição normal?
Para implementação de software, conheço alguns nomes de geradores aleatórios que fornecem uma sequência aleatória pseudo-uniforme em [0,1] (Mersenne Twister, Linear Congruate Generator). Vamos chamá-lo de U (x)
Existe uma área matemática que se denomina teoria da probabilidade. Primeira coisa: se você quiser modelar RV com distribuição integral F, então você pode tentar avaliar apenas F ^ -1 (U (x)). Na teoria pr. Foi provado que tal va terá distribuição integral F.
A etapa 2 pode ser aplicada para gerar rv ~ F sem o uso de quaisquer métodos de contagem quando F ^ -1 pode ser derivado analiticamente sem problemas. (por exemplo, exp.distribution)
Para modelar a distribuição normal, você pode calcular y1 * cos (y2), onde y1 ~ é uniforme em [0,2pi]. e y2 é a distribuição relei.
P: E se eu quiser uma média e um desvio padrão de minha escolha?
Você pode calcular sigma * N (0,1) + m.
Pode ser mostrado que tal mudança e escala levam a N (m, sigma)
fonte
Esta é uma implementação Matlab usando a forma polar da transformação Box-Muller :
Função
randn_box_muller.m
:E invocar
histfit(randn_box_muller(10000000),100);
este é o resultado:Obviamente, é realmente ineficiente em comparação com o randn integrado do Matlab .
fonte
Tenho o seguinte código que talvez possa ajudar:
fonte
Também é mais fácil usar a função implementada rnorm (), pois é mais rápida do que escrever um gerador de números aleatórios para a distribuição normal. Veja o código a seguir como prova
fonte
fonte