Banyak kuantitas di dunia nyata berkumpul di sekitar satu nilai rata-rata: tinggi badan, nilai ujian, maupun noise pada pembacaan sensor. Nilai yang jauh dari rata-rata muncul semakin jarang, sehingga histogramnya menyerupai bentuk lonceng. Pola ini dimodelkan oleh distribusi normal, dan numpy.random menyediakan dua method Generator untuk membangkitkannya: normal() dan standard_normal().
Bab ini memakai Generator ber-seed sehingga setiap output dapat direproduksi — konsep seed sudah dibahas pada Chapter Reproducibility dan Random Seed. Kita akan membangkitkan data, membaca parameter loc dan scale, lalu membuktikan secara empiris bahwa rata-rata dan simpangan baku sampel mendekati keduanya.
Membangkitkan Data dengan normal() #
Method rng.normal(loc, scale, size) membangkitkan sampel dari distribusi normal dengan parameter:
loc— pusat distribusi, yaitu rata-rata (mean).scale— lebar penyebaran, yaitu simpangan baku (standard deviation).size— bentuk array hasil; tanpasize, method mengembalikan satu scalar.
Contoh nyata: sensor suhu yang seharusnya membaca 27,5 °C selalu menyimpan noise pengukuran. Kita modelkan noise tersebut sebagai distribusi normal dengan mean 0 dan simpangan baku 0,5:
import numpy as np
rng = np.random.default_rng(42)
suhu_sebenarnya = 27.5
pengukuran = suhu_sebenarnya + rng.normal(loc=0, scale=0.5, size=5)
print(np.round(pengukuran, 2))Output yang Dihasilkan:
[27.65 26.98 27.88 27.97 26.52]Bedah baris demi baris:
- Baris 3 (
rng = np.random.default_rng(42)): interpreter membuat objekGeneratordengan seed 42, sehingga rangkaian angka acak di bawahnya selalu sama di setiap eksekusi. - Baris 5 (
pengukuran = ...):rng.normal(loc=0, scale=0.5, size=5)membangkitkan lima noise berdistribusi normal, lalu noise itu dijumlahkan kesuhu_sebenarnyasecara element-wise. - Baris 6 (
print(np.round(pengukuran, 2))): array hasil dibulatkan ke dua angka desimal agar mudah dibaca; nilai asli tetap tersimpan penuh dipengukuran.
Perhatikan pembacaan ketiga: 27,97 jauh lebih dekat ke 28 daripada ke 27,5 — noise memang bisa menggeser pengukuran ke dua arah.
standard_normal untuk Distribusi Standar #
Distribusi normal standar adalah kasus khusus dengan loc=0 dan scale=1. Method rng.standard_normal(size) membangkitkan sampel dari distribusi ini tanpa perlu argumen loc maupun scale:
import numpy as np
rng = np.random.default_rng(0)
a = rng.standard_normal(3)
rng = np.random.default_rng(0)
b = rng.normal(loc=0.0, scale=1.0, size=3)
print(np.round(a, 4))
print(np.array_equal(a, b))Output yang Dihasilkan:
[ 0.1257 -0.1321 0.6404]
TrueKedua method menghasilkan angka yang identik untuk seed yang sama, karena normal() dengan loc=0, scale=1 di dalamnya memanggil jalur yang sama dengan standard_normal(). Pilih standard_normal() ketika data memang berada di skala standar; pilih normal() ketika mean dan simpangan baku sudah diketahui.
Mean dan std Empiris Mendekati loc dan scale #
Untuk sampel besar, rata-rata dan simpangan baku empiris mendekati loc dan scale. Kita uji dengan 100.000 sampel tinggi badan (dalam cm) yang dimodelkan mean 165 dan simpangan baku 8:
import numpy as np
rng = np.random.default_rng(42)
tinggi = rng.normal(loc=165, scale=8, size=100_000)
print("Rata-rata :", round(float(tinggi.mean()), 2))
print("Std :", round(float(tinggi.std()), 2))Output yang Dihasilkan:
Rata-rata : 164.97
Std : 8.03Rata-rata empiris 164,97 hanya meleset 0,03 dari loc=165, dan std empiris 8,03 meleset 0,03 dari scale=8. Semakin besar size, semakin kecil penyimpangan itu.
Aturan 68-95-99.7 #
Distribusi normal punya sifat yang sangat teratur: proporsi data di sekitar mean bisa dihitung dari simpangan baku. Aturannya dikenal sebagai aturan 68-95-99.7:
| Rentang di sekitar mean | Persentase data |
|---|---|
loc ± 1·scale | ±68,27% |
loc ± 2·scale | ±95,45% |
loc ± 3·scale | ±99,73% |
Kita verifikasi aturan tersebut pada satu juta sampel standar (loc=0, scale=1), sehingga batas 1, 2, dan 3 std sama dengan batas nilai 1, 2, dan 3:
import numpy as np
rng = np.random.default_rng(7)
data = rng.normal(0, 1, size=1_000_000)
print(f"dalam 1 std : {np.mean(np.abs(data) <= 1):.4f}")
print(f"dalam 2 std : {np.mean(np.abs(data) <= 2):.4f}")
print(f"dalam 3 std : {np.mean(np.abs(data) <= 3):.4f}")Output yang Dihasilkan:
dalam 1 std : 0.6830
dalam 2 std : 0.9544
dalam 3 std : 0.9973Proporsi empiris 0,6830, 0,9544, dan 0,9973 cocok dengan teori 68,27%, 95,45%, dan 99,73%. Sifat inilah yang membuat distribusi normal berguna dalam praktik: dari loc dan scale saja, kita langsung tahu sebaran data — misalnya sekitar 95% pengukuran sensor pada contoh awal akan berada di rentang 27,5 ± 1,0 °C.