Apa yang dilakukan numpy.random.seed (0)?

282

Apa yang np.random.seeddilakukan dalam kode di bawah ini dari tutorial Scikit-Learn? Saya tidak terlalu terbiasa dengan hal-hal generator keadaan acak NumPy, jadi saya sangat menghargai penjelasan istilah orang awam tentang ini.

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

Jawaban:

558

np.random.seed(0) membuat angka acak dapat diprediksi

>>> 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])

Dengan reset benih (setiap kali), sama set nomor akan muncul setiap kali.

Jika seed acak tidak diatur ulang, nomor yang berbeda akan muncul di setiap permintaan:

>>> 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])

(pseudo-) angka acak bekerja dengan mulai dengan angka (seed), mengalikannya dengan angka besar, menambahkan offset, kemudian mengambil modulo dari jumlah itu. Angka yang dihasilkan kemudian digunakan sebagai benih untuk menghasilkan nomor "acak" berikutnya. Ketika Anda mengatur seed (setiap waktu), ia melakukan hal yang sama setiap kali, memberi Anda nomor yang sama.

Jika Anda menginginkan angka yang tampaknya acak, jangan atur seed. Namun, jika Anda memiliki kode yang menggunakan angka acak yang ingin Anda debug, akan sangat membantu untuk mengatur seed sebelum setiap kali dijalankan sehingga kode tersebut melakukan hal yang sama setiap kali Anda menjalankannya.

Untuk mendapatkan nomor paling acak untuk setiap proses, hubungi numpy.random.seed(). Ini akan menyebabkan numpy untuk mengatur seed ke nomor acak yang diperoleh dari /dev/urandomatau analog Windows-nya atau, jika tidak ada yang tersedia, ia akan menggunakan jam.

Untuk informasi lebih lanjut tentang menggunakan benih untuk menghasilkan angka pseudo-random, lihat wikipedia .

John1024
sumber
86
Jawaban ini harus ditambahkan ke dokumentasi numpy. Terima kasih.
gorjanz
8
Juga, ketika Anda menelepon numpy.random.seed(None), itu "akan mencoba membaca data dari / dev / urandom (atau analog Windows) jika tersedia atau seeded dari jam sebaliknya".
Jonathan
1
@ Jonathan Poin luar biasa tentang numpy.random.seed(None). Saya memperbarui jawabannya dengan info itu dan tautan ke dokumen.
John1024
@ curio1729 Implementasi dapat bervariasi dari satu sistem operasi ke yang berikutnya tetapi numpy mencoba untuk membuat perintahnya, termasuk seed, kompatibel.
John1024
1
@ L3viathan Poin bagus! Agar lebih lengkap & akurat, saya seharusnya menyebutkan bahwa offset ditambahkan. Jawaban diperbarui. Bagi mereka yang menginginkan perincian lebih lanjut, saya juga menambahkan tautan ke diskusi wikipedia tentang generator angka pseudo-acak.
John1024
38

Jika Anda mengatur np.random.seed(a_fixed_number)setiap kali Anda memanggil fungsi acak numpy lainnya, hasilnya akan sama:

>>> 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]

Namun, jika Anda hanya memanggilnya sekali dan menggunakan berbagai fungsi acak, hasilnya akan tetap berbeda:

>>> 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]
Zhun Chen
sumber
3
Apakah ada fungsi yang dapat dipanggil sekali sehingga seed acak diatur untuk semua np.randompanggilan berikutnya sampai seed diubah? Harus memanggilnya setiap kali tampaknya tidak perlu dan mudah untuk dilupakan.
Lubed Up Slug
@LubedUpSlug Anda dapat menghiasnya - setidaknya untuk beberapa kasus sederhana saya mengujinya akan berfungsi. def seed_first(fun, seed=0):| \tdef wrapped(*args, **kwargs):| \t\tnp.random.seed(seed)| \t\treturn fun(*args, **kwargs)| \treturn wrapped, dan kemudian for m in np.random.__all__:| \tif m != 'seed':| \t\tsetattr(np.random, m, seed_first(getattr(np.random, m)))Namun, ini bisa menyebabkan bug yang sangat halus dan perilaku aneh dalam jangka panjang. (Ganti dengan empat spasi, dan | dengan jeda baris ...)
Sebastian Höffner
1
@ SebastianHöffner terima kasih atas komentar Anda. Pertanyaan saya agak salah kaprah karena saya bingung dengan kalimat "Namun, jika Anda hanya memanggilnya sekali dan menggunakan berbagai fungsi acak, hasilnya akan tetap berbeda:" Memanggil np.random.seed()satu kali di awal program akan selalu menghasilkan hasil yang sama untuk seed yang sama karena pemanggilan np.randomfungsi selanjutnya secara deterministik akan mengubah seed untuk pemanggilan selanjutnya. Memanggil np.random.seed()sebelum setiap panggilan ke np.randomfungsi mungkin akan menghasilkan hasil yang tidak diinginkan.
Lubed Up Slug
17

Seperti disebutkan, numpy.random.seed (0) menetapkan seed acak ke 0, sehingga angka acak semu yang Anda dapatkan dari acak akan mulai dari titik yang sama. Ini bisa baik untuk men-debug dalam beberapa kasus. NAMUN, setelah membaca beberapa kali, ini tampaknya cara yang salah untuk melakukannya, jika Anda memiliki utas karena bukan utas yang aman.

dari perbedaan-antara-numpy-acak-dan-acak-acak-di-python :

Untuk numpy.random.seed (), kesulitan utama adalah bahwa itu bukan thread-safe - yaitu, itu tidak aman untuk digunakan jika Anda memiliki banyak utas eksekusi yang berbeda, karena itu tidak dijamin bekerja jika dua utas berbeda mengeksekusi fungsi pada saat bersamaan. Jika Anda tidak menggunakan utas, dan jika Anda cukup berharap bahwa Anda tidak perlu menulis ulang program Anda dengan cara ini di masa mendatang, numpy.random.seed () akan baik-baik saja untuk tujuan pengujian. Jika ada alasan untuk curiga bahwa Anda mungkin perlu utas di masa depan, pada akhirnya akan jauh lebih aman untuk melakukan seperti yang disarankan, dan untuk membuat turunan lokal dari kelas numpy.random.Random. Sejauh yang saya tahu, random.random.seed () aman-thread (atau setidaknya, saya belum menemukan bukti yang bertentangan).

contoh cara melakukannya:

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)

dapat memberi:

[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]

Terakhir, perhatikan bahwa mungkin ada kasus di mana inisialisasi ke 0 (sebagai lawan dari seed yang tidak memiliki semua bit 0) dapat mengakibatkan distribusi yang tidak seragam untuk beberapa iterasi pertama karena cara xor bekerja, tetapi ini tergantung pada algoritma , dan berada di luar kekhawatiran saya saat ini dan ruang lingkup pertanyaan ini.

ntg
sumber
12

Saya sudah sering menggunakan ini dalam jaringan saraf. Diketahui bahwa ketika kita mulai melatih jaringan saraf kita secara acak menginisialisasi bobot. Model dilatih tentang bobot ini pada dataset tertentu. Setelah sejumlah zaman, Anda mendapatkan serangkaian bobot yang terlatih.

Sekarang anggaplah Anda ingin melatih lagi dari awal atau Anda ingin meneruskan model itu kepada orang lain untuk mereproduksi hasil Anda, bobot akan kembali diinisialisasi ke angka acak yang sebagian besar akan berbeda dari yang sebelumnya. Bobot terlatih yang diperoleh setelah jumlah zaman yang sama (menyimpan data yang sama dan parameter lainnya) seperti yang sebelumnya akan berbeda. Masalahnya adalah model Anda tidak lagi dapat direproduksi. Setiap kali Anda melatih model Anda dari awal, model itu memberi Anda set bobot yang berbeda. Ini karena model diinisialisasi dengan angka acak yang berbeda setiap kali.

Bagaimana jika setiap kali Anda memulai pelatihan dari awal, model diinisialisasi ke set bobot inisialisasi acak yang sama? Dalam hal ini model Anda dapat direproduksi. Ini dicapai oleh numpy.random.seed (0). Dengan menyebutkan seed () ke nomor tertentu, Anda selalu bergantung pada set angka acak yang sama.

A Santosh
sumber
3

Bayangkan Anda menunjukkan kepada seseorang cara membuat kode dengan sekelompok angka "acak". Dengan menggunakan benih numpy, mereka dapat menggunakan nomor benih yang sama dan mendapatkan set angka "acak" yang sama.

Jadi itu tidak benar-benar acak karena suatu algoritma mengeluarkan angka tetapi sepertinya banyak yang dihasilkan secara acak.

cjHerold
sumber
0

Benih acak menentukan titik awal ketika komputer menghasilkan urutan nomor acak.

Misalnya, katakanlah Anda ingin membuat angka acak di Excel (Catatan: Excel menetapkan batas 9999 untuk seed). Jika Anda memasukkan nomor ke kotak Benih Acak selama proses, Anda akan dapat menggunakan set angka acak yang sama lagi. Jika Anda mengetik "77" ke dalam kotak, dan mengetik "77" saat berikutnya Anda menjalankan generator angka acak, Excel akan menampilkan set angka acak yang sama. Jika Anda mengetik "99", Anda akan mendapatkan serangkaian angka yang sama sekali berbeda. Tetapi jika Anda kembali ke seed of 77, maka Anda akan mendapatkan set angka acak yang sama dengan yang Anda mulai.

Misalnya, "ambil angka x, tambahkan 900 + x, lalu kurangi 52." Agar proses dimulai, Anda harus menentukan nomor awal, x (seed). Mari kita mulai nomor 77:

Tambahkan 900 + 77 = 977 Kurangi 52 = 925 Mengikuti algoritma yang sama, angka "acak" kedua adalah:

900 + 925 = 1825 Kurangi 52 = 1773 Contoh sederhana ini mengikuti sebuah pola, tetapi algoritma di balik pembuatan nomor komputer jauh lebih rumit

sunidhi mittal
sumber
0

Semua angka acak yang dihasilkan setelah menetapkan nilai seed tertentu sama di semua platform / sistem.

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

Ini menghasilkan output berikut: array([5, 0, 3, 3, 7]) Sekali lagi, jika kita menjalankan kode yang sama kita akan mendapatkan hasil yang sama.

Sekarang jika kita mengubah nilai seed 0 menjadi 1 atau yang lain:

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

Ini menghasilkan output berikut: array([5 8 9 5 0])tetapi sekarang output tidak sama seperti di atas.

Humayun Ahmad Rajib
sumber
0

Semua jawaban di atas menunjukkan implementasi dari np.random.seed() dalam kode. Saya akan mencoba yang terbaik untuk menjelaskan secara singkat mengapa itu benar-benar terjadi. Komputer adalah mesin yang dirancang berdasarkan algoritma yang telah ditentukan. Setiap output dari komputer adalah hasil dari algoritma yang diterapkan pada input. Jadi ketika kami meminta komputer untuk menghasilkan angka acak, tentu saja angka itu acak tetapi komputer tidak hanya membuatnya secara acak!

Jadi, ketika kita menulis np.random.seed(any_number_here)algoritme akan menampilkan serangkaian angka tertentu yang unik untuk argumen any_number_here. Hampir seperti seperangkat angka acak tertentu dapat diperoleh jika kita melewati argumen yang benar. Tetapi ini akan mengharuskan kita untuk mengetahui tentang bagaimana algoritma bekerja yang cukup membosankan.

Jadi, misalnya jika saya menulis np.random.seed(10)set angka tertentu yang saya peroleh akan tetap sama bahkan jika saya mengeksekusi baris yang sama setelah 10 tahun kecuali algoritme berubah.

WadeWilson
sumber