[PYTHON] Essayez le générateur de numpy.random

Ceci est le premier message.

NumPy v1.18 est sorti fin mai 2020. J'ai donc relu le document et j'ai remarqué qu'avant de le savoir, une nouvelle classe appelée Generator avait été ajoutée au module numpy.random qui était pris en charge dans les statistiques / apprentissage automatique, et je connaissais jusqu'à présent numpy. Il semble que des fonctions telles que .random.random soient obsolètes.

De plus, ce changement semble avoir été effectué dans NumPy 1.17. La faiblesse que je remarque maintenant ...

https://numpy.org/doc/1.17/reference/random/index.html

Personnellement, je pensais que c'était un grand changement, alors j'aimerais garder une trace de ce qui a changé depuis que j'ai écrit le mémo.

Les articles suivants sont basés sur la documentation NumPy v1.18.

Nouvel échantillonnage aléatoire

Jusqu'à présent, selon la documentation NumPy

from numpy.random import random

random(100)

Au lieu du code d'échantillonnage aléatoire que j'ai écrit, dans la version 1.17 ou ultérieure

from numpy.random import default_rng

rg = default_rng()
rg.random(100)

Est recommandé. C'est un peu orienté objet.

À propos, lors de la mise en place de la graine, cela devient comme ça.

from numpy.random default_rng

rg = default_rng(123)
rg.random(100)

Voici l'ancien code qui correspond à cela.

from numpy.random import RandomState, random, seed

rg = RandomState(123)
rg.random(100)

#Lors de la définition d'une graine globale
seed(123)
random(100)

Avantages de la nouvelle méthode

Quand j'ai vu cela, j'ai pensé: "Le nombre de lignes a été réduit", "Qu'est-ce que default_rng," et "A quoi sert ce genre d'utilisation?", Mais il y a plusieurs avantages. il semble que.

Avantage 1: Rapide

Tout d'abord, c'est rapide et efficace. Dans mon environnement PC

In [1]: from numpy.random import standard_normal, default_rng

In [2]: rg = default_rng()

In [3]: %%timeit
   ...: rg.standard_normal(1000000)  # newer 
   ...:  
   ...:                                                                         
24.8 ms ± 709 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [4]: %%timeit
   ...: standard_normal(1000000)  # older
   ...:                                                                         
52.4 ms ± 835 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

Le résultat était que. Le temps d'exécution est divisé par deux!

La raison en est que le générateur de nombres aléatoires utilisé en interne a changé. Avant la v1.16, Mercenne Twister était utilisé comme générateur de nombres aléatoires, mais après la v1.17, un générateur de nombres aléatoires appelé PCG est utilisé.

PCG est un générateur de nombres aléatoires annoncé en 2014, et il semble qu'il puisse générer des nombres pseudo-aléatoires avec de bonnes propriétés rapidement et efficacement. Je ne suis pas familier avec cela, donc si vous êtes intéressé, veuillez visiter Wikipedia ou Official Page. Vérifie s'il te plaît. Commentaire qiita J'attends un article.

Avantage 2: vous pouvez choisir un générateur de nombres aléatoires

Avant la v1.16, seul Mercenne Twister pouvait être utilisé comme générateur de nombres aléatoires. Il n'y avait pas de choix là-bas. Peut-être qu'un magicien qui peut utiliser le langage C aurait pu réussir à le faire, mais pour un utilisateur final comme moi qui est stupide et pathétique et ne peut pas comprendre pleinement le langage C, la Mercenne donnée Je ne pouvais utiliser qu'un outil appelé twister.

Cependant, c'est différent après la v1.17.

Depuis la v1.17, nous avons le droit de choisir un générateur de nombres aléatoires. En plus du PCG par défaut, nous pouvons utiliser le nostalgique Mercenne Twister, et nous pouvons choisir parmi plusieurs autres randomiseurs.

Les mécanismes clés sont "Generator" et "BitGenerator".

(Bit) Generator est ce que

La classe BitGenerator semble être comme une classe abstraite pour les générateurs aléatoires comme PCG et Mercenne Twister (compréhension duveteuse). Avec NumPy, les générateurs pseudo-aléatoires tels que «PCG64», «MT19937», «Philox» et «SFC64» peuvent être utilisés comme des sous-classes de «BitGenerator».

Je ne l'ai pas essayé, mais vous devriez probablement pouvoir créer et utiliser un générateur de nombres aléatoires personnalisé en étendant la classe BitGenerator. Vous l'avez fait Python-chan! Les nombres aléatoires vont augmenter!

Et la classe «Generator» est responsable de la connexion de ce «BitGenerator» à une distribution de probabilité spécifique telle qu'une distribution uniforme ou une distribution normale.

Les fonctions familières telles que «random» et «normal» se développent dans les méthodes de la classe «Generator». Il existe également des fonctions de distribution de probabilité maniaques comme «gumbel» et «weibull». Je suis heureux.

Maintenant, créons un nombre aléatoire en utilisant Generator.

from numpy.random import Generator, PCG64, MT19937

#Utilisez PCG pour le randomiseur
rg_pcg = Generator(PCG64())
rg_pcg.random(100)

#Utilisez Mercenne Twister comme randomiseur
rg_mt = Generator(MT19937())
rg_mt.random(100)

default_rng est ce que

Le default_rng qui apparaît plus tôt est le constructeur du Generator qui utilise le PCG64 comme randomiseur.

Jetons un œil à la documentation en IPython.

In [1]: default_rng?
Docstring:
Construct a new Generator with the default BitGenerator (PCG64).

C'est pourquoi le code ci-dessous est pratiquement le même.

# default_version rng(Avec graine)
rg = default_rng(123)

#Version du générateur(Avec graine)
rg = Generator(PCG64(123))

C'était un rattrapage un an après la sortie de la v1.17 en raison de ma faiblesse, mais j'espère que cela aide.

Bonne vie en Python!

Recommended Posts

Essayez le générateur de numpy.random
Générateur
Générateur
Essayez Python
essayez pysdl2
Mémo du générateur.
Essayez PyOpenGL