Python'da numpy.random ve random.random arasındaki farklar


103

Python'da büyük bir betiğim var. Başkalarının kodlarında kendime ilham verdim, bu yüzden numpy.randommodülü bazı şeyler için (örneğin bir iki terimli dağılımdan alınan rastgele sayılar dizisi oluşturmak için) ve modülü kullandığım diğer yerlerde kullandım random.random.

Lütfen birisi bana ikisi arasındaki büyük farkları söyleyebilir mi? Bu ikisinin her biri için doküman web sayfasına baktığımda bana göre numpy.randomdaha fazla metot var, ancak rastgele sayıların oluşumunun nasıl farklı olduğu konusunda emin değilim.

Sormamın nedeni, ana programımı hata ayıklama amacıyla başlatmam gerektiğidir. Ancak içe aktardığım tüm modüllerde aynı rastgele sayı üretecini kullanmazsam işe yaramıyor, bu doğru mu?

Ayrıca burada, başka bir yazıda KULLANMAYIN hakkında bir tartışma okudum numpy.random.seed(), ancak bunun neden bu kadar kötü bir fikir olduğunu gerçekten anlamadım. Biri bana bunun neden böyle olduğunu açıklarsa çok memnun olurum.

Yanıtlar:


124

Şimdiden birçok doğru gözlem yaptınız!

Her iki rastgele üreteci de tohumlamak istemiyorsanız, uzun vadede bir üreteci veya diğerini seçmek muhtemelen daha kolaydır. Ama ikisini de kullanmanız gerekiyorsa, o zaman evet, ikisini de tohumlamanız gerekir, çünkü birbirlerinden bağımsız olarak rastgele sayılar üretirler.

Çünkü numpy.random.seed()temel zorluk, iş parçacığı güvenli olmamasıdır - yani, çok sayıda farklı yürütme evrelerine sahipseniz kullanmak güvenli değildir , çünkü işlevi aynı anda iki farklı iş parçacığı çalıştırıyorsa çalışacağı garanti edilmez. İş parçacığı kullanmıyorsanız ve programınızı gelecekte bu şekilde yeniden yazmanız gerekmeyeceğini makul bir şekilde tahmin edebiliyorsanız, numpy.random.seed()sorun değil. Gelecekte iş parçacıklarına ihtiyacınız olabileceğinden şüphelenmek için herhangi bir neden varsa, önerilenleri yapmak ve numpy.random.Randomsınıfın yerel bir örneğini yapmak uzun vadede çok daha güvenlidir . Anladığım kadarıyla random.random.seed(), iş parçacığı için güvenli (veya en azından, aksine herhangi bir kanıt bulamadım).

numpy.randomKütüphane yaygın bilimsel araştırmalarda kullanılan birkaç ekstra olasılık dağılımlarını yanı sıra rastgele veri dizileri üretmek için kolaylık fonksiyonları bir çift içerir. random.randomKütüphane biraz daha hafif olduğunu ve bilimsel araştırma veya istatistik çalışmalarının diğer tür işin yoksa ince olmalıdır.

Aksi takdirde, her ikisi de rastgele sayılarını oluşturmak için Mersenne twister dizisini kullanırlar ve her ikisi de tamamen deterministiktir - yani, birkaç önemli bilgi biti biliyorsanız, bundan sonra hangi sayının geleceğini kesin olarak tahmin etmek mümkündür . Bu nedenle, ne numpy.random ne de random.random herhangi bir ciddi kriptografik kullanım için uygun değildir . Ancak sıra çok uzun olduğu için, verilerinizi tersine çevirmeye çalışan insanlar için endişelenmediğiniz durumlarda her ikisi de rastgele sayılar oluşturmak için uygundur. Rastgele değeri tohumlama gerekliliğinin nedeni de budur - her seferinde aynı yerden başlarsanız, her zaman aynı rastgele sayı dizisini elde edersiniz!

Eğer bir yan not olarak, do kriptografik düzey rastgeleliğine gerek, kullanmak gerekir sırları gibi modülü, ya da bir şey Crypto.Random bir Python sürümünü önceden Python 3.6 den kullanıyorsanız.


14
Uzaktan ilişkili bir not olarak, bazen Mersenne twister kriptografik (ve bazı olağandışı bilimsel) amaçlar için yeterli rastgele entropi dizileri üretmediğinden, ikisinin de kullanılmaması gerekir. Bu nadir durumlarda, genellikle tek başına elde edilenden çok daha yüksek kalitede deterministik olmayan rastgele diziler oluşturmak için işletim sistemine özgü entropi kaynaklarını kullanabilen Crypto.Random'a ihtiyacınız vardırrandom.random . Yine de genellikle buna ihtiyacınız olmaz.
SingleNegationElimination

Teşekkür ederim Hannnele. Görüşleriniz gerçekten çok faydalı oldu! Görünüşe göre SADECE tek bir rasgele sayı üreteci kullanmaktan kurtulamıyorum (rasgele iki terimli dağılımlar üretmediği için uyuşması gerekiyor) çünkü programımın bazı bölümleri rasgele kullanan başka bir programı çağırıyor. İki jeneratörü tohumlamam gerekecek.
Laura

2
"Şu anda hangi numaraya sahip olduğunuzu biliyorsanız, bundan sonra hangi sayının geleceğini kesin olarak tahmin etmek mümkündür." Bu ifadenin biraz açıklamaya ihtiyacı olabileceğini düşünüyorum. Yani , jeneratörün iç durumunu biliyorsanız , diziyi yeniden üretebilirsiniz - jeneratörü tohumladığınızda yaptığınız şey budur. Jeneratörden tek bir sayı çıktısı verildiğinde, bir sonraki sayıyı tahmin edemezsiniz. Periyot o kadar büyük ki, sözde rastgele dizide nerede olduğunuzu hesaplamak ve böylece bir sonrakini tahmin etmek için muhtemelen uzun bir sayı dizisine ihtiyacınız olacaktır.
Kaushik Ghose

12

Gönderen Veri Analizi Python , modül numpy.randomPython tamamlayan randomverimli olasılık dağılımları birçok türde örnek değerlerin tüm diziler oluşturmak için fonksiyonları ile.

Bunun aksine, Python'un yerleşik randommodülü bir seferde yalnızca bir değeri örneklerken, numpy.randomçok büyük örnekleri daha hızlı oluşturabilir. IPython sihirli işlevini kullanarak %timeithangi modülün daha hızlı performans gösterdiğini görebilirsiniz:

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

1
Diğer yöntemler için durum böyle değil. kıyasla np.random.randint(2)ile random.randrange(2)ve NumPy olarak daha yavaş bir . NumPy: 1.25 us ve Random: 891 ns. Ve ayrıca aynı ilişki np.random.rand()ve random.random().
Shayan Amani

3

Tohumun kaynağı ve kullanılan dağıtım profili çıktıları etkileyecektir - eğer şifreli rasgelelik arıyorsanız, os.urandom () 'dan tohumlama, aygıt titreşimlerinden (yani ethernet veya disk) neredeyse gerçek rastgele baytlar alacaktır (yani / BSD üzerinde geliştirici / rastgele)

bu, bir tohum vermenizi ve böylece belirleyici rastgele sayılar üretmenizi önleyecektir. Bununla birlikte, rastgele çağrılar daha sonra sayıları bir dağılıma sığdırmanıza izin verir (ben bilimsel rastgele olma diyorum - sonunda tek istediğiniz rastgele sayıların çan eğrisi dağılımıdır, numpy bunu en iyi şekilde çözmektir.

Öyleyse evet, tek bir jeneratör ile çalışın, ancak hangi rastgele istediğinize karar verin - rastgele, ancak bir dağılım eğrisinden tam anlamıyla veya bir kuantum cihazı olmadan alabileceğiniz kadar rastgele.


Çok teşekkür ederim Paul, cevabın gerçekten faydalı oldu! Kriptografik rastgelelik aramıyorum, matematiksel modelleme yapıyorum ve sözde rastgele sayılar benim için yeterli. Görünüşe göre iki terimli dağılım için uyuşukluğa ihtiyacım olduğu ve programım rastgele kullanan başka bir programı çağırdığı için bir jeneratöre istediğim gibi yapışamıyorum :(
Laura
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.