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; tanpa size, 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:

python
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:

text
[27.65 26.98 27.88 27.97 26.52]

Bedah baris demi baris:

  1. Baris 3 (rng = np.random.default_rng(42)): interpreter membuat objek Generator dengan seed 42, sehingga rangkaian angka acak di bawahnya selalu sama di setiap eksekusi.
  2. Baris 5 (pengukuran = ...): rng.normal(loc=0, scale=0.5, size=5) membangkitkan lima noise berdistribusi normal, lalu noise itu dijumlahkan ke suhu_sebenarnya secara element-wise.
  3. Baris 6 (print(np.round(pengukuran, 2))): array hasil dibulatkan ke dua angka desimal agar mudah dibaca; nilai asli tetap tersimpan penuh di pengukuran.

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:

python
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:

text
[ 0.1257 -0.1321  0.6404]
True

Kedua 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:

python
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:

text
Rata-rata : 164.97
Std       : 8.03

Rata-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 meanPersentase 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:

python
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:

text
dalam 1 std : 0.6830
dalam 2 std : 0.9544
dalam 3 std : 0.9973

Proporsi 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.