Satu angka akurasi menyembunyikan jenis kesalahan yang dibuat oleh model. Confusion matrix menyandingkan label prediksi dengan label aktual dalam tabel berisi empat sel, sehingga kesalahan yang saling meniadakan di balik satu angka terlihat apa adanya. Topik ini membahas makna setiap sel, hubungan sel-sel itu dengan presisi dan recall, serta cara menampilkan matriks dan menghitung ulang metrik dari sel-selnya dengan scikit-learn. Hasil akhirnya adalah kebiasaan membaca jenis kesalahan terlebih dahulu sebelum menyimpulkan kualitas model.
Struktur empat sel#
Confusion matrix membandingkan dua informasi untuk setiap sampel data uji, yaitu label aktual dan label prediksi. Dengan dua kelas, hasilnya berupa empat sel seperti tabel berikut, dengan kelas ganas sebagai kelas positif.
| Prediksi ganas | Prediksi jinak | |
|---|---|---|
| Aktual ganas | TP, benar positif | FN, salah negatif |
| Aktual jinak | FP, salah positif | TN, benar negatif |
Sel (true positive) berisi sampel ganas yang diprediksi ganas, yaitu keputusan yang benar dan diinginkan. Sel (false negative) berisi tumor ganas yang lolos karena diprediksi jinak. Kesalahan ini termahal pada saringan penyakit karena penderita tidak dirujuk ke pengobatan.
Sel (false positive) berisi tumor jinak yang keliru diprediksi ganas, sehingga pasien menjalani pemeriksaan lanjutan yang tidak perlu. Sel (true negative) berisi tumor jinak yang diprediksi jinak, sehingga tidak ada tindakan yang diperlukan. Tabel yang sama dapat diperluas untuk lebih dari dua kelas, dan setiap barisnya masih mewakili label aktual.
Dari empat sel itu, presisi dan recall dapat dinyatakan ulang secara langsung:
Presisi menjumlahkan seluruh sel pada kolom prediksi positif dan mengambil bagian yang benar, sehingga presisi dibaca secara vertikal. Recall menjumlahkan seluruh sel pada baris aktual positif dan mengambil bagian yang tertangkap, sehingga recall dibaca secara horizontal. Akurasi adalah jumlah sel diagonal dan dibagi jumlah seluruh sel. Ketiga metrik dihitung dari tabel yang sama, dan kesamaan asal inilah yang menjadikan confusion matrix sebagai titik temu semua metrik klasifikasi.
Jumlah baris dan kolom matriks juga bermakna. Jumlah sel pada satu baris adalah banyaknya sampel dengan label aktual tersebut, sedangkan jumlah sel pada satu kolom adalah banyaknya sampel yang diprediksi sebagai kelas tersebut. Baris dan kolom yang timpang menandakan kelas yang tidak seimbang. Pada kondisi ini, satu angka akurasi mudah menyesatkan karena kelas terbanyak mendominasi penjumlahannya.
Membaca matriks dengan scikit-learn#
Fungsi confusion_matrix dari scikit-learn menghasilkan matriks dengan baris untuk label aktual dan kolom untuk label prediksi. Skrip berikut memuat dataset breast cancer dan memisahkan dua puluh persen data sebagai data uji dengan test_size=0.2 serta random_state=42. Pipeline StandardScaler dan LogisticRegression(max_iter=1000) kemudian dilatih pada data latih. Matriks tersebut ditampilkan sebagai DataFrame pandas dengan nama baris dan kolom, sehingga orientasinya tidak perlu dihafal. Setelah itu, presisi dan recall dihitung secara manual dari sel-sel matriks, lalu dibandingkan dengan precision_score dan recall_score.
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import confusion_matrix, precision_score, recall_score
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
pd.set_option("display.width", 80)
X, y = load_breast_cancer(return_X_y=True)
X_latih, X_uji, y_latih, y_uji = train_test_split(
X, y, test_size=0.2, random_state=42
)
model = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000))
model.fit(X_latih, y_latih)
prediksi = model.predict(X_uji)
matriks = confusion_matrix(y_uji, prediksi)
tabel = pd.DataFrame(
matriks,
index=["ganas (0)", "jinak (1)"],
columns=["ganas (0)", "jinak (1)"],
)
tabel.index.name = "aktual"
tabel.columns.name = "prediksi"
print(tabel)
# penghitungan manual dari sel-sel matriks
tp = int(matriks[0, 0]) # aktual ganas, prediksi ganas
fn = int(matriks[0, 1]) # aktual ganas, prediksi jinak
fp = int(matriks[1, 0]) # aktual jinak, prediksi ganas
tn = int(matriks[1, 1]) # aktual jinak, prediksi jinak
presisi_manual = tp / (tp + fp)
recall_manual = tp / (tp + fn)
print(f"TP = {tp}, FP = {fp}, FN = {fn}, TN = {tn}")
print(f"presisi manual = {presisi_manual:.4f}")
print(f"presisi sklearn = {precision_score(y_uji, prediksi, pos_label=0, zero_division=0):.4f}")
print(f"recall manual = {recall_manual:.4f}")
print(f"recall sklearn = {recall_score(y_uji, prediksi, pos_label=0, zero_division=0):.4f}")prediksi ganas (0) jinak (1)
aktual
ganas (0) 41 2
jinak (1) 1 70
TP = 41, FP = 1, FN = 2, TN = 70
presisi manual = 0.9762
presisi sklearn = 0.9762
recall manual = 0.9535
recall sklearn = 0.9535Matriks terbaca sebagai berikut. Sel berisi 41 tumor ganas yang diprediksi ganas, sedangkan sel berisi 2 tumor ganas yang lolos dan diprediksi jinak. Sel berisi 1 tumor jinak yang keliru diprediksi ganas, dan sel berisi 70 tumor jinak yang benar diprediksi jinak. Dua kesalahan inilah yang paling perlu diwaspadai pada konteks saringan penyakit, dan keberadaannya tidak terlihat dari angka akurasi 0.9737 saja.
Penghitungan manual memberi presisi dan recall . Hasilnya identik dengan keluaran fungsi precision_score dan recall_score. Kesamaan angka ini menegaskan bahwa metrik klasifikasi hanyalah ringkasan dari sel-sel matriks, bukan informasi yang berdiri sendiri.
Matriks juga menunjukkan arah perbaikan. Kesalahan yang banyak berarti ambang perlu diturunkan atau fitur yang lebih pembeda perlu dicari, sedangkan kesalahan yang banyak menunjukkan arah sebaliknya. Tanpa matriks, kedua pola ini bercampur menjadi satu angka kesalahan yang tidak dapat ditindaklanjuti.
Kesalahan umum#
- Membaca orientasi matriks secara terbalik. Penyebabnya adalah perbedaan konvensi antar pustaka, dan pembaca sering menganggap satu susunan berlaku secara universal. Konvensi scikit-learn menaruh label aktual pada baris dan label prediksi pada kolom, sehingga pembacaan yang terbalik menukar sel dengan sel . Perbaikannya adalah memeriksa orientasi dari dokumentasi pustaka yang digunakan sebelum sel-selnya dihitung.
- Menjumlahkan sel menjadi satu angka terlalu cepat. Penjumlahan mengembalikan kondisi awal, yaitu satu angka akurasi yang justru menyembunyikan jenis kesalahan yang sedang dicari. Kejadian ini sering muncul ketika laporan hanya memuat persentase kebenaran tanpa lampiran matriksnya. Perbaikannya adalah melaporkan sel-sel utama atau menyandingkan akurasi dengan presisi dan recall, sehingga komposisi kesalahannya tetap terlihat.
- Mengabaikan bahwa sel yang disebut bergantung pada kelas positif. Matriks yang sama memberi sel berbeda apabila kelas positifnya diubah dari ganas ke jinak, karena definisi sel mengikuti kelas yang dianggap positif, bukan isi matriksnya. Akibatnya, presisi yang dilaporkan bisa merujuk pada kelas yang berbeda dari yang dimaksud pembaca. Perbaikannya adalah menyatakan
pos_labelsecara eksplisit saat menghitung metrik per kelas, sehingga metrik yang dilaporkan merujuk pada kelas yang sama.
Ringkasan#
- Confusion matrix menyajikan empat jenis hasil prediksi sehingga jenis kesalahan terlihat, bukan hanya jumlahnya.
- Presisi dibaca secara vertikal pada kolom prediksi positif, sedangkan recall dibaca secara horizontal pada baris aktual positif.
confusion_matrixmenaruh label aktual pada baris dan label prediksi pada kolom.- Presisi dan recall dapat dihitung ulang langsung dari sel-sel matriks dan hasilnya identik dengan fungsi scikit-learn.
Referensi#
- Metrics and scoring: quantifying the quality of predictions — scikit-learn — Panduan resmi metrik klasifikasi termasuk pembahasan confusion matrix.
- sklearn.metrics.confusion_matrix — scikit-learn — Dokumentasi fungsi confusion matrix beserta definisi baris dan kolomnya.
- sklearn.metrics.precision_score — scikit-learn — Dokumentasi fungsi presisi yang dibandingkan dengan penghitungan manual.
- sklearn.metrics.recall_score — scikit-learn — Dokumentasi fungsi recall yang dibandingkan dengan penghitungan manual.