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
Idr
sumber

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.

Sven Marnach
sumber
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])
Robert Kern
sumber
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)
mari756h
sumber
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.

t_sic
sumber
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])
Kirk Walla
sumber