Chapter sebelumnya menutup dengan distribusi keyakinan Bayesian atas sebuah parameter: bukan satu angka konversi, melainkan rentang beserta derajat keyakinannya. Pada chapter ini kita membawa cara berpikir itu ke ranah yang lebih luas — uncertainty quantification, seni melaporkan ketidakpastian pada setiap keluaran analisis dan prediksi model. Sebuah prediksi “besok terjual 58 gelas” tanpa keterangan rentang hampir selalu terlalu percaya diri; manajer toko yang menyiapkan stok 58 gelas akan kehabisan barang di separuh hari. Kita mulai dari peta dua sumber ketidakpastian, membedakan interval kepercayaan dari interval prediksi, membaca predict_proba sebagai ketidakpastian model klasifikasi, lalu menutup dengan prediksi kuantil yang menghasilkan interval menyesuaikan data.
Dua Sumber Ketidakpastian: Epistemic dan Aleatoric #
Semua bentuk ketidakpastian bermuara ke dua sumber yang berbeda nasibnya. Ketidakpastian epistemic berasal dari ketidaktahuan kita — data masih sedikit, model belum melihat cukup contoh, fitur penting belum terukur. Ketidakpastian aleatoric berasal dari derau bawaan masalah itu sendiri — dua pelanggan dengan profil sama tetap bisa memilih menu berbeda, dua hari bersuhu sama tetap menghasilkan penjualan berbeda.
| Aspek | Epistemic | Aleatoric |
|---|---|---|
| Asal usul | ketidaktahuan model/pengamat | keacakan bawaan proses |
| Contoh | prediksi wilayah yang jarang dikunjungi pelanggan | selisih penjualan antar hari yang sibuk |
| Bisa dikurangi? | ya — tambah data, perbaiki model, ukur fitur baru | tidak — hanya bisa dilaporkan selebar apa adanya |
| Penanganan praktis | kumpulkan data lagi sebelum memutuskan | siapkan buffer stok, rancang skenario terburuk |
Pembedaan ini penting karena keduanya menuntut tindakan yang berlawanan. Ketidakpastian epistemic yang dominan berarti jawabannya adalah mengumpulkan data atau menunggu — memaksa model memberi angka pasti hanya mengarang. Ketidakpastian aleatoric yang dominan berarti tidak ada data tambahan yang bisa menolong; yang dibutuhkan adalah keputusan yang tahan terhadap sebaran, misalnya menyimpan stok untuk persentil ke-90 permintaan, bukan rata-ratanya.
Interval Kepercayaan vs Interval Prediksi #
Dua istilah ini sering tertukar padahal menjawab pertanyaan berbeda. Interval kepercayaan (confidence interval) menyatakan ketidakpastian kita tentang parameter — misalnya rata-rata penjualan harian sejati; konsep ini sudah kita dalami pada chapter Interval Kepercayaan . Interval prediksi (prediction interval) menyatakan rentang yang memuat satu observasi baru dengan tingkat keyakinan tertentu. Parameter tidak berubah-ubah sehingga intervalnya menyempit seiring data; observasi baru selalu membawa derau segar sehingga intervalnya tetap lebar.
Kita bandingkan keduanya pada 12 hari data penjualan Toko Kopi Kita:
import numpy as np
from scipy import stats
# 12 hari penjualan gelas kopi (data beku, deterministik)
penjualan = np.array([46, 52, 44, 58, 49, 41, 55, 47, 51, 43, 57, 48])
n = len(penjualan)
rerata = penjualan.mean()
simpangan = penjualan.std(ddof=1)
galat_baku = simpangan / np.sqrt(n)
t = stats.t.ppf(0.975, df=n - 1)
ci_rerata = rerata - t * galat_baku, rerata + t * galat_baku
pi_baru = (rerata - t * simpangan * np.sqrt(1 + 1 / n),
rerata + t * simpangan * np.sqrt(1 + 1 / n))
print(f"Rata-rata 12 hari : {rerata:.2f} gelas")
print(f"Simpangan baku sampel : {simpangan:.2f}")
print(f"Interval kepercayaan 95% : {ci_rerata[0]:.2f} - {ci_rerata[1]:.2f} gelas")
print(f"Interval prediksi 95% : {pi_baru[0]:.2f} - {pi_baru[1]:.2f} gelas")
print(f"Lebar CI : {ci_rerata[1] - ci_rerata[0]:.2f} | Lebar PI : {pi_baru[1] - pi_baru[0]:.2f}")Output yang Dihasilkan:
Rata-rata 12 hari : 49.25 gelas
Simpangan baku sampel : 5.50
Interval kepercayaan 95% : 45.76 - 52.74 gelas
Interval prediksi 95% : 36.66 - 61.84 gelas
Lebar CI : 6.98 | Lebar PI : 25.18Mari kita telaah baris-baris pentingnya:
- Baris 12 (
t = stats.t.ppf(0.975, df=n - 1)): kita meminta nilai t sehingga 97,5% luas distribusi-t berada di kirinya; dipakai untuk kedua sisi interval sehingga total cakupan 95%. Distribusi-t (bukan normal) dipilih karena simpangan baku pun ikut diestimasi dari sampel kecil. - Baris 14-15 (
ci_rerata): galat baku membagi simpangan dengansqrt(n), sehingga interval kepercayaan rata-rata hanya selebar 6,98 gelas — makin banyak hari teramati, makin tajam dugaan kita tentang rata-rata sejati. - Baris 16-17 (
pi_baru): untuk satu hari baru, derau harian tidak menipis oleh jumlah data, jadi simpangan dipakai utuh dikali faktorsqrt(1 + 1/n)(faktor kecil yang mengakui estimasi rerata juga bisa meleset). Hasilnya 25,18 gelas — sekitar 3,6 kali lebar interval kepercayaan.
Salah membaca jenis interval berujung pada keputusan stok yang keliru: memakai 45,76-52,74 (interval parameter!) sebagai rentang penjualan besok membuat toko kehabisan kopi hampir setiap hari di atas rata-rata. Untuk keputusan operasional harian, interval prediksi-lah yang relevan.
predict_proba: Ketidakpastian pada Klasifikasi #
Pada klasifikasi, ketidakpastian model tersaji sebagai probabilitas lewat predict_proba — kemampuan yang sudah kita pakai sejak chapter-chapter machine learning pertama. Angka ini memadukan dua sumber ketidakpastian: model yang belum belajar cukup (epistemic) dan batas keputusan yang memang melintasi wilayah abu-abu (aleatoric). Kita latih model kecil status member dari frekuensi kunjungan 24 pelanggan:
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
# 24 pelanggan: frekuensi kunjungan per bulan vs status member
frekuensi = np.array([0.5, 0.8, 1.0, 1.2, 1.5, 1.8, 2.0, 2.2, 2.5, 2.8, 3.0, 3.2,
3.5, 3.8, 4.0, 4.2, 4.5, 4.8, 5.0, 5.2, 5.5, 5.8, 6.0, 6.5])
member = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
model = LogisticRegression().fit(frekuensi.reshape(-1, 1), member)
pelanggan_baru = np.array([[1.0], [3.4], [6.0]])
peluang = model.predict_proba(pelanggan_baru)
hasil = pd.DataFrame({
"kunjungan_bulan": pelanggan_baru.ravel(),
"P(bukan member)": peluang[:, 0].round(3),
"P(member)": peluang[:, 1].round(3),
"prediksi": model.predict(pelanggan_baru),
})
print(hasil.to_string(index=False))Output yang Dihasilkan:
kunjungan_bulan P(bukan member) P(member) prediksi
1.0 0.985 0.015 0
3.4 0.489 0.511 1
6.0 0.010 0.990 1Bedah hasilnya:
- Pelanggan 1,0 kunjungan: probabilitas 0,985/0,015 — nyaris pasti bukan member. Model sanggup yakin karena banyak contoh serupa di data latih.
- Pelanggan 3,4 kunjungan: 0,489 lawan 0,511 — praktis lempar koin. Label “member” menang tipis, tetapi keputusan berbasis angka ini sebaiknya ditunda atau ditanyakan langsung ke pelanggan; di sinilah ketidakpastian aleatoric wilayah perbatasan muncul.
- Pelanggan 6,0 kunjungan: 0,990 — model kembali sangat yakin. Perhatikan polanya: probabilitas ekstrem pada wilayah yang dikenalnya, probabilitas tengah pada perbatasan kelas.
Prediksi Kuantil: Interval yang Menyesuaikan Data #
Interval prediksi pada bagian sebelumnya berbentuk simetris dan selebar itu terus — padahal dunia nyata sering tidak seimbang: penjualan kopi saat cuaca sedang stabil perilakunya, saat panas terik keragamannya melebar. Prediksi kuantil menjawab dengan melatih model memperkirakan persentil tertentu dari target — konsep persentil yang sudah kita kenal di chapter Persentil dan Kuartil . Dua model dipakai sebagai batas: model persentil ke-10 sebagai batas bawah dan ke-90 sebagai batas atas, sehingga keduanya memuat 80% observasi.
Kita pakai GradientBoostingRegressor dengan loss="quantile" pada 40 hari data suhu dan penjualan:
import numpy as np
import pandas as pd
from sklearn.ensemble import GradientBoostingRegressor
rng = np.random.default_rng(42)
# 40 hari penjualan: gelas terjual naik dengan suhu, derau melebar saat panas
suhu = rng.uniform(22, 32, 40)
derau = rng.normal(0, 3, 40) + 1.1 * (suhu - 22)
gelas = 40 + 3.5 * (suhu - 25) + derau
def model_kuantil(alpha):
return GradientBoostingRegressor(
loss="quantile", alpha=alpha, n_estimators=100, random_state=42
)
bawah = model_kuantil(0.1).fit(suhu.reshape(-1, 1), gelas)
tengah = model_kuantil(0.5).fit(suhu.reshape(-1, 1), gelas)
atas = model_kuantil(0.9).fit(suhu.reshape(-1, 1), gelas)
suhu_baru = np.array([[24.0], [28.0], [31.5]])
hasil = pd.DataFrame({
"suhu": suhu_baru.ravel(),
"batas_bawah_q10": bawah.predict(suhu_baru).round(1),
"tengah_q50": tengah.predict(suhu_baru).round(1),
"batas_atas_q90": atas.predict(suhu_baru).round(1),
})
hasil["lebar_interval"] = (hasil["batas_atas_q90"] - hasil["batas_bawah_q10"]).round(1)
print("Interval prediksi 80% (q10 sampai q90) pada tiga suhu:")
print(hasil.to_string(index=False))
tercakup = (gelas >= bawah.predict(suhu.reshape(-1, 1))) & (
gelas <= atas.predict(suhu.reshape(-1, 1))
)
print(f"\nCakupan empiris interval pada 40 hari data: {tercakup.mean():.2f}")Output yang Dihasilkan:
Interval prediksi 80% (q10 sampai q90) pada tiga suhu:
suhu batas_bawah_q10 tengah_q50 batas_atas_q90 lebar_interval
24.0 38.5 40.7 47.4 8.9
28.0 55.1 56.4 61.5 6.4
31.5 59.3 70.6 70.9 11.6
Cakupan empiris interval pada 40 hari data: 0.80Mari kita baca hasilnya:
- Baris 24-27 (tiga model terpisah): satu model per persentil —
alpha=0.1,0.5,0.9— masing-masing meminimalkan galat kuantil, bukan galat kuadrat rata-rata. Modelalpha=0.5memperkirakan median, lebih tahan terhadap pencilan daripada rata-rata. - Lebar interval yang berubah-ubah: 6,4 gelas di suhu 28 (penjualan paling stabil) membengkak menjadi 11,6 gelas di suhu 31,5 — di wilayah panas, keragaman permintaan melebar sehingga interval ikut melapang. Interval simetris statis tidak bisa menangkap perilaku ini.
- Cakupan empiris 0,80: dari 40 hari data, 80% nilai nyata jatuh di antara kedua batas — persis target interval 80% (q10 ke q90). Memeriksa cakupan empiris seperti ini adalah cara cepat menilai apakah interval yang dilaporkan model bisa dipercaya.
Rangkuman #
- Ketidakpastian epistemic (ketidaktahuan model) bisa dikurangi dengan data; ketidakpastian aleatoric (derau bawaan) hanya bisa dilaporkan — keduanya menuntut tindakan yang berbeda.
- Interval kepercayaan menyasar parameter dan menyempit dengan
sqrt(n); interval prediksi menyasar satu observasi baru dan tetap lebar — 6,98 lawan 25,18 gelas pada contoh 12 hari penjualan kita. predict_probamelaporkan ketidakpastian model klasifikasi: probabilitas dekat 0,5 menandai wilayah perbatasan yang layak ditunda keputusannya, asalkan model terkalibrasi.- Prediksi kuantil (
loss="quantile"pada GradientBoostingRegressor) menghasilkan interval adaptif yang melebar-menyesempit mengikuti keragaman lokal data, dengan cakupan empiris yang bisa diperiksa langsung.
Sejauh ini seluruh analisis kita diam-diam mengandaikan dunia berhenti bergerak: model yang dilatih hari ini diasumsikan masih sahih bulan depan. Kenyataannya perilaku pelanggan, harga, dan musim terus bergeser — prediksi yang yakin hari ini bisa diam-diam menjadi keliru tanpa kita sadari. Bagaimana mendeteksi pergeseran itu sebelum merugikan? Itulah tugas chapter berikutnya: Drift Detection .
Referensi: