Topik ini membahas seed sebagai mekanisme yang menjadikan urutan angka acak tetap dan dapat direproduksi. Cakupannya meliputi efek seed terhadap Generator, bukti eksekusi bahwa dua Generator berseed sama menghasilkan urutan yang sama, peran algoritma PCG64 di balik Generator, serta praktik pencatatan seed pada eksperimen.
Apa yang dilakukan seed#
Pembangkit angka acak pada NumPy pada dasarnya bersifat deterministik. Ia menghasilkan urutan angka yang tampak tak terduga, tetapi urutan tersebut sepenuhnya ditentukan oleh state internalnya. Parameter seed pada default_rng mengisi state awal tersebut, sehingga seed yang sama selalu menghasilkan urutan yang sama. Istilah yang tepat untuk angka semacam ini adalah acak semu (pseudorandom). Sifat deterministik ini bukan kelemahan, melainkan fitur yang justru dimanfaatkan pada pengujian dan materi ajar. Secara mekanis, seed menentukan posisi awal pada satu urutan angka yang sangat panjang, dan setiap pemanggilan metode menggeser posisi tersebut ke depan. Dua Generator yang berdiri di posisi awal yang sama menghasilkan angka yang sama persis selama rangkaian pemanggilannya juga sama.
import numpy as np
rng_1 = np.random.default_rng(seed=2024)
rng_2 = np.random.default_rng(seed=2024)
print(rng_1.integers(low=0, high=100, size=5))
print(rng_2.integers(low=0, high=100, size=5))[24 67 9 21 31]
[24 67 9 21 31]Kedua baris keluaran identik karena rng_1 dan rng_2 dibuat dengan seed yang sama. Kesamaan ini berlaku bukan hanya untuk lima bilangan pertama, melainkan untuk seluruh urutan yang sangat panjang. Seed boleh berupa bilangan bulat apa pun, dan pemilihan angkanya tidak memengaruhi kualitas urutan yang dihasilkan.
Urutan yang sama di setiap proses#
Karena urutan sepenuhnya ditentukan oleh seed dan algoritmanya, skrip yang sama yang dijalankan ulang pada waktu berbeda menghasilkan angka yang persis sama. Sifat inilah yang disebut reproduktibilitas: eksperimen dapat diulang, dan hasilnya dapat diperiksa kembali oleh pihak lain tanpa bergantung pada kebetulan. Manfaatnya nyata pada pekerjaan sehari-hari, karena laporan dapat menyertakan angka yang dapat diulang dan perubahan kode dapat diuji dengan membandingkan keluaran sebelum dan sesudahnya.
Apabila default_rng dipanggil tanpa argumen, NumPy mengambil nilai awal dari sumber entropi sistem operasi. Urutan yang dihasilkan berbeda pada setiap proses dan tidak dapat direproduksi. Perilaku ini diinginkan untuk program yang angka acaknya tidak boleh mudah ditebak, misalnya pembangkit token. Sebaliknya, eksperimen ilmiah, pengujian otomatis, dan materi ajar memerlukan seed tertulis. Blok kode pada modul ini sengaja selalu menyertakan seed agar setiap keluaran yang ditampilkan dapat diverifikasi ulang.
Dua Generator dengan seed berbeda#
Seed yang berbeda menghasilkan urutan yang berbeda pula. Blok berikut membuat dua Generator dengan seed 1 dan 2, lalu mengambil empat sampel normal dari masing-masing.
import numpy as np
rng_a = np.random.default_rng(seed=1)
rng_b = np.random.default_rng(seed=2)
print(rng_a.normal(size=4))
print(rng_b.normal(size=4))[ 0.34558419 0.82161814 0.33043708 -1.30315723]
[ 0.18905338 -0.52274844 -0.41306354 -2.44146738]Kedua baris keluaran tidak berhubungan satu sama lain. Nilai seed sendiri bersifat arbitrer: angka 1, 42, atau 2024 sama sahnya, dan yang penting adalah seed tersebut dicatat. Karena urutannya berbeda, dua Generator tidak dapat dipertukarkan begitu saja pada eksperimen yang sama. Apabila hasil antar konfigurasi perlu dibandingkan, gunakan seed yang sama untuk semua konfigurasi agar perbedaan hasil murni berasal dari perubahan konfigurasinya. Di balik Generator, NumPy menjalankan algoritma pembangkit bernama PCG64 (Permuted Congruential Generator), yaitu algoritma yang deterministik terhadap state awalnya dan dirancang agar urutannya sulit ditebak. Sebagai pembanding, API warisan RandomState dibangun di atas algoritma MT19937 yang berbeda, sehingga kode lama dengan seed sama tidak menghasilkan urutan yang sama dengan Generator. Seluruh jaminan reproduktibilitas bersandar pada determinisme algoritma ini, bukan pada kebetulan.
Praktik seeding yang disiplin#
Reproduktibilitas diperoleh melalui kebiasaan yang konsisten, bukan hanya melalui pengetahuan tentang parameter seed. Kebiasaan berikut menjaga eksperimen tetap dapat diulang.
- Catat seed bersama catatan eksperimen, misalnya sebagai konstanta bernama di baris awal skrip.
- Buat Generator sekali di awal program, lalu teruskan objeknya ke fungsi yang membutuhkan.
- Gunakan satu seed per eksperimen agar seluruh angka pada satu laporan berasal dari satu urutan yang tercatat.
- Hindari mencoba banyak seed hingga muncul hasil yang disukai, karena hasil yang dipilih demikian tidak lagi netral.
Untuk program yang lebih besar, satu Generator dapat diteruskan ke banyak fungsi, sehingga seluruh keacakannya berasal dari satu seed yang tercatat. Apabila satu bagian memerlukan urutan tersendiri yang tidak mengganggu urutan bagian lain, buat Generator tambahan dari seed lain dan catat keduanya. Kebiasaan ini membuat perbedaan hasil antar komputer dapat dilacak hingga ke perbedaan seed, bukan ke ketidakpastian yang tidak terjelaskan.
Kesalahan umum#
Kesalahan yang paling sering terjadi adalah membuat Generator baru di dalam perulangan dengan seed yang sama. Setiap iterasi memperoleh state awal yang sama, sehingga angka yang dihasilkan berulang pula. Blok berikut memperlihatkan gejalanya.
import numpy as np
for i in range(3):
rng = np.random.default_rng(seed=42)
print(f"iterasi {i}: {rng.integers(low=0, high=100)}")iterasi 0: 8
iterasi 1: 8
iterasi 2: 8Ketiga iterasi menghasilkan angka 8 karena setiap putaran membuat Generator baru, mengisi seed yang sama, lalu memanggilnya sekali. Angka yang berulang ini bukan kebetulan, melainkan konsekuensi langsung dari state awal yang sama. Perbaikannya adalah membuat Generator satu kali sebelum perulangan, sehingga state maju dari satu iterasi ke iterasi berikutnya.
import numpy as np
rng = np.random.default_rng(seed=42)
for i in range(3):
print(f"iterasi {i}: {rng.integers(low=0, high=100)}")iterasi 0: 8
iterasi 1: 77
iterasi 2: 65Kesalahan lain adalah menganggap seed menentukan nilai, bukan urutan. Seed 42 tidak berarti angka berikutnya adalah 42, melainkan berarti urutan dimulai dari state awal tertentu. Karena urutannya sangat panjang, mengubah seed sedikit saja mengubah seluruh angka berikutnya secara tak terduga, sehingga perbandingan antar seed tidak menunjukkan pola yang mudah ditebak. Praktik yang tepat adalah menetapkan seed pada awal kerja, mencatatnya, dan hanya mengubahnya apabila urutan baru memang diperlukan.
Ringkasan#
- Seed mengisi state awal Generator, dan seed yang sama selalu menghasilkan urutan yang sama.
- Dua Generator berseed sama menghasilkan urutan identik, sedangkan Generator tanpa seed menghasilkan urutan berbeda di setiap proses.
- Generator dibangun di atas algoritma PCG64 yang deterministik terhadap state awalnya.
- Catat seed pada eksperimen, buat Generator sekali, lalu teruskan objeknya ke fungsi yang membutuhkan.
Referensi#
- numpy.random.Generator — NumPy — Dokumentasi kelas Generator, termasuk perilaku konstruktornya.
- Random sampling (numpy.random) — NumPy — Ikhtisar submodul numpy.random dan konsepnya.
- Legacy RandomState — NumPy — API warisan berbasis MT19937 yang disebut sebagai pembanding.