Pipeline pada chapter sebelumnya menjaga konsistensi di satu mesin dan satu waktu. Bab ini menghadapi ujian yang lebih keras: bisakah orang lain — atau kita sendiri enam bulan dari sekarang, di komputer lain — menjalankan ulang analisis dari awal dan memperoleh angka yang persis sama? Analisis yang lulus ujian itu disebut reproducible (dapat direproduksi), dan statusnya bukan pujian akademis. Ketika pemilik kedai bertanya “angka retensi ini dari mana?”, jawaban yang bisa menunjukkan jalur ulang dari data mentah ke angka akhir jauh lebih kuat daripada jawaban yang mengandalkan ingatan. Pada chapter ini kita bedah tiga sumber hasil yang berubah sendiri, lalu membangun kebiasaan yang menahan ketiganya.

Tiga Sumber Hasil yang Berubah Sendiri #

Hasil analisis yang tidak reproducible hampir selalu bocor dari tiga tempat yang sama. Pertama, keacakan tanpa kendali: pembagian data latih-uji, bootstrap, dan inisialisasi model memakai angka acak; tanpa seed yang dicatat, setiap eksekusi menarik keacakan baru. Kedua, data yang berubah diam-diam: berkas transaksi.csv yang diperbarui setiap pekan membuat analisis “yang sama” membaca isi yang berbeda. Ketiga, lingkungan yang berbeda: versi pandas atau scikit-learn yang berbeda di komputer rekan bisa mengubah perilaku fungsi tertentu, dan hasilnya ikut bergeser.

Sumber perubahanGejalanyaPenawarnya
Keacakan tanpa seedhasil beda tiap dijalankan, tanpa pesan galatdefault_rng(seed) / random_state=42, seed dicatat di laporan
Data berubah diam-diamangka lama tak bisa dijelaskan, “dulu katanya 68%”salinan data beku per analisis, versi tercatat
Lingkungan berbedajalan di laptop kita, gagal atau beda di tempat laindaftar dependensi terkunci versi, lingkungan terisolasi

Ketiga penawar itu satu keluarga: mencatat. Seed dicatat, versi data dicatat, versi pustaka dicatat. Analisis yang reproducible pada dasarnya adalah analisis yang tahu dirinya terbuat dari apa.

Seed: Membuat Keacakan Terkendali #

Angka acak di NumPy tidak benar-benar acak — angka itu ditarik dari generator yang keadaannya ditentukan seed. Seed sama menghasilkan rangkaian angka “acak” yang sama; seed berbeda menghasilkan rangkaian lain. Kita buktikan dengan analisis bootstrap kecil: rata-rata transaksi dari lima sampel ulang atas 16 transaksi Toko Kopi Kita.

python
import numpy as np

transaksi = np.array([24, 18, 28, 15, 24, 32, 26, 30,
                      21, 24, 16, 29, 19, 25, 20, 27])

def rata_bootstrap(nilai, seed, n_sampel=5):
    "Rata-rata transaksi dari lima sampel ulang (bootstrap)."
    rng = np.random.default_rng(seed)
    hasil = []
    for _ in range(n_sampel):
        sampel = rng.choice(nilai, size=len(nilai), replace=True)
        hasil.append(round(float(sampel.mean()), 2))
    return hasil

jalan_pertama = rata_bootstrap(transaksi, seed=42)
jalan_kedua = rata_bootstrap(transaksi, seed=42)
print("seed 42, jalan pertama:", jalan_pertama)
print("seed 42, jalan kedua  :", jalan_kedua)
print("identik               :", jalan_pertama == jalan_kedua)
print("seed 7, jalan lain    :", rata_bootstrap(transaksi, seed=7))

Output yang Dihasilkan:

text
seed 42, jalan pertama: [22.38, 24.19, 23.12, 24.19, 23.94]
seed 42, jalan kedua  : [22.38, 24.19, 23.12, 24.19, 23.94]
identik               : True
seed 7, jalan lain    : [22.38, 25.38, 24.19, 24.12, 23.94]

Mari kita baca hasilnya:

  1. Dua eksekusi dengan seed 42 menghasilkan daftar yang identik — np.random.default_rng(42) selalu memulai generator pada keadaan yang sama, sehingga rng.choice() menarik indeks yang sama. Angka True pada baris ketiga adalah uji reproduksinya.
  2. Seed 7 menghasilkan angka lain yang juga valid — nilai terbesarnya 25,38, sesuatu yang tidak pernah muncul pada rangkaian seed 42 (22,38 sampai 24,19). Kedua rangkaian sama-sama sah; keduanya hanya sampel dari keacakan yang berbeda. Inilah sebabnya seed wajib dicatat di laporan: pembaca yang mengulang dengan seed lain akan mendapat angka berbeda, dan tanpa catatan seed, perbedaan itu terlihat seperti kekeliruan.
  3. Bayangkan tanpa seed: default_rng() tanpa argumen menabur dari jam sistem, sehingga setiap eksekusi menghasilkan lima angka baru. Tidak ada yang salah secara statistik — semua sampel sama-sama sah — tetapi tidak ada satu pun angka yang bisa ditunjukkan kembali.

Membekukan Data dan Lingkungan #

Seed menahan keacakan; dua sumber lain ditahan dengan pembekuan. Untuk data, kebiasaannya adalah bekerja pada salinan beku (frozen copy): saat analisis dimulai, data mentah disalin ke folder proyek beserta catatan asal dan tanggal ambil, dan seluruh analisis membaca salinan itu — bukan sumber yang terus berganti. Data transaksi tetap mengalir di sistem kasir, tetapi analisis Januari ini membaca potret 31 Januari 2026 pukul 24.00, dan potret itu tidak berubah sampai analisis selesai. Cara mencatat versi data dengan checksum dan menelusuri riwayatnya kita bahas tuntas pada chapter Version Control untuk Data .

Untuk lingkungan, kebiasaannya adalah mengunci versi pustaka: analisis yang sehat di pandas 2.2 dan scikit-learn 1.5 perlu mendeklarasikan hal itu, sehingga komputer lain memasang versi yang sama. Deklarasi itu berbentuk berkas daftar dependensi yang dibuat sekali dan ikut disimpan bersama proyek — pekerjaan yang akan kita praktikkan pada chapter Pengelolaan Dependensi . Dua pembekuan ini menjadikan rumus reproducibility lengkap: data yang sama, kode yang sama, lingkungan yang sama, seed yang sama.

Notebook vs Skrip #

Dua wadah kerja menuntut kebiasaan reproducibility yang berbeda. Notebook Jupyter — yang sudah kita kenal pada chapter Penggunaan Notebook — sangat baik untuk menjelajah: sel dijalankan berurutan, keluaran terlihat di sampingnya, dan kita bisa berpindah maju-mundur. Kebiasaan berpindah itulah bahayanya: sel ke-9 yang kita jalankan ulang setelah menyunting sel ke-4 bisa memakai keadaan memori yang sudah tidak sesuai urutan cerita, dan hasilnya terlihat benar padahal tidak bisa dijalankan ulang dari atas.

Uji paling murah untuk notebook adalah Restart and Run All: matikan kernel, jalankan seluruh sel dari kosong. Notebook yang lulus ujian ini secara efektif adalah skrip — dan pada titik itu kita biasanya memindahkan hasil akhirnya ke berkas skrip .py yang dijalankan dari atas ke bawah. Pola kerja yang sehat memakai keduanya sesuai peran: notebook untuk menjelajah dan menyusun cerita, skrip untuk hasil yang akan dijalankan ulang secara rutin.

Rangkuman #

  • Reproducible berarti orang lain bisa menjalankan ulang analisis dari awal dan memperoleh hasil identik — syarat bagi audit, kerja tim, dan kepercayaan.
  • Tiga sumber hasil yang berubah sendiri: keacakan tanpa seed, data yang berubah diam-diam, dan lingkungan pustaka yang berbeda; ketiganya ditahan dengan kebiasaan mencatat.
  • Seed yang sama menghasilkan angka yang sama, dan seed yang berbeda menghasilkan angka lain yang sama-sama sah — karena itu nilainya wajib tertulis di laporan.
  • Data dibekukan sebagai salinan potret bertanggal, dan versi pustaka dikunci dalam daftar dependensi.
  • Notebook untuk menjelajah, skrip untuk hasil rutin; uji Restart and Run All adalah batas pisah yang jujur.

Data beku, seed tercatat, lingkungan terkunci — satu kebutuhan masih tersisa: bukti bahwa data yang kita bekukan memang berkas yang sama dengan yang dipakai kemarin, dan jejak perubahan bila berkas itu berganti. Membuktikan identitas berkas dan melacak riwayatnya adalah pekerjaan chapter berikutnya: Version Control untuk Data .

Referensi #

  1. Project Jupyter — Documentation