Numpy.random.seed (0) ne yapıyor?


282

np.random.seedBir Scikit-Learn öğreticisinden aşağıdaki kodda ne işe yarar? NumPy'nin rastgele durum üreteci malzemelerine pek aşina değilim, bu yüzden bir layman'ın bunun açıklamalarını gerçekten takdir ediyorum.

np.random.seed(0)
indices = np.random.permutation(len(iris_X))

Yanıtlar:


557

np.random.seed(0) rastgele sayıları öngörülebilir yapar

>>> numpy.random.seed(0) ; numpy.random.rand(4)
array([ 0.55,  0.72,  0.6 ,  0.54])
>>> numpy.random.seed(0) ; numpy.random.rand(4)
array([ 0.55,  0.72,  0.6 ,  0.54])

Tohum sıfırlama ile (her seferinde), her seferinde aynı sayı kümesi görünecektir.

Rastgele tohum sıfırlanmazsa, her çağrıda farklı sayılar görünür:

>>> numpy.random.rand(4)
array([ 0.42,  0.65,  0.44,  0.89])
>>> numpy.random.rand(4)
array([ 0.96,  0.38,  0.79,  0.53])

(sözde-) rasgele sayılar, bir sayıyla (tohum) başlayarak, büyük bir sayıyla çarparak, bir ofset ekleyerek ve sonra bu toplamın modulo'sunu alarak çalışır. Elde edilen sayı daha sonra bir sonraki "rastgele" sayıyı üretmek için tohum olarak kullanılır. Tohumu ayarladığınızda (her seferinde), her seferinde aynı şeyi yapar ve size aynı sayıları verir.

Görünüşte rastgele sayılar istiyorsanız, tohumu ayarlamayın. Bununla birlikte, hata ayıklamak istediğiniz rasgele sayılar kullanan bir kodunuz varsa, her çalıştırmadan önce tohumun ayarlanması çok yararlı olabilir, böylece kod her çalıştırıldığında aynı şeyi yapar.

Her çalışma için en rastgele sayıları almak için arayın numpy.random.seed(). Bu , numpy'nin tohumu /dev/urandomveya Windows analoğundan elde edilen rastgele bir sayıya ayarlamasına veya bunların hiçbiri yoksa saati kullanmasına neden olur.

Sahte rasgele sayılar üretmek için tohumları kullanma hakkında daha fazla bilgi için bkz. Wikipedia .


86
Bu cevap numpy belgelerine eklenmelidir. Teşekkür ederim.
gorjanz

8
Ayrıca, aradığınızda numpy.random.seed(None)"/ dev / urandom'dan (veya Windows analogundan) verileri okumaya çalışacak veya aksi takdirde saatten çekilecektir".
Jonathan

1
@Jonathan Hakkında mükemmel bir nokta numpy.random.seed(None). Cevabı bu bilgilerle ve dokümanlar için bir bağlantıyla güncelledim.
John1024

@ curio1729 Uygulama bir işletim sisteminden diğerine değişebilir, ancak numpy komutlarını seeduyumlu hale getirmeye çalışır .
John1024

1
@ L3viathan İyi bir nokta! Daha eksiksiz ve doğru olmak için, bir ofset eklendiğinden bahsetmeliydim. Yanıt güncellendi. Daha fazla ayrıntı isteyenler için, wikipedia'nın sözde rasgele sayı üreteçleri tartışmasına bir bağlantı ekledim.
John1024

38

Ayarlarsanız np.random.seed(a_fixed_number)size numpy diğer rasgele işlevi çağırmak her zaman, sonuç aynı olacak:

>>> import numpy as np
>>> np.random.seed(0) 
>>> perm = np.random.permutation(10) 
>>> print perm 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.permutation(10) 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.permutation(10) 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.permutation(10) 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.rand(4) 
[0.5488135  0.71518937 0.60276338 0.54488318]
>>> np.random.seed(0) 
>>> print np.random.rand(4) 
[0.5488135  0.71518937 0.60276338 0.54488318]

Bununla birlikte, sadece bir kez çağırır ve çeşitli rastgele işlevler kullanırsanız, sonuçlar yine de farklı olacaktır:

>>> import numpy as np
>>> np.random.seed(0) 
>>> perm = np.random.permutation(10)
>>> print perm 
[2 8 4 9 1 6 7 3 0 5]
>>> np.random.seed(0) 
>>> print np.random.permutation(10)
[2 8 4 9 1 6 7 3 0 5]
>>> print np.random.permutation(10) 
[3 5 1 2 9 8 0 6 7 4]
>>> print np.random.permutation(10) 
[2 3 8 4 5 1 0 6 9 7]
>>> print np.random.rand(4) 
[0.64817187 0.36824154 0.95715516 0.14035078]
>>> print np.random.rand(4) 
[0.87008726 0.47360805 0.80091075 0.52047748]

3
np.randomTohum değiştirilene kadar sonraki tüm çağrılar için rasgele tohum ayarlanacak şekilde bir kez çağrılabilecek bir işlev var mı ? Her seferinde aramak zorunda olmak gereksiz yere ayrıntılı ve unutulması kolay görünüyor.
Slug

@LubedUpSlug onları dekore edebilirsiniz - en azından bazı basit durumlar için çalışacağını test ettim. def seed_first(fun, seed=0):| \tdef wrapped(*args, **kwargs):| \t\tnp.random.seed(seed)| \t\treturn fun(*args, **kwargs)| \treturn wrappedve sonra for m in np.random.__all__:| \tif m != 'seed':| \t\tsetattr(np.random, m, seed_first(getattr(np.random, m)))Ancak, bu uzun vadede çok ince hatalara ve garip davranışlara yol açabilir. (\
T'yi

1
@ SebastianHöffner yorumunuz için teşekkür ederiz. Sorum biraz yanlış yönlendirildi çünkü cümle karıştı "Ancak, sadece bir kez çağırır ve çeşitli rastgele işlevler kullanırsanız, sonuçlar yine de farklı olacaktır:" np.random.seed()Bir programın başında bir kez çağırmak her zaman aynı sonucu verecektir aynı tohum içinnp.random fonksiyonlar için yapılan çağrılar sonraki çağrılar için tohumu belirleyici olarak değiştirecektir. Arama np.random.seed()için her görüşmeden önce np.randomfonksiyonları muhtemelen istenmeyen sonuçlar üretecektir.
lubed Yukarı Slug

17

Belirtildiği gibi, numpy.random.seed (0) rastgele çekirdeği 0 olarak ayarlar, böylece rastgele aldığınız sahte rastgele sayılar aynı noktadan başlar. Bu, bazı durumlarda hata ayıklama için iyi olabilir. Ancak, biraz okuduktan sonra, iş parçacıkları güvenli değil, çünkü iş parçacıkları güvenli değilse, bu gitmek için yanlış yol gibi görünüyor.

dan farklılıkları-arası numpy-in-piton rasgele rasgele rasgele-ve- :

Numpy.random.seed () için ana zorluk, iş parçacığı için güvenli olmamasıdır - yani, çok sayıda farklı yürütme iş parçacığına sahipseniz kullanmak güvenli değildir, çünkü iki farklı iş parçacığı yürütülürse çalışması garanti edilmez işlevi aynı anda. İş parçacıkları kullanmıyorsanız ve gelecekte programınızı bu şekilde yeniden yazmanız gerekmeyeceğini makul bir şekilde bekliyorsanız, numpy.random.seed () test amaçları için iyi olmalıdır. Gelecekte iş parçacıklarına ihtiyacınız olabileceğinden şüphelenmek için herhangi bir neden varsa, uzun vadede önerildiği gibi yapılması ve numpy.random.Random sınıfının yerel bir örneğini oluşturmak daha güvenlidir. Anlayabildiğim kadarıyla, random.random.seed () iş parçacığı açısından güvenlidir (veya en azından, aksine bir kanıt bulamadım).

bunun nasıl yapılacağıyla ilgili örnek:

from numpy.random import RandomState
prng = RandomState()
print prng.permutation(10)
prng = RandomState()
print prng.permutation(10)
prng = RandomState(42)
print prng.permutation(10)
prng = RandomState(42)
print prng.permutation(10)

verebilir:

[3 0 4 6 8 2 1 9 7 5]

[1 6 9 0 2 7 8 3 5 4]

[8 1 5 0 7 2 9 4 3 6]

[8 1 5 0 7 2 9 4 3 6]

Son olarak, 0'a başlamanın (tüm bitleri 0 olmayan bir tohumun aksine), xor'un çalışma şekli nedeniyle ilk birkaç tekrarlama için tek tip olmayan dağılımlara neden olabileceği durumlar olabileceğini unutmayın, ancak bu algoritmaya bağlıdır ve şu anki endişelerimin ve bu sorunun kapsamı dışında.


12

Bunu sinir ağlarında çok sık kullandım. Bir sinir ağını eğitmeye başladığımızda ağırlıkları rastgele başlattığımız iyi bilinmektedir. Model, bu ağırlıklar üzerinde belirli bir veri seti üzerinde eğitilir. Dönem sayısından sonra eğitimli ağırlık seti alırsınız.

Şimdi tekrar sıfırdan antrenman yapmak istediğinizi veya sonuçları yeniden üretmek için modeli başkalarına iletmek istediğinizi varsayalım, ağırlıklar çoğunlukla daha öncekilerden farklı olacak rastgele sayılara yeniden başlatılacak. Aynı sayıda çağdan sonra (aynı verileri ve diğer parametreleri koruyarak) önceki eğitimlerle elde edilen eğitilmiş ağırlıklar farklı olacaktır. Sorun, modelinizin artık tekrarlanamaz olması, modelinizi sıfırdan her çalıştırdığınızda size farklı ağırlık setleri sağlamasıdır. Bunun nedeni, modelin her seferinde farklı rasgele sayılarla başlatılmasıdır.

Antrenmana her sıfırdan başladığınızda, model aynı rastgele başlangıç ​​ağırlığı setine başlatılırsa ne olur? Bu durumda modeliniz tekrarlanabilir hale gelebilir. Bu numpy.random.seed (0) ile elde edilir. Belirli bir sayıya seed () 'den bahsederek, her zaman aynı rastgele sayılar kümesine asılı kalırsınız.


3

Birisine "rasgele" sayılarla bir şeyin nasıl kodlanacağını gösterdiğinizi düşünün. Numpy tohum kullanarak aynı tohum numarasını kullanabilir ve aynı "rasgele" sayılar kümesini alabilirler.

Bu yüzden tam olarak rastgele değil, çünkü bir algoritma sayıları tükürüyor ancak rastgele oluşturulmuş bir demet gibi görünüyor.


0

Bir rasgele tohum, bir bilgisayar rasgele bir sayı dizisi oluşturduğunda başlangıç ​​noktasını belirtir.

Örneğin, Excel'de rastgele bir sayı oluşturmak istediğinizi varsayalım (Not: Excel, tohum için 9999'luk bir sınır belirler). İşlem sırasında Rastgele Tohum kutusuna bir sayı girerseniz, aynı rasgele sayılar kümesini tekrar kullanabilirsiniz. Kutuya “77” yazdıysanız ve rasgele sayı üretecini bir sonraki çalıştırışınızda “77” yazdıysanız, Excel aynı rasgele sayılar kümesini görüntüler. “99” yazarsanız, tamamen farklı bir sayı kümesi alırsınız. Ancak 77 tohumuna geri dönerseniz, başladığınız aynı rastgele sayılar kümesini alırsınız.

Örneğin, “x sayısını alın, 900 + x ekleyin, sonra 52 çıkarın.” İşlemin başlaması için bir başlangıç ​​numarası (x (tohum)) belirtmeniz gerekir. 77 numaralı başlangıç ​​numarasını alalım:

Toplama 900 + 77 = 977 Çıkar 52 = 925 Aynı algoritmayı takiben, ikinci “rasgele” sayı şöyle olacaktır:

900 + 925 = 1825 Çıkar 52 = 1773 Bu basit örnek bir kalıbı takip eder, ancak bilgisayar numarası üretiminin arkasındaki algoritmalar çok daha karmaşıktır


0

Belirli tohum değeri ayarlandıktan sonra üretilen tüm rasgele sayılar tüm platformlar / sistemler arasında aynıdır.



0
numpy.random.seed(0)
numpy.random.randint(10, size=5)

Bu, aşağıdaki çıktıyı üretir: array([5, 0, 3, 3, 7]) Yine, aynı kodu çalıştırırsak aynı sonucu alırız.

Şimdi tohum değerini 0 olarak 1 veya diğerleri olarak değiştirirsek:

numpy.random.seed(1)
numpy.random.randint(10, size=5)

Bu şu çıktıyı üretir: array([5 8 9 5 0])ama şimdi çıktı yukarıdakiyle aynı değil.


0

Yukarıdaki tüm cevaplar np.random.seed()kodun uygulanmasını göstermektedir . Bunun gerçekte neden olduğunu kısaca açıklamak için elimden geleni yapacağım. Bilgisayarlar, önceden tanımlanmış algoritmalara göre tasarlanmış makinelerdir. Bilgisayardan gelen herhangi bir çıktı, girdiye uygulanan algoritmanın sonucudur. Bir bilgisayardan rastgele sayılar üretmesini istediğimizde, rastgele olduklarından emin olun, ancak bilgisayar sadece rastgele bir şekilde gelmedi!

Bu yüzden np.random.seed(any_number_here)algoritma yazdığımızda , bağımsız değişkene özgü belirli bir sayı kümesi çıkarırany_number_here . Doğru argümanı geçersek neredeyse belirli bir rasgele sayılar kümesi elde edilebilir. Ancak bu, algoritmanın nasıl çalıştığını bilmemizi gerektirecek ki bu oldukça sıkıcı.

Örneğin np.random.seed(10), algoritma değişmedikçe 10 yıl sonra aynı satırı çalıştırsam bile elde ettiğim belirli sayılar kümesini yazarsam aynı kalır.

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.