Setiap variabel acak membawa daftar peluangnya sendiri — dan di dunia nyata, daftar-daftar itu ternyata suka berulang polanya. Banyaknya pembeli yang memesan menu baru, jumlah keluhan pelanggan per hari, jeda antar kedatangan pelanggan: semuanya mengikuti pola yang sudah bernama dan sudah dipelajari bertahun-tahun. Pola bernama itulah distribusi probabilitas, dan memilih distribusi berarti memilih asumsi tentang cara data terbentuk. Pada chapter ini kita rapikan peralatan dasarnya — PMF, PDF, dan CDF — lalu membedah empat distribusi paling sering dipakai: seragam diskrit, binomial, Poisson, dan eksponensial.

Distribusi: Peta Peluang Sebuah Variabel Acak #

Distribusi probabilitas adalah peta lengkap peluang sebuah variabel acak: nilai-nilai apa saja yang mungkin dan seberapa besar peluang tiap nilainya. Untuk variabel diskrit, peta itu berupa daftar P(X = x); untuk variabel kontinu, berupa fungsi kerapatan. Tiga istilah akan terus muncul di seluruh Course ini, jadi kita rapikan sekarang:

AlatBerlaku untukPertanyaan yang dijawab
PMF (probability mass function)DiskritBerapa peluang X tepat bernilai x?
PDF (probability density function)KontinuSeberapa padat peluang di sekitar x? (bukan peluang itu sendiri)
CDF (cumulative distribution function)Diskrit dan kontinuBerapa peluang X bernilai kurang dari atau sama dengan x?

CDF adalah alat paling serbaguna karena berlaku untuk kedua jenis variabel: F(x) = P(X ≤ x) selalu sah dibaca, baik pada dadu maupun pada suhu udara. CDF selalu naik dari 0 menuju 1; dari CDF kita bisa menjawab peluang selang mana pun dengan satu pengurangan. Seluruh keluarga distribusi ini tinggal di satu tempat di ekosistem Python: modul scipy.stats, yang menyediakan fungsi .pmf(), .pdf(), dan .cdf() untuk puluhan distribusi.

Distribusi Seragam Diskrit: Peluang yang Rata #

Distribusi paling sederhana memberi peluang sama rata pada seluruh nilai yang mungkin — persis seperti dadu yang adil: enam sisi, masing-masing berpeluang 1/6. Rumusnya singkat, P(X = x) = 1/n untuk n nilai yang mungkin. Kita bangun PMF-nya secara manual, akumulasikan CDF-nya, lalu cocokkan dengan randint milik scipy.stats:

python
from scipy.stats import randint

sisi = [1, 2, 3, 4, 5, 6]
pmf = {x: 1 / 6 for x in sisi}

print("x | PMF   | CDF")
cdf = 0.0
for x in sisi:
    cdf += pmf[x]
    print(f"{x} | {pmf[x]:.4f} | {cdf:.4f}")

print(f"\nCek scipy randint: pmf(4) = {randint.pmf(4, 1, 7):.4f}, cdf(4) = {randint.cdf(4, 1, 7):.4f}")

Output yang Dihasilkan:

text
x | PMF   | CDF
1 | 0.1667 | 0.1667
2 | 0.1667 | 0.3333
3 | 0.1667 | 0.5000
4 | 0.1667 | 0.6667
5 | 0.1667 | 0.8333
6 | 0.1667 | 1.0000

Cek scipy randint: pmf(4) = 0.1667, cdf(4) = 0.6667

Mari kita telaah kode di atas:

  1. Baris 4 (pmf): dictionary comprehension membangun PMF — tiap sisi mendapat bobot 1/6. Total keenam bobot berjumlah tepat 1, syarat mutlak setiap PMF.
  2. Baris 7-10 (akumulator cdf): CDF dijumlah bertahap dari kiri. Setelah sisi 4, CDF = 0,6667 — artinya P(X ≤ 4) = 4/6, karena empat nilai sudah terkumpul.
  3. Baris 12 (randint.pmf(4, 1, 7)): randint(low, high) di scipy mengikuti kebiasaan rentang Python — batas atas terbuka — sehingga randint(1, 7) berarti sisi 1 sampai 6. Hasil manual dan hasil scipy cocok.

CDF seragam diskrit berbentuk tangga: melompat 1/6 di tiap nilai yang mungkin. Bentuk tangga inilah wajah khas CDF variabel diskrit, berbeda dari kurva mulus variabel kontinu yang akan kita jumpai sebentar lagi.

Distribusi Binomial: Menghitung Banyaknya Sukses #

Binomial menjawab pertanyaan yang muncul di mana-mana: dari n percobaan yang saling merdeka, masing-masing berpeluang sukses p, berapa banyak yang sukses? Kita pakai skenario kafe: lima pembeli pertama hari itu, dan tiap pembeli berpeluang 30% memesan menu baru matcha latte. X = banyaknya pembeli yang memesan. Rumus PMF binomial memakai kombinasi untuk menghitung banyaknya susunan keberhasilan:

text
P(X = k) = C(n, k) × p^k × (1-p)^(n-k)
E[X] = n × p        Var(X) = n × p × (1-p)

Kita hitung manual dengan math.comb, lalu adu berdampingan dengan binom.pmf dari scipy:

python
from math import comb
from scipy.stats import binom

n, p = 5, 0.30   # 5 pembeli hari itu, peluang 30% memesan menu baru

print("k | rumus manual | binom.pmf(k)")
for k in range(n + 1):
    manual = comb(n, k) * p**k * (1 - p) ** (n - k)
    print(f"{k} | {manual:<12.4f}| {binom.pmf(k, n, p):.4f}")

print(f"\nE[K]   = n x p = {n * p:.2f}")
print(f"Var(K) = n x p x (1-p) = {n * p * (1 - p):.4f}")

Output yang Dihasilkan:

text
k | rumus manual | binom.pmf(k)
0 | 0.1681      | 0.1681
1 | 0.3601      | 0.3601
2 | 0.3087      | 0.3087
3 | 0.1323      | 0.1323
4 | 0.0283      | 0.0283
5 | 0.0024      | 0.0024

E[K]   = n x p = 1.50
Var(K) = n x p x (1-p) = 1.0500

Mari kita telaah kode di atas:

  1. Baris 8 (manual = ...): rumus PMF diterjemahkan apa adanya — comb(n, k) menghitung C(n, k), banyaknya cara memilih k pembeli pemesan dari n pembeli; p**k adalah peluang k pembeli memesan; (1-p)**(n-k) peluang sisanya tidak memesan.
  2. Baris 9 (binom.pmf): hasil scipy identik hingga empat desimal. Untuk n kecil, rumus manual dan library sama mudahnya; untuk n besar, comb membesar dengan cepat dan library menjadi satu-satunya jalan yang nyaman.
  3. Baris 11-12 (E[K] dan Var(K)): rata-rata cukup n × p = 1,5 pembeli — konsisten dengan intuisi “30% dari lima orang”. Bentuk varians n × p × (1−p) akan sering kita pakai saat menghitung galat standar proporsi pada chapter-chapter inferensi.

Puncak PMF ada di k = 1 (peluang 0,3601) — modus distribusi — lalu melandai cepat ke arah k besar: peluang kelima pembeli sekaligus memesan hanya 0,0024. Pertanyaan yang lebih sering diajukan bisnis bukan “tepat dua?” melainkan “minimal dua?” atau “kurang dari dua?”, dan di sinilah CDF masuk:

python
from scipy.stats import binom

n, p = 5, 0.30

p_kurang_2 = binom.cdf(1, n, p)
p_minimal_2 = binom.sf(1, n, p)
p_minimal_1 = 1 - binom.pmf(0, n, p)

print(f"P(K <= 1) = {p_kurang_2:.4f}")
print(f"P(K >= 2) = 1 - P(K <= 1) = {p_minimal_2:.4f}")
print(f"P(K >= 1) = 1 - P(K = 0) = {p_minimal_1:.4f}")
print(f"P(K = 2 | K >= 1) = {binom.pmf(2, n, p):.4f} / {p_minimal_1:.4f} = "
      f"{binom.pmf(2, n, p) / p_minimal_1:.4f}")

Output yang Dihasilkan:

text
P(K <= 1) = 0.5282
P(K >= 2) = 1 - P(K <= 1) = 0.4718
P(K >= 1) = 1 - P(K = 0) = 0.8319
P(K = 2 | K >= 1) = 0.3087 / 0.8319 = 0.3711

Perhatikan tiga kebiasaan membaca CDF pada hasil di atas:

  1. Baris 5 (binom.cdf(1, ...)): P(K ≤ 1) = 0,5282 menjumlahkan pmf(0) + pmf(1). Batas “kurang dari 2” dan “kurang dari sama dengan 1” adalah kalimat yang sama untuk bilangan bulat — hati-hati memilih argumennya.
  2. Baris 6 (binom.sf(1, ...)): survival function sf(k) = 1 − cdf(k) langsung menjawab P(K ≥ 2) = 0,4718 tanpa pengurangan manual.
  3. Baris 12-13 (probabilitas bersyarat): kita bahas probabilitas bersyarat di chapter sebelumnya, dan rumusnya hidup juga di sini — P(K = 2 | K ≥ 1) = P(K = 2)/P(K ≥ 1) = 0,3087/0,8319 = 0,3711. Ruang sampel menyempit menjadi “minimal ada satu pemesan”.

Poisson dan Eksponensial: Hitungan per Selang Waktu #

Dua distribusi terakhir chapter ini selalu datang berpasangan. Poisson menghitung banyaknya kejadian dalam satu selang waktu dengan laju rata-rata λ; eksponensial mengukur jeda antar kejadian pada proses yang sama. Di Toko Kopi Kita, jam sepi mencatat kedatangan rata-rata 3 pelanggan per jam: Poisson menjawab “berapa pelanggan pada jam berikutnya?”, eksponensial menjawab “berapa lama lagi sampai pelanggan berikutnya datang?”:

python
from scipy.stats import poisson, expon

# Kedatangan pelanggan di jam sepi: rata-rata 3 orang per jam
laju = 3
print(f"Poisson, rata-rata {laju} pelanggan per jam:")
for k in (0, 1, 2, 3):
    print(f"  P(K = {k}) = {poisson.pmf(k, laju):.4f}")
print(f"  P(K <= 2) = {poisson.cdf(2, laju):.4f}")

# Pasangannya: jeda antar kedatangan, rata-rata 1/3 jam = 20 menit
print(f"\nEksponensial, jeda rata-rata 20 menit:")
print(f"  P(jeda <= 20 menit) = {expon.cdf(20, scale=20):.4f}")
print(f"  P(jeda > 40 menit)  = {1 - expon.cdf(40, scale=20):.4f}")

Output yang Dihasilkan:

text
Poisson, rata-rata 3 pelanggan per jam:
  P(K = 0) = 0.0498
  P(K = 1) = 0.1494
  P(K = 2) = 0.2240
  P(K = 3) = 0.2240
  P(K <= 2) = 0.4232

Eksponensial, jeda rata-rata 20 menit:
  P(jeda <= 20 menit) = 0.6321
  P(jeda > 40 menit)  = 0.1353

Mari kita telaah hasilnya:

  1. Poisson cukup satu parameter: cukup laju λ = 3, dan baik rata-rata maupun variansnya sama-sama 3. Peluang jam tanpa pelanggan sama sekali hanya 0,0498 — rata-rata satu dari dua puluh jam — dan peluang terpadat berada di K = 2 dan K = 3.
  2. Eksponensial miring ke kanan: scale diisi rata-rata jeda 20 menit (kebalikan laju: 1/3 jam). Peluang menunggu tidak lebih dari rata-rata jeda justru 0,6321 — lebih dari separuh — karena distribusi ini menumpuk di jeda pendek dan menyisakan ekor panjang untuk jeda lama.
  3. Pasangan λ: Poisson dengan λ = 3 per jam dan eksponensial dengan rata-rata jeda 20 menit adalah dua wajah proses kedatangan yang sama. Mengubah salah satunya otomatis mengubah pasangannya.

Rangkuman #

  • Distribusi probabilitas adalah peta peluang variabel acak; PMF melayani variabel diskrit, PDF melayani variabel kontinu, dan CDF — P(X ≤ x) — adalah bahasa umum keduanya.
  • Seragam diskrit memberi peluang rata 1/n pada tiap nilai; CDF-nya berbentuk tangga.
  • Binomial menghitung banyaknya sukses dari n percobaan merdeka berpeluang p: P(X = k) = C(n,k)·p^k·(1−p)^(n−k), dengan E[X] = np dan Var(X) = np(1−p); binom.cdf dan binom.sf menjawab pertanyaan “minimal” dan “paling banyak”.
  • Poisson menghitung banyaknya kejadian per selang waktu (satu parameter λ); eksponensial adalah pasangannya untuk jeda antar kejadian, dengan rata-rata jeda = 1/λ.
  • scipy.stats menyediakan .pmf(), .pdf(), .cdf() untuk keluarga distribusi ini — cukup satu pola pemakaian untuk semuanya.

Empat distribusi ini baru permulaan. Satu anggota keluarga paling terkenal belum kita sentuh: kurva lonceng yang menaungi tinggi badan, hasil ujian, dan galat pengukuran — distribusi normal. Kita akan mempelajari bentuknya, dua parameternya, dan cara menstandardisasinya lewat z-score pada chapter Distribusi Normal .

Referensi #

  1. SciPy — scipy.stats: Statistical Functions
  2. Python — statistics: Mathematical statistics functions