Bab sebelumnya mengharuskan kita memilih satu ambang untuk melihat satu pasangan precision-recall. Kurva ROC (Receiver Operating Characteristic) membebaskan kita dari pilihan tersebut: kurva ini memeriksa model pada seluruh ambang sekaligus, dari paling ketat hingga paling longgar, lalu merangkumnya menjadi satu angka bernama AUC. Hasilnya adalah ukuran kualitas pemeringkatan — seberapa baik model menempatkan kasus positif di atas kasus negatif — yang tidak bergantung pada ambang mana pun yang akhirnya dipilih. Chapter ini membangun intuisi ROC dari fungsi roc_curve, membaca AUC dari tiga kandidat skor pada data yang sama, lalu membahas batas pentingnya: pada data yang sangat timpang, AUC yang tinggi bisa hidup berdampingan dengan precision yang runtuh.
Dua Sumbu Kurva ROC #
Kurva ROC digambar pada dua sumbu yang keduanya kita kenal dari bab-bab sebelumnya. Sumbu vertikal adalah TPR (True Positive Rate) — recall, yaitu TP / (TP + FN). Sumbu horizontal adalah FPR (False Positive Rate) — yaitu FP / (FP + TN), porsi transaksi sah yang keliru ditahan. Untuk setiap ambang keputusan yang mungkin, kita dapat satu titik (FPR, TPR); menghubungkan semua titik menghasilkan kurvanya. Ambang sangat ketat memberi titik di pojok kiri bawah (hampir tidak ada alarm: FPR kecil, TPR kecil); ambang sangat longgar memberi titik di pojok kanan atas (semua dibunyikan: TPR = 1, FPR = 1). Model yang baik menempel ke pojok kiri atas — recall tinggi dengan alarm palsu minimum.
AUC: Kualitas Pemeringkatan dalam Satu Angka #
AUC (Area Under the Curve) adalah luas di bawah kurva ROC, bernilai 0 sampai 1, dengan penafsiran yang sangat konkret: probabilitas bahwa satu kasus positif yang dipilih acak menerima skor lebih tinggi daripada satu kasus negatif yang dipilih acak. Penafsiran ini menjelaskan segala hal tentang AUC. Model acak memeringkatkan tanpa bekal — peluang positif di atas negatif 50% — sehingga AUC-nya 0,5 (kurva = diagonal). Model sempurna menempatkan seluruh positif di atas seluruh negatif sehingga AUC-nya 1,0. Model yang skor-nya terbalik (positif diberi skor rendah) menghasilkan AUC di bawah 0,5 — 0,125 pada contoh kita nanti. Karena AUC hanya membandingkan urutan skor, ia tidak peduli skala probabilitas dan tidak terpengaruh pilihan ambang; itulah yang membuatnya populer untuk membandingkan beberapa model sebelum menyetel ambang.
Tiga Kandidat Skor pada Data yang Sama #
Mari kita uji tiga kandidat skor pada 12 transaksi yang sama (4 penipuan, 8 sah) dan lihat bagaimana AUC membedakannya. Ketiga array skor ditulis sebagai nilai tetap — bukan hasil generator acak — supaya Anda bisa memeriksa urutannya baris demi baris.
# ROC dan AUC: menilai kualitas PEMERINGKATAN skor di seluruh ambang,
# bukan kinerja pada satu ambang saja.
import numpy as np
from sklearn.metrics import (
accuracy_score,
precision_score,
recall_score,
roc_auc_score,
roc_curve,
)
# --- Bagian 1: tiga kandidat skor untuk data yang sama ---
# 1 = penipuan (positif), 0 = sah. Terdapat 4 positif dan 8 negatif.
y_true = np.array([0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0])
# Semua skor di bawah adalah array tetap (bukan hasil rng) supaya
# contoh ini bisa dibaca ulang dan dibandingkan baris demi baris.
skor_bagus = np.array([0.89, 0.95, 0.10, 0.08, 0.86, 0.15,
0.90, 0.12, 0.07, 0.88, 0.09, 0.11])
skor_acak = np.array([0.48, 0.42, 0.31, 0.66, 0.36, 0.29,
0.55, 0.38, 0.60, 0.44, 0.53, 0.35])
skor_buruk = np.array([0.91, 0.12, 0.05, 0.83, 0.10, 0.88,
0.15, 0.89, 0.92, 0.11, 0.85, 0.87])
for nama, skor in (("bagus", skor_bagus), ("acak", skor_acak),
("buruk", skor_buruk)):
auc = roc_auc_score(y_true, skor)
print(f"Skor {nama:5s}: AUC = {auc:.3f}")
# --- Bagian 2: roc_curve pada skor bagus ---
# roc_curve menyusun titik (FPR, TPR) sambil menurunkan ambang keputusan.
fpr, tpr, ambang = roc_curve(y_true, skor_bagus)
print()
print("Ambang | FPR | TPR")
for i in range(len(ambang)):
print(f" {ambang[i]:>6.3f} | {fpr[i]:.3f} | {tpr[i]:.3f}")
# --- Bagian 3: peringatan ketidakseimbangan kelas ---
# 20 transaksi dengan HANYA 1 penipuan (5% positif).
y_timpang = np.zeros(20, dtype=int)
y_timpang[7] = 1
skor_timpang = np.array([0.31, 0.22, 0.91, 0.18, 0.40, 0.12, 0.27, 0.90,
0.15, 0.33, 0.21, 0.44, 0.09, 0.38, 0.26, 0.17,
0.47, 0.11, 0.29, 0.20])
auc_timpang = roc_auc_score(y_timpang, skor_timpang)
prediksi = (skor_timpang >= 0.895).astype(int) # ambang untuk menangkap si penipuan
presisi = precision_score(y_timpang, prediksi)
recall = recall_score(y_timpang, prediksi)
akurasi_semua_sah = accuracy_score(y_timpang, np.zeros(20, dtype=int))
print()
print(f"AUC pada data timpang = {auc_timpang:.3f}")
print(f"Presisi saat recall penuh = {presisi:.3f}")
print(f"Recall pada ambang tersebut = {recall:.3f}")
print(f"Akurasi model 'tebak semua sah' = {akurasi_semua_sah:.3f}")Output yang Dihasilkan:
Skor bagus: AUC = 0.938
Skor acak : AUC = 0.531
Skor buruk: AUC = 0.125
Ambang | FPR | TPR
inf | 0.000 | 0.000
0.950 | 0.000 | 0.250
0.900 | 0.000 | 0.500
0.890 | 0.125 | 0.500
0.860 | 0.125 | 1.000
0.070 | 1.000 | 1.000
AUC pada data timpang = 0.947
Presisi saat recall penuh = 0.500
Recall pada ambang tersebut = 1.000
Akurasi model 'tebak semua sah' = 0.950Mari kita telaah bagian-bagian pentingnya:
- Baris 19–24 (tiga array skor): pada
skor_bagus, keempat penipuan menerima skor 0,86–0,95 sementara tujuh dari delapan transaksi sah menerima skor di bawah 0,16 — urutan yang hampir sempurna, diganggu satu transaksi sah berskor 0,89.skor_acaktidak berpola;skor_burukmembalik urutan — penipuan justru menerima skor terendah. - Baris 26–29 (
roc_auc_score): satu pemanggilan menghasilkan AUC langsung dari pasangan label dan skor, tanpa perlu memilih ambang. - Baris 33 (
roc_curve): fungsi mengembalikan tiga array —fpr,tpr, danambang— tersusun dari ambang paling ketat ke paling longgar. Jumlah titiknya jauh lebih sedikit dari jumlah sampel karena hanya ambang yang mengubah pasangan (FPR, TPR) yang disimpan. - Baris 41–45 (bagian timpang): 20 transaksi dengan satu-satunya penipuan (indeks ke-7) menerima skor 0,90 — peringkat kedua tertinggi, tepat di bawah satu transaksi sah berskor 0,91. Ambang 0,895 dipilih agar si penipuan pasti tertangkap.
Output bagian pertama menegaskan penafsiran pemeringkatan. Skor bagus mencapai AUC 0,938: dari 32 pasangan positif-negatif yang mungkin, hanya 2 pasangan yang salah urutan (dua penipuan berskor 0,86 dan 0,88 kalah dari satu transaksi sah 0,89). Skor acak mendarat di 0,531 — nyaris tak beda dari lempar koin. Skor buruk jatuh ke 0,125, jauh di bawah koin: model yang skornya terbalik bisa “dijadikan baik” dengan membalik keputusannya, dan justru itu pesan AUC < 0,5.
Membaca Tabel roc_curve #
Tabel pada output bagian kedua adalah isi kurva ROC yang biasanya digambar. Baris pertama (ambang = inf) adalah titik awal (0, 0): ambang di atas skor tertinggi berarti belum ada transaksi yang ditandai. Menurunkan ambang ke 0,950 menangkap satu penipuan tanpa satu pun alarm palsu — TPR naik ke 0,250, FPR tetap 0. Pada ambang 0,860, keempat penipuan tertangkap (TPR = 1,000) dengan hanya satu alarm palsu (FPR = 0,125) — titik operasi yang nyaris ideal. Ambang terakhir 0,070 menandai semuanya: TPR dan FPR sama-sama 1. Kurva ROC penuh hanyalah seluruh baris tabel ini digambar dan dihubungkan; AUC adalah luas di bawahnya.
Kapan AUC Menyesatkan: Data Sangat Timpang #
Bagian ketiga output adalah peringatan yang sering diabaikan. Pada 20 transaksi dengan hanya 5% penipuan, model kita memeringkatkan si penipuan di posisi kedua — secara pemeringkatan sangat baik, dan AUC membaca 0,947. Namun saat ambang diturunkan sampai penipuan itu tertangkap (recall 1,0), satu transaksi sah yang berperingkat lebih tinggi ikut tertangkap: precision hanya 0,500. Setengah alarm adalah alarm palsu. Sementara itu model yang menebak “semua sah” mencatat akurasi 0,950 tanpa bekerja sama sekali.
Akar masalahnya: FPR mengukur galat relatif terhadap populasi negatif yang besar, sehingga sedikit galat pun “murah” di kurva ROC, padahal jumlah absolut alarm palsu tetap sama. Pada kelas positif yang sangat langka, kurva PR (precision-recall) dan average precision lebih jujur karena precision langsung memperhitungkan langkanya positif — gunakan precision_recall_curve pada situasi seperti ini. AUC tetap sah untuk membandingkan model pada data yang sama; ia hanya tidak boleh diterjemahkan sebagai “presisi pasti baik”.
Metrik apa pun yang dipilih, keputusan akhir tetap harus kembali ke pertanyaan bisnis: galat yang mana yang paling mahal, seberapa timpang kelasnya, dan siapa yang membaca angkanya. Kerangka untuk menjawab pertanyaan-pertanyaan tersebut adalah pokok bahasan Chapter Memilih Metrik yang Tepat.
Referensi Resmi #
- sklearn.metrics.roc_curve — API Reference — mekanika kurva ROC beserta parameter threshold yang diturunkan.
- sklearn.metrics.roc_auc_score — API Reference — perhitungan AUC untuk kasus biner dan multiclass.
- sklearn.metrics.precision_recall_curve — API Reference — alternatif yang lebih jujur untuk data kelas sangat langka.