Kolom tanggal sudah bertipe benar, dan catatan pemeriksaan awal kita tinggal satu dugaan yang belum dibuktikan: harga 240000 untuk segelas kopi susu — sepuluh kali lipat harga menunya. Nilai yang menjulang jauh dari kawanannya disebut pencilan (outlier), dan ia menuntut keputusan yang tidak bisa didelegasikan ke fungsi mana pun: apakah ini salah ketik yang harus dikoreksi, atau transaksi besar yang sah? Pada chapter ini kita mendeteksi pencilan dengan dua metode klasik — pagar IQR dan z-score — lalu membandingkan empat strategi tindak lanjut beserta dampaknya pada rata-rata dan median.
Pencilan: Kesalahan Ketik atau Kejadian Nyata #
Sebelum mendeteksi, kita perlu mengakui bahwa pencilan punya tiga wajah yang berbeda nasibnya. Ketiganya tampak sama di data — angka yang jauh dari kerumunan — tetapi tindakan yang benar bertolak belakang. Perhatikan tabel berikut.
| Wajah pencilan | Contoh di Toko Kopi Kita | Tindakan yang tepat |
|---|---|---|
| Salah ketik atau galat input | Harga 240000 untuk kopi susu | Koreksi berdasarkan sumber tepercaya |
| Kejadian sah yang langka | Pesanan katering 100 gelas sekaligus | Pertahankan; mungkin justru temuan terpenting |
| Kejadian yang mencurigakan | Transaksi berulang jauh di atas kebiasaan | Tandai dan telusuri lebih lanjut |
Metode deteksi hanya menunjukkan di mana nilai menjauh dari kerumunan; memutuskan wajah mana yang sedang kita hadapi adalah pekerjaan pemahaman domain — ingat tiga komponen data science dari pembuka Course ini. Data latihan kita memuat dua belas harga transaksi: sebelas di antaranya bergerak antara 20000 dan 28000, satu lagi tertulis 240000.
Metode IQR: Pagar dari Kuartil #
Metode IQR membangun pagar dari kuartil — nilai yang membagi data terurut menjadi empat bagian. Jangkauan antar-kuartil (interquartile range, IQR) adalah lebar kotak tengah data; nilai yang menjauh lebih dari satu setengah kali lebar kotak itu dari tepinya dinyatakan pencilan. Rumusnya ringkas:
IQR = Q3 − Q1
pagar bawah = Q1 − 1,5 × IQR
pagar atas = Q3 + 1,5 × IQRAngka pengali 1,5 adalah konvensi yang dipopulerkan John Tukey: cukup lebar agar data wajar tidak salah tandai, cukup sempit agar pencilan sejati tertangkap. Mari kita hitung pagarnya dengan pandas.
import pandas as pd
harga = pd.Series([24000, 20000, 24000, 28000, 22000, 20000, 24000,
22000, 22000, 240000, 28000, 28000], name="harga")
q1 = harga.quantile(0.25)
q3 = harga.quantile(0.75)
iqr = q3 - q1
pagar_bawah = q1 - 1.5 * iqr
pagar_atas = q3 + 1.5 * iqr
print("Q1:", q1, "| Q3:", q3, "| IQR:", iqr)
print("Pagar bawah:", pagar_bawah, "| pagar atas:", pagar_atas)
print()
pencilan = harga[(harga < pagar_bawah) | (harga > pagar_atas)]
print("Pencilan menurut IQR:", pencilan.tolist())Output yang Dihasilkan:
Q1: 22000.0 | Q3: 28000.0 | IQR: 6000.0
Pagar bawah: 13000.0 | pagar atas: 37000.0
Pencilan menurut IQR: [240000]Mari kita telaah hitungannya:
- Baris 6-8 (
quantile(0.25),quantile(0.75),iqr): kuartil pertama 22000 dan kuartil ketiga 28000 membingkai kotak tengah tempat separuh data berkumpul. IQR-nya 6000 — sempit, karena sebelas harga wajar kita memang seragam. - Baris 9-10 (pagar bawah dan atas): 22000 − 9000 = 13000 dan 28000 + 9000 = 37000. Seluruh harga wajar (20000 sampai 28000) berdiri nyaman di dalam pagar.
- Baris 15-16 (saring pencilan): harga yang berada di luar pagar dikumpulkan dengan operasi perbandingan
|. Hasilnya satu nilai: 240000 — dugaan kita dari chapter pemeriksaan awal akhirnya terbukti secara hitungan.
Kekuatan IQR ada pada bahannya: kuartil dihitung dari peringkat data, bukan dari rata-rata, sehingga pencilan sendiri tidak ikut menentukan pagar. Metode ini tahan (robust) — pagar tetap sama meski pencilannya semakin jauh melonjak.
Metode Z-Score: Jarak dalam Satuan Simpangan Baku #
Z-score mengukur jarak sebuah nilai dari rata-rata, dalam satuan simpangan baku:
z = (x − rata-rata) / simpangan baku
pencilan bila |z| > 3Nilai dengan z-score melebihi 3 berarti letaknya lebih dari tiga simpangan baku dari rata-rata — pada distribusi normal, nyaris seluruh data berada di dalam zona itu. Ambang 3 adalah konvensi yang lazim; pustaka SciPy
menyediakan scipy.stats.zscore bila kita ingin memakai fungsi siap pakai, tetapi hitungannya memang sepanjang satu baris.
import pandas as pd
harga = pd.Series([24000, 20000, 24000, 28000, 22000, 20000, 24000,
22000, 22000, 240000, 28000, 28000], name="harga")
z = (harga - harga.mean()) / harga.std()
print("Rata-rata:", round(harga.mean(), 2))
print("Simpangan baku:", round(harga.std(), 2))
print()
print(z.round(2).tolist())
print()
print("Pencilan menurut z-score:", harga[z.abs() > 3].tolist())Output yang Dihasilkan:
Rata-rata: 41833.33
Simpangan baku: 62473.02
[-0.29, -0.35, -0.29, -0.22, -0.32, -0.35, -0.29, -0.32, -0.32, 3.17, -0.22, -0.22]
Pencilan menurut z-score: [240000]Mari kita telaah angka-angkanya:
- Baris 6 (
z = (harga - harga.mean()) / harga.std()): setiap harga dikurangi rata-rata lalu dibagi simpangan baku. Sebelas harga wajar menghasilkan z negatif kecil (−0,22 sampai −0,35) — semuanya di bawah rata-rata yang ternoda. - Rata-rata 41833 dan simpangan baku 62473: keduanya tertarik jauh ke atas oleh satu nilai 240000. Padahal sebelas harga wajar berkisar 20000-28000 dengan rata-rata sebenarnya hanya 23818. Pencilan meracuni alat ukurnya sendiri.
- z pencilan hanya 3,17: nilai 240000 berjarak 3,17 simpangan baku dari rata-rata — lolos ambang 3, tetapi nyaris tidak. Pada data kecil, z-score praktis tidak bisa melampaui 3 dengan jauh: dengan 12 baris, nilai z tertinggi yang mungkin secara matematis hanyalah sekitar 3,18.
Kedua metode akhirnya sepakat menandai satu nilai yang sama, tetapi jalan yang mereka tempuh berbeda. Tabel berikut merangkum perbedaan itu.
| Aspek | IQR | Z-score |
|---|---|---|
| Bahan hitung | Kuartil (peringkat data) | Rata-rata dan simpangan baku |
| Tahan pencilan | Ya — pagar tak ikut bergeser | Tidak — ukuran ikut tertarik |
| Cocok untuk | Data kecil hingga sedang, distribusi miring | Data besar, sebaran kira-kira normal |
| Ambang | 1,5 × IQR (konvensi Tukey) | |z| > 3 |
Menghapus, Membatasi, atau Mengoreksi #
Terdeteksi hanyalah setengah pekerjaan; kini kita putuskan tindakannya. Empat strategi yang umum: membiarkan apa adanya, menghapus, membatasi di pagar (cap, juga disebut winsorize), dan mengoreksi berdasarkan sumber lain. Kita bandingkan dampaknya pada dua ukuran pemusatan sekaligus.
import pandas as pd
harga = pd.Series([24000, 20000, 24000, 28000, 22000, 20000, 24000,
22000, 22000, 240000, 28000, 28000], name="harga")
q1 = harga.quantile(0.25)
q3 = harga.quantile(0.75)
pagar_bawah = q1 - 1.5 * (q3 - q1)
pagar_atas = q3 + 1.5 * (q3 - q1)
dihapus = harga[harga.between(pagar_bawah, pagar_atas)]
dibatasi = harga.clip(lower=pagar_bawah, upper=pagar_atas)
dikoreksi = harga.replace(240000, 24000)
ringkas = pd.DataFrame({
"strategi": ["apa adanya", "hapus", "batasi (cap)", "koreksi"],
"rata_rata": [harga.mean(), dihapus.mean(),
dibatasi.mean(), dikoreksi.mean()],
"median": [harga.median(), dihapus.median(),
dibatasi.median(), dikoreksi.median()],
})
print(ringkas.round(2))Output yang Dihasilkan:
strategi rata_rata median
0 apa adanya 41833.33 24000.0
1 hapus 23818.18 24000.0
2 batasi (cap) 24916.67 24000.0
3 koreksi 23833.33 24000.0Mari kita telaah dampak tiap strategi:
- Baris 11 (
between): strategi hapus menyaring hanya harga di dalam pagar — sebelas baris bertahan, dan rata-ratanya turun dari 41833 ke 23818. - Baris 12 (
clip): strategi batasi tidak membuang baris; nilai 240000 dipangkas menjadi pagar atas 37000. Rata-ratanya 24917 — tetap terdistorsi nilai buatan, tetapi jauh lebih sehat. - Baris 13 (
replace(240000, 24000)): koreksi berbasis bukti. Daftar harga Toko Kopi Kita menyebut kopi susu seharga 24000 — berarti 240000 hampir pasti salah ketik satu angka nol. Rata-rata 23833 adalah yang paling dekat dengan kenyataan. - Kolom
median: 24000 pada keempat baris. Median sama sekali tidak bergeser karena dihitung dari peringkat tengah — bukti lagi bahwa median adalah ukuran pemusatan yang tahan pencilan, dan alasan laporan yang sering dikunjungi pencilan sebaiknya memakai median.
Rangkuman #
- Pencilan punya tiga wajah — salah ketik, kejadian sah langka, kejadian mencurigakan — dan tindakannya bertolak belakang; deteksi tidak menggantikan pertimbangan domain.
- IQR menandai pencilan lewat pagar
Q1 − 1,5 × IQRdanQ3 + 1,5 × IQR; pagarnya tahan pencilan karena berbasis kuartil. - Z-score
z = (x − rata-rata) / simpangan bakudengan ambang 3 mudah dihitung, tetapi alat ukurnya ikut terpapar pencilan — pada data kecil, z nyaris tak melampaui 3. - Empat strategi — biarkan, hapus, batasi, koreksi — memberi rata-rata yang berbeda; median tidak tergerak oleh salah satu pun.
- Koreksi berbasis bukti paling jujur bila sumber pembanding tersedia, seperti daftar harga untuk kasus 240000 kita.
Harga 240000 telah dikoreksi dan seluruh kolom data penjualan kini wajar. Namun sepanjang perjalanan ini kita selalu bekerja pada satu tabel, sedangkan data nyata datang terpisah-pisah: rekap Januari di satu berkas, rekap Februari di berkas lain, dan data pelanggan di tabel yang berbeda lagi. Kita pelajari cara menumpuk dan menggabungkannya pada chapter berikutnya, Menggabungkan Dataset .