ROC dan AUC

Kurva ROC, threshold, dan ukuran kualitas yang bebas threshold.

Daftar isi

Kurva ROC (receiver operating characteristic) menggambarkan kemampuan model memisahkan dua kelas dengan memplot TPR terhadap FPR pada seluruh nilai threshold, sedangkan AUC (area under the curve) merangkum kurva itu menjadi satu bilangan luas. Topik ini membahas cara kedua laju dihitung dari confusion matrix, cara membaca keluaran roc_curve, interpretasi AUC, dan alasan AUC lebih tahan terhadap ketidakseimbangan daripada accuracy. Kurva disajikan sebagai titik-titik angka, bukan grafik, sehingga setiap nilai dapat dibaca langsung.

TPR dan FPR pada berbagai threshold#

Dua laju pada sumbu kurva ROC diturunkan dari confusion matrix. TPR (true positive rate) atau laju positif benar sama dengan recall, sedangkan FPR (false positive rate) atau laju positif palsu menghitung porsi negatif yang salah disangka positif. Satu laju saja tidak cukup untuk menilai model, karena model yang selalu menebak positif memiliki TPR 1.0 sekaligus FPR 1.0.

TPR=TPTP+FNFPR=FPFP+TN \text{TPR} = \frac{TP}{TP + FN} \qquad \text{FPR} = \frac{FP}{FP + TN}

Setiap nilai threshold menghasilkan satu pasang TPR dan FPR, sehingga menyapu threshold dari tinggi ke rendah melukiskan satu lintasan pada bidang tersebut. Titik (0, 0) berarti tidak ada satu pun prediksi positif, sedangkan titik (1, 1) berarti semua sampel diprediksi positif. Model acak menghasilkan lintasan yang menyusuri garis diagonal, sedangkan model yang memisahkan kedua kelas dengan baik melengkung ke sudut kiri atas, yaitu wilayah dengan TPR tinggi pada FPR rendah.

Membaca roc_curve dan roc_auc_score#

Fungsi roc_curve(y_true, y_score) menerima label aktual dan skor positif, biasanya probabilitas kelas 1 dari predict_proba, lalu mengembalikan tiga array bernama fpr, tpr, dan thresholds. Kode berikut mencetak beberapa baris pertama kurva beserta AUC dua pembanding.

python kurva-roc.py
from sklearn.datasets import make_classification
from sklearn.dummy import DummyClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score, roc_curve
from sklearn.model_selection import train_test_split

X, y = make_classification(
    n_samples=600, n_features=6, n_informative=3, n_redundant=0,
    weights=[0.95, 0.05], random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)
model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)
proba = model.predict_proba(X_test)[:, 1]

fpr, tpr, thresholds = roc_curve(y_test, proba)
print("Jumlah titik pada kurva:", len(thresholds))
print("threshold   fpr     tpr")
for i in range(6):
    print(f"{thresholds[i]:>9.4f} {fpr[i]:>7.4f} {tpr[i]:>7.4f}")
print()
print("AUC LogisticRegression:", round(roc_auc_score(y_test, proba), 4))

dummy = DummyClassifier(strategy="most_frequent")
dummy.fit(X_train, y_train)
proba_dummy = dummy.predict_proba(X_test)[:, 1]
print("AUC DummyClassifier   :", round(roc_auc_score(y_test, proba_dummy), 4))
text Keluaran
Jumlah titik pada kurva: 8
threshold   fpr     tpr
      inf  0.0000  0.0000
   0.8904  0.0000  0.1667
   0.3982  0.0000  0.5000
   0.2910  0.0263  0.5000
   0.2889  0.0263  0.6667
   0.1371  0.0877  0.6667

AUC LogisticRegression: 0.9664
AUC DummyClassifier   : 0.5

Baris pertama keluaran memuat threshold tak berhingga (inf) dengan TPR dan FPR nol, yaitu titik asal kurva ketika tidak ada satu pun prediksi positif. Menyusuri baris berikutnya, threshold yang menurun membuat TPR naik lebih cepat daripada FPR pada model yang baik, dan pola itu terlihat pada tabel di atas. Kurva lengkapnya hanya memuat 8 titik karena roc_curve menyimpan satu titik untuk tiap perubahan hasil prediksi, bukan satu titik untuk tiap sampel.

Isi tabel juga dapat dibaca ke arah sebaliknya, yaitu memilih threshold kerja dari kurva. Pada threshold 0.8904, satu sampel minoritas sudah tertangkap dengan FPR masih nol, sedangkan pada threshold 0.1371 TPR mencapai 0.6667 dengan FPR baru 0.0877. Penurunan threshold berikutnya menambah TPR lebih lambat daripada FPR, sehingga wilayah itu menjadi batas wajar pemilihan threshold sebelum precision terlalu jauh turun.

Skor AUC dihitung dengan roc_auc_score terhadap probabilitas positif. LogisticRegression mencatat 0.9664, sedangkan DummyClassifier mencatat 0.5. Angka 0.5 adalah tebakan acak karena skor baseline tidak membedakan apa pun antara kedua kelas, dan 1.0 adalah pemisahan sempurna. Nilai yang dianggap baik di lapangan bergantung pada domainnya, sehingga AUC paling tepat digunakan untuk membandingkan model pada data uji yang sama.

Mengapa AUC digunakan#

AUC memiliki interpretasi probabilistik, yaitu peluang sebuah sampel positif yang diambil acak memperoleh skor lebih tinggi daripada sampel negatif yang diambil acak. Nilai 1.0 berarti setiap positif diskor lebih tinggi daripada setiap negatif, dan 0.5 berarti skor kedua kelas tidak terbedakan. Interpretasi ini membuat AUC tidak menuntut pemilihan threshold, sehingga perbandingan antarmodel dapat dilakukan pada tingkat pemeringkatan (ranking), yaitu urutan sampel dari skor tertinggi ke terendah.

Ketahanannya terhadap ketidakseimbangan juga lebih baik daripada accuracy. Accuracy menghukum keputusan pada satu threshold tetap, biasanya 0.5, dan sangat dipengaruhi proporsi kelas, sedangkan AUC menilai seluruh lintasan threshold sekaligus. Pada data 95:5, model dengan skor threshold 0.5 yang kecil tetap dapat memiliki AUC tinggi karena kualitas pemeringkatannya baik, dan sebaliknya accuracy tinggi dapat dimiliki model yang AUC-nya hanya 0.5 seperti baseline di atas. Karena itu, AUC cocok untuk memilih model, sedangkan threshold operasional beserta precision dan recall pada threshold itu tetap ditentukan dari kebutuhan domain.

Kesalahan umum#

Tiga kesalahan berikut sering muncul saat menggunakan ROC dan AUC.

  • Menghitung AUC dari keluaran predict yang berisi label 0 dan 1, alih-alih probabilitas dari predict_proba, sehingga sebagian besar informasi pemeringkatan hilang dan AUC tidak lagi mengukur kemampuan model yang sesungguhnya. Perbaikannya, selalu beri skor probabilitas kelas positif.
  • Membandingkan AUC antar dataset yang berbeda, padahal AUC hanya bermakna untuk model-model yang dinilai pada data uji yang sama. Perbaikannya, bandingkan model pada data uji yang identik.
  • Memakai AUC sebagai satu-satunya bukti mutu ketika biaya FN dan FP berbeda jauh. Perbaikannya, tetapkan threshold operasional lalu laporkan precision dan recall pada threshold tersebut.

Ringkasan#

  • Kurva ROC memplot TPR terhadap FPR yang keduanya diturunkan dari confusion matrix pada setiap nilai threshold.
  • roc_curve mengembalikan fpr, tpr, dan thresholds, dengan titik pertama pada threshold tak berhingga.
  • AUC adalah luas di bawah kurva ROC, dengan 0.5 sebagai tebakan acak dan 1.0 sebagai pemisahan sempurna, dan terbaca sebagai peluang positif diskor lebih tinggi daripada negatif.
  • AUC menilai kualitas pemeringkatan tanpa memilih threshold, sehingga lebih tahan terhadap ketidakseimbangan daripada accuracy.

Referensi#