Les implémentations de Python random.seed () et numpy.random.seed () diffèrent-elles les unes des autres?

2020-06-02 python numpy matplotlib random random-seed

J'expérimente une différence de distribution de données lors de l'implémentation du CLT (Central Limit Theorem), en comparant deux approches: l'une utilisant du Python pur et l'autre, Numpy.

Voici mon code:

from numpy.random import seed
from numpy.random import randint
from numpy import mean
import matplotlib.pyplot as plt
import random

# [With Numpy]
#
# Generate 1000 samples of 50 men, from 60 to 90 Kilos and calculate the mean
# of each sample, at once.
seed(1)
means = [mean(randint(60, 90, 50)) for _i in range(1000)]

# [Without Numpy]
#
# Generate 1000 samples of 50 men, from 60 to 90 Kilos.
# Calculate the mean of each sample, storing on a separated list.
random.seed(1)
samples = list()
for i in range(0, 1000):
    samples.append([random.randint(60, 90) for n in range(50)])
means_without_numpy = [sum(s) / len(s) for s in samples]

# Plot distributions of sample means, side by side.
plt.subplot(1, 2, 1)
plt.title("Numpy")
plt.hist(means)
plt.subplot(1, 2, 2)
plt.title("Pure Python")
plt.hist(means_without_numpy)
plt.show()

print(f"The mean of means:                 {mean(means)}")
print(f"The mean of means (without numpy): {mean(means_without_numpy)}")   

Ce code produit les histogrammes suivants et un message, après les avoir fermés:

entrez la description de l'image ici

$ python3 clt_comparisson.py 
The mean of means:                74.54001999999998
The mean of means (without numpy): 74.94394

Mes questions sont:

  1. Les distributions (moyennes issues d'ensembles de données aléatoires) sont-elles affectées par la façon dont chaque module ( random et numpy ) fournit des données aléatoires?
  2. Si la première question est vraie: puisque je fournis 1 comme graine, ne devraient-ils pas générer les mêmes jeux de données randomisés, car ils ont la même valeur de graine?

Answers

numpy et python utilisent au random des algorithmes différents, ce qui, je pense, est très attendu pour un paquet de mathématiques écrit en C et fortran. Le même algorithme avec la même graine produira les mêmes valeurs

>>> import random
>>> random.seed(12345678)
>>> import numpy.random
>>> numpy.random.seed(12345678)
>>> random.randint(0, 100000)
94406
>>> numpy.random.randint(0, 100000)
67251

(Pas le même)

Les distributions varieront légèrement entre les deux implémentations, même sur une large plage, car vous ne vous attendez pas à ce que la qualité de l'aléatoire soit exactement égale entre elles. Si vous créiez un deuxième jeu de données dans le même programme sans modifier la valeur de départ, cela varierait un peu, tout comme un jeu de données avec une valeur de départ différente.

On ne fournirait pas sa propre graine dans un environnement cryptographique, mais du côté scientifique, cela peut être utile si vous voulez qu'un modèle soit reproductible. Dans ce cas, numpy.random.RandState votre code sur numpy.random.RandState avec un nombre entier bien connu de 32, de sorte que vous n'ayez pas à vous soucier du programme large numpy.random.seed() dont d'autres peuvent avoir besoin ou peuvent changer.

Related