semilla aleatoria numpy

Deje de usar la semilla aleatoria global de NumPy

En su lugar, establezca semillas aleatorias para clases individuales en Python. Así es cómo.

El uso np.random.seed(number)ha sido una práctica recomendada al usar NumPy para crear un trabajo reproducible. Establecer la semilla aleatoria significa que su trabajo es reproducible para otros que usan su código. Pero ahora, cuando miras los documentos de np.random.seed, la descripción dice:

Esta es una función heredada conveniente.

La mejor práctica es no reinicializar un BitGenerator, sino recrear uno nuevo. Este método está aquí solo por razones heredadas.

Entonces, ¿qué ha cambiado? Voy a explicar el método antiguo y los problemas con él . Luego demostraré la nueva mejor práctica y sus beneficios.

Deje de usar la semilla aleatoria global de NumPy: este es el motivo

El uso de np.random.seed(number) establece lo que NumPy llama la semilla aleatoria global, que afecta todos los usos del módulo np.random.*. Algunos paquetes importados u otras secuencias de comandos podrían restablecer la semilla aleatoria global a otra semilla aleatoria con np.random.seed(another_number), lo que puede generar cambios no deseados en su salida y que sus resultados se vuelvan irreproducibles.

Mejores prácticas heredadas

Si busca tutoriales usando np.random, verá que muchos de ellos se usan np.random.seedpara configurar la semilla para un trabajo reproducible. Podemos ver cómo funciona esto:

>>> import numpy as np

>>> import numpy as np
>>> np.random.rand(4)
array([0.96176779, 0.7088082 , 0.06416725, 0.82679036])

>>> np.random.rand(4)
array([0.15051909, 0.77788803, 0.67073372, 0.32134285])

Como puede ver, dos llamadas a la función conducen a dos respuestas completamente diferentes. Si desea que alguien pueda reproducir sus proyectos, puede configurar la semilla con el siguiente fragmento de código:

>>> np.random.seed(2021)
>>> np.random.rand(4)
array([0.60597828, 0.73336936, 0.13894716, 0.31267308])


>>> np.random.seed(2021)
>>> np.random.rand(4)
array([0.60597828, 0.73336936, 0.13894716, 0.31267308])

Verás que los resultados son los mismos. Si necesita probar esto por sí mismo, puede ingresar el código anterior en su configuración de Python.

Establecer la semilla significa que la siguiente llamada aleatoria es la misma; establece la secuencia de números aleatorios de modo que cualquier código que produzca o use números aleatorios (con NumPy) ahora producirá la misma secuencia de números. Por ejemplo, mira lo siguiente:

>>> np.random.seed(2021)
>>> np.random.rand(4)
array([0.60597828, 0.73336936, 0.13894716, 0.31267308])
>>> np.random.rand(4)
array([0.99724328, 0.12816238, 0.17899311, 0.75292543])
>>> np.random.rand(4)
array([0.66216051, 0.78431013, 0.0968944 , 0.05857129])
>>> np.random.rand(4)
array([0.96239599, 0.61655744, 0.08662996, 0.56127236])
>>> np.random.seed(2021)
>>> np.random.rand(4)
array([0.60597828, 0.73336936, 0.13894716, 0.31267308])
>>> np.random.rand(4)
array([0.99724328, 0.12816238, 0.17899311, 0.75292543])
>>> np.random.rand(4)
array([0.66216051, 0.78431013, 0.0968944 , 0.05857129])
>>> np.random.rand(4)
array([0.96239599, 0.61655744, 0.08662996, 0.56127236])

Más de nuestros expertos en Python: 5 formas de escribir más código pitónico

El problema con la semilla aleatoria global de NumPy

Es posible que esté mirando el ejemplo anterior y pensando, «¿cuál es el problema?» Puede crear llamadas reproducibles, lo que significa que todos los números aleatorios generados después de configurar la semilla serán los mismos en cualquier máquina. En su mayor parte, esto es cierto; y para muchos proyectos, es posible que no tenga que preocuparse por esto.

El problema viene en proyectos más grandes o proyectos con importaciones que también podrían poner la semilla. El uso np.random.seed(number)establece lo que NumPy llama la semilla aleatoria global , que afecta todos los usos del np.random.*módulo. Algunos paquetes importados u otras secuencias de comandos podrían restablecer la semilla aleatoria global a otra semilla aleatoria con np.random.seed(another_number), lo que puede provocar cambios no deseados en su salida y que sus resultados se vuelvan irreproducibles. En su mayor parte, solo deberá asegurarse de usar los mismos números aleatorios para partes específicas de su código (como pruebas o funciones).

Método de semilla aleatoria NumPy en Python

tu mama no trabaja aqui: Científicos de datos, sus nombres de variables son un desastre. Limpie su código.

La solución y el nuevo método

Esta es una de las razones por las que NumPy ha pasado a aconsejar a los usuarios que creen un generador de números aleatorios para tareas específicas (o incluso para pasar cuando necesite que las partes sean reproducibles).

«La mejor práctica preferida para obtener números pseudoaleatorios reproducibles es crear una instancia de un objeto generador con una semilla y pasarla». —Robert Kern, NEP19

El uso de esta nueva práctica recomendada se ve así :

import numpy as np
>>> rng = np.random.default_rng(2021)
>>> rng.random(4)
array([0.75694783, 0.94138187, 0.59246304, 0.31884171])

Como puede ver, estos números son diferentes del ejemplo anterior porque NumPy ha cambiado el generador de números pseudoaleatorios predeterminado. Sin embargo, puede replicar los resultados anteriores utilizando RandomState, que es un generador de métodos heredados antiguos.

>>> rng = np.random.RandomState(2021)
>>> rng.rand(4)
array([0.60597828, 0.73336936, 0.13894716, 0.31267308])

Más ayuda de Python: 4 herramientas Python para simplificar tu vida

Los beneficios

Puede pasar generadores de números aleatorios entre funciones y clases, lo que significa que cada individuo o función podría tener su propio estado aleatorio sin restablecer la semilla global. Además, cada script podría pasar un generador de números aleatorios a funciones que deben ser reproducibles. El beneficio es que sabe exactamente qué generador de números aleatorios se usa en cada parte de su proyecto.

def f(x, rng): return rng.random(1)
#Intialise a random number generator
rng = np.random.default_rng(2021)
#pass the rng to functions which you would like to use it
random_number = f(x, rng)

Otros beneficios surgen con el procesamiento paralelo, como nos muestra Albert Thomas. 

El uso de generadores de números aleatorios independientes puede ayudar a mejorar la reproducibilidad de sus resultados. Puede hacer esto al no confiar en el estado aleatorio global (que se puede restablecer o usar sin saberlo). Pasar un generador de números aleatorios significa que puede realizar un seguimiento de cuándo y cómo se usó y asegurarse de que sus resultados sean los mismos.