Buat larik numpy acak yang sama secara konsisten


89

Saya menunggu pengembang lain untuk menyelesaikan sepotong kode yang akan mengembalikan bentuk larik np (100,2000) dengan nilai -1,0, atau 1.

Sementara itu, saya ingin membuat array dengan karakteristik yang sama secara acak sehingga saya dapat memulai pengembangan dan pengujian saya. Masalahnya adalah saya ingin array yang dibuat secara acak ini menjadi sama setiap kali, sehingga saya tidak menguji array yang terus mengubah nilainya setiap kali saya menjalankan ulang proses saya.

Saya dapat membuat array saya seperti ini, tetapi apakah ada cara untuk membuatnya sehingga selalu sama. Saya dapat membuat acar objek dan melepaskannya, tetapi bertanya-tanya apakah ada cara lain.

r = np.random.randint(3, size=(100, 2000)) - 1

Jawaban:


84

Cukup seed generator nomor acak dengan nilai tetap, misalnya

numpy.random.seed(42)

Dengan cara ini, Anda akan selalu mendapatkan urutan nomor acak yang sama.


43
Seseorang menyelinap ke dalam numpy.random.seed()fungsi saat saya tidak memperhatikan. :-) Saya sengaja meninggalkannya dari modul aslinya. Saya merekomendasikan agar orang-orang menggunakan contoh mereka sendiri RandomStatedan meneruskan objek-objek itu.
Robert Kern

6
Robert adalah kontributor utama numpy. Saya pikir kita harus memberikan pendapatnya sedikit bobot.
tidak berlaku lagi

10
@deprecated: Saya berterima kasih atas pekerjaan Robert, tetapi karyanya bukanlah pengganti untuk memberikan alasan yang rasional untuk rekomendasi tersebut. Selain itu, jika penggunaan dari numpy.random.seed()tidak disarankan, ini harus disebutkan dalam dokumentasi . Tampaknya, kontributor NumPy lainnya tidak sependapat dengan Robert. Tidak ada maksud tersinggung sama sekali, saya hanya penasaran.
Sven Marnach

13
Ini sama dengan menggunakan random.seedvs. menggunakan random.Randomobjek di pustaka standar Python. Jika Anda menggunakan random.seedatau numpy.random.seed, Anda melakukan seeding semua instance acak, baik dalam kode Anda maupun dalam kode apa pun yang Anda panggil atau kode apa pun yang dijalankan dalam sesi yang sama seperti milik Anda. Jika hal-hal itu bergantung pada hal-hal yang sebenarnya acak, maka Anda mulai mengalami masalah. Jika Anda menerapkan kode yang menetapkan seed acak, Anda dapat menyebabkan kerentanan keamanan.
asmeurer

3
@asmeurer Siapa pun yang menggunakan pembuat nomor pseudorandom untuk tujuan keamanan mungkin tidak tahu apa yang mereka lakukan.
JAB

191

Buat instance Anda sendiri numpy.random.RandomState()dengan benih pilihan Anda. Jangan gunakan numpy.random.seed()kecuali untuk menangani pustaka yang tidak fleksibel yang tidak memungkinkan Anda menyebarkan RandomStateinstans Anda sendiri .

[~]
|1> from numpy.random import RandomState

[~]
|2> prng = RandomState(1234567890)

[~]
|3> prng.randint(-1, 2, size=10)
array([ 1,  1, -1,  0,  0, -1,  1,  0, -1, -1])

[~]
|4> prng2 = RandomState(1234567890)

[~]
|5> prng2.randint(-1, 2, size=10)
array([ 1,  1, -1,  0,  0, -1,  1,  0, -1, -1])

7
Apakah Anda punya alasan untuk rekomendasi Anda? Ada apa dengan numpy.random.seed()? Saya tahu ini tidak aman untuk benang, tetapi sangat nyaman jika Anda tidak memerlukan pengaman benang.
Sven Marnach

52
Ini sebagian besar untuk membentuk kebiasaan baik. Anda mungkin tidak memerlukan streaming independen sekarang, tetapi Sven-6-bulan-dari-sekarang mungkin. Jika Anda menulis perpustakaan Anda untuk menggunakan metode langsung dari numpy.random, Anda tidak dapat membuat aliran independen nanti. Juga lebih mudah untuk menulis pustaka dengan tujuan mengontrol aliran PRNG. Selalu ada banyak cara untuk masuk ke perpustakaan Anda, dan setiap cara harus memiliki cara untuk mengontrol benih. Mengirimkan objek PRNG adalah cara yang lebih bersih untuk melakukan itu daripada mengandalkan numpy.random.seed(). Sayangnya, kotak komentar ini terlalu pendek untuk memuat lebih banyak contoh. :-)
Robert Kern

25
Cara lain untuk mendeskripsikan alasan Robert: menggunakan numpy.random.seed menggunakan variabel global untuk mempertahankan status PRNG, dan alasan standar yang sama bahwa variabel global buruk diterapkan di sini.
Robie Basak

9
Jika Anda ingin PRNG mandiri, jangan menyemai mereka dengan apa pun. Gunakan saja numpy.random.RandomState()tanpa argumen. Ini akan menyemai status dengan nilai unik yang diambil dari fasilitas sistem operasi Anda untuk hal-hal seperti itu ( /dev/urandompada mesin UNIX dan Windows yang setara di sana). Jika numpy.random.RandomState(1234567890)tidak berhasil untuk Anda, tunjukkan dengan tepat apa yang Anda ketik dan pesan kesalahan yang Anda dapatkan dengan tepat.
Robert Kern

5
Bukan ide yang bagus. Gunakan numpy.random.RandomState()tanpa argumen untuk hasil terbaik.
Robert Kern

3

Jika Anda menggunakan fungsi lain yang bergantung pada keadaan acak, Anda tidak bisa hanya mengatur dan keseluruhan benih, tetapi sebaliknya harus membuat fungsi untuk menghasilkan daftar nomor acak dan mengatur benih sebagai parameter fungsi. Ini tidak akan mengganggu generator acak lainnya dalam kode:

# Random states
def get_states(random_state, low, high, size):
    rs = np.random.RandomState(random_state)
    states = rs.randint(low=low, high=high, size=size)
    return states

# Call function
states = get_states(random_state=42, low=2, high=28347, size=25)

3

Penting untuk memahami apa itu seed generator acak dan kapan / bagaimana itu diatur dalam kode Anda (periksa misalnya di sini untuk penjelasan yang bagus tentang arti matematis dari seed tersebut).

Untuk itu perlu dilakukan penyetelan benih dengan melakukan:

random_state = np.random.RandomState(seed=your_favorite_seed_value)

Maka penting untuk membuat nomor acak dari random_state dan bukan dari np.random. Yaitu Anda harus melakukan:

random_state.randint(...)

dari pada

np.random.randint(...) 

yang akan membuat instance baru dari RandomState () dan pada dasarnya menggunakan jam internal komputer Anda untuk mengatur benih.


2

Saya hanya ingin mengklarifikasi sesuatu terkait jawaban @Robert Kern kalau-kalau itu tidak jelas. Bahkan jika Anda menggunakan the RandomStateAnda harus menginisialisasi setiap kali Anda memanggil metode acak numpy seperti dalam contoh Robert jika tidak Anda akan mendapatkan hasil berikut.

Python 3.6.9 |Anaconda, Inc.| (default, Jul 30 2019, 19:07:31) 
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> prng = np.random.RandomState(2019)
>>> prng.randint(-1, 2, size=10)
array([-1,  1,  0, -1,  1,  1, -1,  0, -1,  1])
>>> prng.randint(-1, 2, size=10)
array([-1, -1, -1,  0, -1, -1,  1,  0, -1, -1])
>>> prng.randint(-1, 2, size=10)
array([ 0, -1, -1,  0,  1,  1, -1,  1, -1,  1])
>>> prng.randint(-1, 2, size=10)
array([ 1,  1,  0,  0,  0, -1,  1,  1,  0, -1])
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.