¿Cómo tomar muestras de una distribución normal con media y varianza conocidas usando un lenguaje de programación convencional?

36

Nunca he tenido un curso de estadística, así que espero preguntar en el lugar correcto aquí.

Supongamos que tengo sólo dos datos que describen una distribución normal: la media y varianza σ 2 . Quiero usar una computadora para la muestra al azar de esta distribución tal que respeto estas dos estadísticas.μσ2

Es bastante obvio que puedo manejar la media simplemente normalizar alrededor de 0: sólo tiene que añadir a cada muestra antes de la salida de la muestra. Pero no veo cómo generar mediante programación muestras de respetar σ 2 .μσ2

Mi programa estará en un lenguaje de programación convencional; No tengo acceso a ningún paquete estadístico.

Fixee
fuente
¿Tu idioma tiene un generador de números aleatorios? ¿Es este generador solo de distribución uniforme o también puede generar de distribución normal?
ttnphns
@ttnphns: Casi todos los lenguajes de computadora vienen con un generador de números aleatorios. Son generadores abrumadoramente uniformes en algún dominio finito.
Fixee

Respuestas:

33

Si puede muestrear a partir de una distribución dada con media 0 y varianza 1, entonces puede muestrear fácilmente desde una transformación de ubicación de escala de esa distribución, que tiene media y varianza σ 2 . Si x es una muestra de una distribución media 0 y varianza 1, entonces σ x + μ es una muestra con media μμσ2x

σx+μ
μ y varianza . Entonces, todo lo que tiene que hacer es escalar la variable por la desviación estándar σ (raíz cuadrada de la varianza) antes de agregar la media μ .σ2σμ

Cómo se obtiene realmente una simulación de una distribución normal con media 0 y varianza 1 es una historia diferente. Es divertido e interesante saber cómo implementar tales cosas, pero ya sea que use un paquete estadístico o un lenguaje de programación o no, le recomendaré que obtenga y use una función o biblioteca adecuada para la generación de números aleatorios. Si desea asesoramiento sobre qué biblioteca utilizar, puede agregar información específica sobre qué lenguaje (s) de programación está utilizando.

Editar: A la luz de los comentarios, algunas otras respuestas y el hecho de que Fixee aceptó esta respuesta, daré más detalles sobre cómo se pueden usar transformaciones de variables uniformes para producir variables normales.

  • Un método, ya mencionado en un comentario de VitalStatistix , es el método Box-Muller que toma dos variables aleatorias uniformes independientes y produce dos variables aleatorias normales independientes. Francogrex publicó como respuesta un método similar que evita el cálculo de dos funciones trascendentales sin y cos a expensas de algunas simulaciones más .
  • Un método completamente general es la transformación de una variable aleatoria uniforme mediante la función de distribución inversa. Si se distribuye uniformemente en [ 0 , 1 ], entonces Φ - 1 ( U ) tiene una distribución normal estándar. Aunque no existe una fórmula analítica explícita para Φ - 1 , puede calcularse mediante aproximaciones numéricas precisas. La implementación actual en R (la última vez que revisé) usa esta idea. El método es conceptualmente muy simple, pero requiere una implementación precisa de Φ - 1 , que probablemente no esté tan extendido como las (otras) funciones trascendentales.U[0,1]
    Φ1(U)
    Φ1Φ1registro , pecado y cos .
  • Varias respuestas mencionan la posibilidad de utilizar el teorema del límite central para aproximar la distribución normal como un promedio de variables aleatorias uniformes. Esto no es generalmente recomendado. Los argumentos presentados, como igualar la media 0 y la varianza 1, y las consideraciones de apoyo de la distribución no son convincentes. En el ejercicio 2.3 en "Introducción a los métodos de Monte Carlo con R" de Christian P. Robert y George Casella, este generador se llama anticuado y la aproximación se llama muy pobre .
  • Hay una cantidad desconcertante de otras ideas. Capítulo 3 y, en particular, la Sección 3.4, en "El arte de la programación de computadoras" vol. 2 por Donald E. Knuth es una referencia clásica sobre la generación de números aleatorios. Brian Ripley escribió Computer Generation of Random Variables: A Tutorial , que puede ser útil. También se recomienda el libro mencionado por Robert y Casella, o quizás el Capítulo 2 en su otro libro, "Métodos estadísticos de Monte Carlo".

Al final del día, un método implementado correctamente no es mejor que el generador de números pseudoaleatorios uniforme utilizado. Personalmente, prefiero confiar en bibliotecas de propósito especial que creo que son confiables. Casi siempre confío en los métodos implementados en R, ya sea directamente en R o mediante la API en C / C ++. Obviamente, esta no es una solución para todos, pero no estoy lo suficientemente familiarizado con otras bibliotecas para recomendar alternativas.

NRH
fuente
(+1) Buena respuesta y consejos para el OP.
cardenal
18
2log(U1)cos(2πU2)
2log(U1)sin(2πU2)
2
@Vital: no es un comentario innecesario; una buena. La transformación Box-Muller es probablemente la más fácil de programar con una mínima posibilidad de hacer algo malo sin darse cuenta. No es el más rápido , pero es lo suficientemente competitivo. Dicho esto, el uso de una biblioteca de códigos establecida probablemente sea aún más seguro, especialmente porque el lugar donde es más probable que se dé un paso en falso es cómo se generan las entradas variables aleatorias uniformes .
Cardenal
@Vital: Gracias, esto es lo que estaba buscando. Si desea convertir su comentario en una respuesta, felizmente lo votaré.
Fixee
1
@VitalStatistix, es un buen comentario, y parece que esto era lo que estaba buscando el OP. ¿Por qué no convertirlo en una respuesta y tal vez elaborarlo un poco sobre la idea general de usar transformaciones de variables aleatorias uniformes? Dudé en hacer esto por la razón que Cardinal menciona principalmente porque no sé si el generador uniforme predeterminado de cualquier idioma es un buen generador.
NRH
10

Esto es realmente un comentario sobre la respuesta de Michael Lew y el comentario de Fixee, pero se publica como respuesta porque no tengo la reputación en este sitio para comentar.

[0,1]61

E[i=112Xi]=i=112E[Xi]=12×12=6
var[i=112Xi]=i=112var[Xi]=12×112=1.
i=112Xi610/12i=112Xi6[6,6]6
Dilip Sarwate
fuente
5

Además de la respuesta de NRH, si aún no tiene medios para generar muestras aleatorias a partir de una "distribución normal estándar" N (0,1), a continuación se muestra una manera buena y simple (ya que usted menciona que no tiene una estadística paquete, las siguientes funciones deberían estar disponibles en la mayoría de los lenguajes de programación estándar).

1. Genere u y v como dos números aleatorios distribuidos uniformemente en el rango de -1 a 1 por
u = 2 r1 - 1yv = 2 r2 - 1

2.calcule w = u^2 + v^2si w> 1 vuelve a 1

3. devuelva u * z e y = v * z con z= sqrt(-2ln(w)/w) un código de ejemplo que se vería así:

u = 2 * random() - 1;
v = 2 * random() - 1;
w = pow(u, 2) + pow(v, 2);
if (w < 1) {
    z = sqrt((-2 * log(w)) / w);
    x = u * z;
    y = v * z;
    }

luego use lo que MHR ha sugerido anteriormente para obtener las desviaciones aleatorias de N(mu, sigma^2).

francogrex
fuente
Cuando publiqué mi respuesta arriba, no noté que @vitalStatistix te dio el algoritmo de transformación Box-Muller. El que doy arriba también es tan bueno, supongo.
francogrex
2
¿Podría explicar la razón para generar variaciones normales a partir de una distribución uniforme (que no sea desde una perspectiva algorítmica) y no solo usando directamente el pdf de una distribución gaussiana / normal? ¿O está totalmente mal?
Arun
44
@Arun Una razón: el método polar de Marsaglia es útil cuando solo tienes un RNG que genera desviaciones uniformes.
chl
1
@Arun es la forma más fácil. También puede generar directamente desde el pdf utilizando, por ejemplo, el método de "rechazo de aceptación". Publiqué para usted un ejemplo simple en mi sitio (porque no hay suficiente espacio en el cuadro de comentarios aquí).
francogrex
4

La distribución normal surge cuando se suman muchos valores aleatorios de distribución similar (es decir, similares entre sí). Si suma diez o más valores aleatorios distribuidos uniformemente, la suma se distribuye casi de manera normal. (Agregue más de diez si desea que sea aún más normal, pero diez es suficiente para casi todos los propósitos).

Supongamos que sus valores aleatorios uniformes se distribuyen uniformemente entre 0 y 1. La suma estará entre 0 y 10. Reste 5 de la suma y la media de la distribución resultante será 0. Ahora divida el resultado por la desviación estándar de la distribución normal (cercana) y multiplique el resultado por la desviación estándar deseada. Desafortunadamente, no estoy seguro de cuál es la desviación estándar de la suma de diez desviaciones aleatorias uniformes, pero si tenemos suerte, alguien nos lo dirá en un comentario.

Prefiero hablar con los estudiantes sobre la distribución normal en estos términos porque la utilidad de la suposición de una distribución normal en muchos sistemas se deriva completamente de la propiedad de que las sumas de muchas influencias aleatorias conducen a una distribución normal.

Michael Lew
fuente
Está utilizando el límite central Thm aquí (que un montón de variables aleatorias iid suman una variable aleatoria normal). No consideré esto porque pensé que sería demasiado lento, ¡¿pero dices que 10 es suficiente ?! ¡Esto es mejor que calcular un registro y un sin / cos y un sqrt!
Fixee
Además, la media del rv uniforme en [0,1] es 0.5 con varianza 1/12. Si sumas 10 de estos, obtienes una media de 5 y una varianza de 10/12 = 5/6.
Fixee
1
Desde un punto de vista pedagógico, este método proporciona una discusión y demostración agradable y útil. Sin embargo, desaconsejaría a cualquiera que use este enfoque en la práctica.
cardenal
1
@Fixee: debe estar seguro y equilibrar el cálculo de Iniciar sesión, pecado, cosy la raíz cuadrada contra la generación de variables aleatorias uniformes adicionales. Por ejemplo, las CPU Intel tienen las cuatro funciones como operaciones integradas que se realizan en hardware. La raíz cuadrada es una operación fundamental "aritmética" de acuerdo con los estándares IEEE 754.
cardenal
1
@Michael: Declarar que proporciona la distribución "correcta" es un poco exagerado, particularmente porque la distribución aproximada tiene un soporte compacto y, en muchas aplicaciones, a uno le importa cuán eficientemente se pueden generar las variaciones. :) El punto es que hay varias opciones mucho mejores disponibles. Pero, sigo pensando que proporciona algo útil pedagógicamente.
Cardenal