establecer el programa de semillas aleatorias en todo el programa

82

Tengo un programa bastante grande, donde uso funciones del randommódulo en diferentes archivos. Me gustaría poder establecer la semilla aleatoria una vez, en un lugar, para que el programa siempre devuelva los mismos resultados. ¿Se puede lograr eso en python?

Mischa Obrecht
fuente

Respuestas:

116

El módulo principal de Python que se ejecuta debería import randomy llamar random.seed(n): esto se comparte entre todas las demás importaciones randomsiempre que en otro lugar no restablezca la semilla.

Jon Clements
fuente
3
¿Podría estar restableciendo la semilla en algún lugar sin saberlo? porque establecer la semilla una vez en el archivo principal, no funciona
Mischa Obrecht
1
@MischaObrecht Supongo que sí: la semilla solo se inicializa en la primera importación del módulo aleatorio; si se importa más de una vez, no realizará la inicialización ni restablecerá la semilla, por lo que debe haber una llamada explícita en algún lugar de su código
Jon Clements
3
Si está llamando a métodos desde el randomcódigo de nivel de módulo, que está importando en main, antes de llegar a random.seed(n)in main, entonces esas llamadas se realizarán antes de la semilla, por lo que serán sembradas en el tiempo y de manera efectiva no reproducible. aleatorio.
Russell Borogove
12
Si resulta que algún código de terceros está reiniciando el RNG (poco probable pero posible), tenga en cuenta que puede crear generadores de números aleatorios adicionales con un estado independiente a través del random.Random()constructor y utilizarlos cuando la reproducibilidad estricta sea importante.
Russell Borogove
Esto no funciona para mi. Y no tengo un código reproducible. Supongo que tendré que verificar la documentación de todas las bibliotecas importadas ... (ver stackoverflow.com/questions/37886997/…
B Furtado
36

El comentario de zss debe resaltarse como una respuesta real:

Otra cosa con la que la gente debe tener cuidado: si está usando numpy.random, entonces debe usar numpy.random.seed()para establecer la semilla. El uso random.seed()no establecerá la semilla para números aleatorios generados a partir de numpy.random. Esto me confundió por un tiempo. -zss

Sida Zhou
fuente
Absolutamente cierto, si en algún lugar de su aplicación está utilizando números aleatorios de random module, digamos, función random.choices()y luego más abajo en algún otro punto el numpygenerador de números aleatorios, digamos np.random.normal()que tiene que establecer la semilla para ambos módulos. Lo que suelo hacer es tener un par de líneas en mi me main.pygusta random.seed(my_seed)y np.random.seed(my_seed). Felicitaciones a zss
Aenaon
Sage tiene un problema similar, ya que su PRNG es distinto de Python y numpy. Usar set_random_seed()para Sage.
Brent Baccala
8

Al comienzo de su aplicación, llame random.seed(x)para asegurarse de que x sea siempre el mismo. Esto asegurará que la secuencia de números pseudoaleatorios sea la misma durante cada ejecución de la aplicación.

Quimera
fuente
3

Jon Clements prácticamente responde a mi pregunta. Sin embargo, no fue el problema real: resulta que la razón de la aleatoriedad de mi código fue el numpy.linalg SVD porque no siempre produce los mismos resultados para matrices mal acondicionadas.

¡Así que asegúrese de verificar eso en su código, si tiene los mismos problemas!

Mischa Obrecht
fuente
22
Otra cosa con la que la gente debe tener cuidado: si está usando numpy.random, entonces necesita usar numpy.random.seed () para establecer la semilla. El uso de random.seed () no establecerá la semilla para números aleatorios generados a partir de numpy.random. Esto me confundió por un tiempo.
zss
1

Basándose en respuestas anteriores: tenga en cuenta que muchas construcciones pueden divergir en las rutas de ejecución, incluso cuando todas las semillas están controladas.

Estaba pensando " bueno, puse mis semillas para que sean siempre las mismas, y no tengo dependencias externas / cambiantes, por lo tanto, la ruta de ejecución de mi código siempre debería ser la misma ", pero eso está mal.

El ejemplo que me mordió fue list(set(...)), donde el orden resultante puede diferir.

JBSnorro
fuente
Buen punto, esto me quemó antes. También cosas como obtener resultados de una base de datos, también regresan fuera de orden (al azar) a menos que especifique lo contrario
Justin Furuness
-14

Puede garantizar esto con bastante facilidad utilizando su propio generador de números aleatorios.

Simplemente elija tres números primos grandes (asumiendo que esta no es una aplicación de criptografía) y conéctelos a a, byc: a = ((a * b)% c) Esto le da un sistema de retroalimentación que produce datos bastante aleatorios. Tenga en cuenta que no todos los números primos funcionan igual de bien, pero si solo está haciendo una simulación, no debería importar; todo lo que realmente necesita para la mayoría de las simulaciones es una mezcla de números con un patrón (pseudoaleatorio, recuerde) lo suficientemente complejo como para no coincide de alguna manera con su aplicación.

Knuth habla de esto.

usuario1277476
fuente
10
No es necesario utilizar el tuyo propio, porque Python tiene excelentes funciones de números aleatorios en su biblioteca estándar, y es muy fácil crear un generador realmente malo si no sabes lo que estás haciendo.
Russell Borogove
6
Estoy de acuerdo en que es una solución bastante mala: en las simulaciones de Monte Carlo (que es lo que es mi programa), donde uno generalmente recolecta millones de muestras, los números aleatorios correlacionados (derivados de un mal generador) pueden estropear fácilmente sus resultados.
Mischa Obrecht
¿Quieres decir que Knuth está hablando de esto todo el tiempo? ¿Incluso ahora?
significa-a-significado