Preciso gerar números aleatórios seguindo a distribuição Normal dentro do intervalo . (Eu estou trabalhando na R.)
Eu sei que a função rnorm(n,mean,sd)
irá gerar números aleatórios após a distribuição normal, mas como definir os limites de intervalo dentro disso? Existe alguma função R específica disponível para isso?
x <- rnorm(n, mean, sd); x <- x[x > lower.limit & x < upper.limit]
Respostas:
Parece que você deseja simular a partir de uma distribuição truncada e, no seu exemplo específico, uma normal truncada .
Existem vários métodos para fazê-lo, alguns simples, outros relativamente eficientes.
Ilustrarei algumas abordagens no seu exemplo normal.
Aqui está um método muito simples para gerar um de cada vez (em algum tipo de pseudocódigo):
Se a maior parte da distribuição estiver dentro dos limites, isso é bastante razoável, mas pode ficar bem lento se você quase sempre gerar fora dos limites.
Em R, você pode evitar o loop de uma vez calculando a área dentro dos limites e gerar valores suficientes para ter quase certeza de que, depois de lançar os valores fora dos limites, você ainda terá os valores necessários.
Você pode usar accept-rejeitar com alguma função de atualização adequada durante o intervalo (em alguns casos, uniforme será bom o suficiente). Se os limites fossem razoavelmente estreitos em relação ao sd, mas você não estivesse muito longe, uma majoração uniforme funcionaria bem com o normal, por exemplo.
Se você tem um cdf razoavelmente eficiente e cdf inversa (como
pnorm
eqnorm
para a distribuição normal em R), você pode usar o método inverso do CDF descrito no primeiro parágrafo da seção simulação da página da Wikipedia sobre normal truncada . [Na verdade, é o mesmo que pegar um uniforme truncado (truncado nos quantis necessários, o que na verdade não exige nenhuma rejeição, já que isso é apenas mais um uniforme) e aplicar o cdf normal inverso a ele. Observe que isso pode falhar se você estiver muito longe]Existem outras abordagens; a mesma página da Wikipedia menciona a adaptação do método zigurate , que deve funcionar para uma variedade de distribuições.
O mesmo link da Wikipedia menciona dois pacotes específicos (ambos no CRAN) com funções para gerar normais truncados:
Olhando em volta, muito disso é abordado nas respostas de outras perguntas (mas não exatamente duplicadas, já que essa pergunta é mais geral do que apenas a normal truncada) ... consulte discussão adicional em
uma. Esta resposta
b. A resposta de Xi'an aqui , que tem um link para seu artigo sobre o arXiv (junto com algumas outras respostas que valem a pena).
fonte
A abordagem rápida e suja é usar a regra 68-95-99.7 .
Em uma distribuição normal, 99,7% dos valores estão dentro de 3 desvios padrão da média. Portanto, se você definir sua média como o meio do valor mínimo e do valor máximo desejados e definir o desvio padrão para 1/3 da média, obtém (principalmente) valores que se enquadram no intervalo desejado. Então você pode apenas limpar o resto.
Recentemente, enfrentei esse mesmo problema, tentando gerar notas aleatórias dos alunos para os dados dos testes. No código acima, usei
pmax
epmin
substituí valores fora dos limites pelo valor mínimo ou máximo dentro dos limites. Isso funciona para o meu objetivo, porque estou gerando quantidades razoavelmente pequenas de dados, mas para quantidades maiores ele fornecerá saliências visíveis nos valores mínimo e máximo. Portanto, dependendo de seus propósitos, pode ser melhor descartar esses valores, substituí-los porNA
s ou "rolá-los novamente" até que estejam dentro dos limites.fonte
sample(x=min:max, prob=dnorm(...))
talvez seja uma maneira mais fácil de fazer isso.sample(x=min:max, prob=dnorm(...))
que parece um pouco mais curto que sua resposta.sample()
truque só será útil se você estiver tentando escolher números inteiros aleatórios ou algum outro conjunto de valores discretos e predefinidos.Não há função incorporada para valores gerados a partir da distribuição truncada, mas é trivial programar esse método usando as funções comuns para gerar variáveis aleatórias. Aqui está uma
R
função simplesrtruncnorm
que implementa esse método em algumas linhas de código.Essa é uma função vetorizada que irá gerar
N
variáveis aleatórias de IID a partir da distribuição normal truncada. Seria fácil programar funções para outras distribuições truncadas pelo mesmo método. Também não seria muito difícil programar funções associadas de densidade e quantil para a distribuição truncada.fonte