Różnice między numpy.random i random.random w Pythonie

100

Mam duży skrypt w Pythonie. Zainspirowałem się kodem innych ludzi, więc ostatecznie wykorzystałem numpy.randommoduł do niektórych rzeczy (na przykład do stworzenia tablicy liczb losowych wziętych z rozkładu dwumianowego), aw innych miejscach używam modułu random.random.

Czy ktoś może mi powiedzieć, jakie są główne różnice między nimi? Patrząc na stronę internetową dokumentu dla każdego z nich, wydaje mi się, że numpy.randomma po prostu więcej metod, ale nie jestem pewien, jak różni się generowanie liczb losowych.

Powodem, dla którego pytam, jest to, że muszę umieścić mój główny program w celu debugowania. Ale to nie działa, chyba że używam tego samego generatora liczb losowych we wszystkich modułach, które importuję. Czy to prawda?

Przeczytałem również tutaj, w innym poście, dyskusję o NIE używaniu numpy.random.seed(), ale tak naprawdę nie rozumiałem, dlaczego to był taki zły pomysł. Byłbym bardzo wdzięczny, gdyby ktoś wyjaśnił mi, dlaczego tak jest.

Laura
źródło

Odpowiedzi:

120

Dokonałeś już wielu poprawnych obserwacji!

O ile nie chcesz wysiewać obu losowych generatorów, na dłuższą metę prawdopodobnie łatwiej będzie wybrać jeden lub drugi generator. Ale jeśli musisz użyć obu, to tak, musisz również zasiać oba, ponieważ generują liczby losowe niezależnie od siebie.

Ponieważ numpy.random.seed()główna trudność polega na tym, że nie jest bezpieczny dla wątków - to znaczy, że nie jest bezpieczny w użyciu, jeśli masz wiele różnych wątków wykonania , ponieważ nie ma gwarancji, że zadziała, jeśli dwa różne wątki wykonują funkcję w tym samym czasie. Jeśli nie używasz wątków i możesz rozsądnie oczekiwać, że nie będziesz musiał przepisywać swojego programu w ten sposób w przyszłości, numpy.random.seed()powinno być dobrze. Jeśli istnieje jakikolwiek powód, by podejrzewać, że możesz potrzebować wątków w przyszłości, na dłuższą metę znacznie bezpieczniej jest postępować zgodnie z sugestią i utworzyć lokalną instancję numpy.random.Randomklasy . O ile wiem, random.random.seed()jest bezpieczny dla wątków (a przynajmniej nie znalazłem żadnych dowodów przeciwnych).

numpy.randomBiblioteka zawiera kilka dodatkowych rozkładów prawdopodobieństwa powszechnie wykorzystywane w badaniach naukowych, a także kilka funkcji wygoda dla generowania tablic losowych danych. random.randomBiblioteka jest trochę bardziej lekki i powinno być w porządku, jeśli nie robisz badań naukowych lub innych rodzajów prac w statystykach.

W przeciwnym razie obaj używają sekwencji twistera Mersenne'a do generowania swoich liczb losowych i oba są całkowicie deterministyczne - to znaczy, jeśli znasz kilka kluczowych informacji, można z absolutną pewnością przewidzieć, jaka liczba będzie następna . Z tego powodu ani numpy.random, ani random.random nie nadają się do poważnych zastosowań kryptograficznych . Ale ponieważ sekwencja jest tak bardzo długa, obie są dobre do generowania liczb losowych w przypadkach, gdy nie martwisz się, że ludzie próbują odtworzyć twoje dane. Stąd też konieczność zasiania losowej wartości - jeśli zaczniesz za każdym razem w tym samym miejscu, zawsze otrzymasz tę samą sekwencję liczb losowych!

Na marginesie, jeśli nie potrzebujemy poziom losowości kryptograficznych, należy użyć tajemnice moduł lub coś podobnego Crypto.Random jeśli używasz wersji Pythona wcześniej niż Python 3.6.

Hannele
źródło
14
Co więcej, czasami konieczne jest użycie żadnego z nich , ponieważ twister Mersenne nie wytwarza przypadkowych sekwencji entropii wystarczających do celów kryptograficznych (i niektórych niezwykłych naukowych). W tych rzadkich przypadkach często potrzebujesz Crypto.Random , który jest w stanie wykorzystać źródła entropii specyficzne dla systemu operacyjnego do generowania niedeterministycznych losowych sekwencji o znacznie wyższej jakości niż jest dostępna random.randomsamodzielnie. Jednak zwykle tego nie potrzebujesz.
SingleNegationElimination
Dziękuję Hannnele. Twoje spostrzeżenia były naprawdę bardzo przydatne! Okazuje się, że nie mogę uciec z użyciem TYLKO jednego generatora liczb losowych (który musi być numpy, ponieważ losowy nie tworzy rozkładów dwumianowych), ponieważ część mojego programu wywołuje inny program, który używa losowego. Będę musiał obsiać dwa generatory.
Laura
2
„jeśli wiesz, jaki numer masz teraz, możesz z absolutną pewnością przewidzieć, jaka liczba będzie następna”. Myślę, że to stwierdzenie może wymagać wyjaśnienia. Chodzi o to, że jeśli znasz stan wewnętrzny generatora, możesz odtworzyć sekwencję - co robisz, gdy zasiewasz generator. Biorąc pod uwagę pojedynczą liczbę wyjściową z generatora, nie można przewidzieć następnej liczby. Okres jest tak duży, że prawdopodobnie będziesz potrzebować długiej sekwencji liczb, zanim będziesz mógł obliczyć, gdzie jesteś w pseudolosowej sekwencji, a tym samym przewidzieć następną.
Kaushik Ghose
12

Począwszy od Pythona do analizy danych , moduł numpy.randomuzupełnia Python randomo funkcje do wydajnego generowania całych tablic wartości przykładowych z wielu rodzajów rozkładów prawdopodobieństwa.

Z kolei wbudowany randommoduł Pythona próbkuje tylko jedną wartość na raz, podczas gdy numpy.randommoże szybciej generować bardzo duże próbki. Korzystając z magicznej funkcji IPythona, %timeitmożna zobaczyć, który moduł działa szybciej:

In [1]: from random import normalvariate
In [2]: N = 1000000

In [3]: %timeit samples = [normalvariate(0, 1) for _ in xrange(N)]
1 loop, best of 3: 963 ms per loop

In [4]: %timeit np.random.normal(size=N)
10 loops, best of 3: 38.5 ms per loop
lmiguelvargasf
źródło
1
Nie dotyczy to innych metod. w porównaniu np.random.randint(2)z random.randrange(2)NumPy był wolniejszy . NumPy: 1,25 nas i losowo: 891 ns. A także ta sama relacja dla np.random.rand()i random.random().
Shayan Amani
3

Źródło ziarna i używany profil dystrybucji będą miały wpływ na wyniki - jeśli szukasz kryptograficznej losowości, seeding z os.urandom () otrzyma prawie rzeczywiste losowe bajty z rozmowy urządzenia (tj. Ethernet lub dysk) (tj. / dev / random na BSD)

pozwoli to uniknąć podania ziarna, a tym samym generowania deterministycznych liczb losowych. Jednak losowe wywołania pozwalają następnie dopasować liczby do rozkładu (to, co nazywam naukową losowością - ostatecznie wszystko, czego chcesz, to rozkład krzywej dzwonowej liczb losowych, numpy jest najlepszy w osiągnięciu tego.

WIĘC tak, trzymaj się jednego generatora, ale zdecyduj, jaki chcesz losowy - losowy, ale zdecydowanie na podstawie krzywej zniekształcenia lub tak losowy, jak możesz uzyskać bez urządzenia kwantowego.

proszę pana - weź to
źródło
Dziękuję bardzo Paul, twoja odpowiedź była naprawdę przydatna! Nie szukam kryptograficznej losowości, zajmuję się modelowaniem matematycznym i wystarczą mi liczby pseudolosowe. Okazuje się, że nie mogę trzymać się jednego generatora tak, jak chciałem, ponieważ potrzebuję numpy do rozkładu dwumianowego, a mój program wywołuje inny program, który używa losowego :(
Laura