[PYTHON] Try numpy.random Generator

This is the first post.

NumPy v1.18 was released at the end of May 2020. So I read the documentation again and noticed that before I knew it, a new class called Generator was added to the numpy.random module that was taken care of in statistics / machine learning, and I was familiar with numpy. It seems that functions such as .random.random have been deprecated.

Moreover, this change seems to have been made in NumPy 1.17. The weakness that I notice now ...

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

Personally, I thought it was a big change, so I would like to keep track of what has changed since I took notes.

The following articles are based on the NumPy v1.18 documentation.

New random sampling

So far, according to the NumPy documentation

from numpy.random import random

random(100)

Instead of the random sampling code that I wrote, in v1.17 or later

from numpy.random import default_rng

rg = default_rng()
rg.random(100)

Is recommended. It's kind of object-oriented.

By the way, when setting the seed, it becomes like this.

from numpy.random default_rng

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

Here's the old code that corresponds to this.

from numpy.random import RandomState, random, seed

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

#When setting a global seed
seed(123)
random(100)

Benefits of the new method

When I saw this, I thought, "The number of lines has been reduced," "What is default_rng, "and" What is this kind of use for? ", But there are some advantages. it seems like.

Benefit 1: Fast

First, it's fast and efficient. In my PC environment,

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)

The result was that. The execution time is halved!

The reason for this seems to be that the random number generator used internally has changed. Before v1.16, Mersenne Twister was used as a random number generator, but after v1.17, a random number generator called PCG is used.

PCG is a random number generator announced in 2014, and it seems that it can generate pseudo-random numbers that are fast, efficient, and have good properties. I'm not familiar with it, so if you are interested, please visit Wikipedia or Official Page. Please check it out. Commentary qiita article is waiting.

Advantage 2: Random number generator can be selected

Prior to v1.16, only Mersenne Twister could be used as a random number generator. There was no choice there. Perhaps a magician who can use C could have managed to do it, but for one end user like me who is stupid and pathetic and cannot fully understand C, the Mersenne Twister was given. I could only use a tool called Twister.

However, it is different after v1.17.

Since v1.17 we have been given the right to choose a random number generator. In addition to the default PCG, we can use the nostalgic Mersenne Twister, and we can choose from several other random number generators.

The key mechanisms are Generator and BitGenerator.

(Bit) Generator is what

The BitGenerator class seems to be like an abstract class of random number generators like PCG and Mersenne Twister (fluffy understanding). With NumPy, pseudo-random number generators such as PCG64, MT19937, Philox, and SFC64 can be used like subclasses of BitGenerator.

I haven't tried it, but you should probably be able to create and use a custom random number generator by inheriting the BitGenerator class. You did it Python-chan! Random numbers will increase!

And the Generator class is responsible for connecting this BitGenerator to a specific probability distribution such as a uniform distribution or a normal distribution.

Familiar functions such as random and normal grow in the methods of the Generator class. There are also some maniac probability distribution functions like gumbel and weibull. I'm happy.

Now, let's actually create a random number using Generator.

from numpy.random import Generator, PCG64, MT19937

#Use PCG for random number generator
rg_pcg = Generator(PCG64())
rg_pcg.random(100)

#Use Mersenne Twister as a random number generator
rg_mt = Generator(MT19937())
rg_mt.random(100)

default_rng is what

The default_rng that appears earlier is the constructor for the Generator that uses the PCG64 as the random number generator.

Let's take a look at the documentation in IPython.

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

That's why the code below is essentially the same.

# default_rng version(With seed)
rg = default_rng(123)

#Generator version(With seed)
rg = Generator(PCG64(123))

It was a catch-up one year after v1.17 was released due to my weakness, but I hope it helps.

Have a good Python life!

Recommended Posts

Try numpy.random Generator
generator
Generator
Try python
try pysdl2
Generator memo.
Try PyOpenGL