Literasi Evaluasi

Memilih metrik yang cocok dengan biaya keputusan bisnis, bukan sekadar akurasi.

Daftar isi

Metrik evaluasi adalah jembatan antara model dan keputusan, dan memilihnya sebelum melatih adalah bagian dari desain, bukan pelaporan. Topik ini memperagakan cara akurasi menipu pada kelas yang timpang, membaca matriks kebingungan sebagai sumber kebenarannya, dan mengaitkan presisi serta recall dengan biaya kesalahan yang berbeda. Setelah membacanya, setiap model dinilai dengan metrik yang menyatakan biaya keputusannya, dan angka 0.923 tidak lagi otomatis berarti bagus.

Akurasi menipu pada kelas yang timpang#

Akurasi menghitung proporsi tebakan yang benar, dan pada kelas yang timpang ia dapat tinggi sambil sama sekali tidak berguna. Model yang menebak kelas mayoritas untuk semua baris mencapai akurasi sebesar prevalensinya, dan itu persis yang diperlihatkan dataset latihan dengan kelas positif “jam sibuk” yang prevalensinya 7.7 persen.

Skrip berikut membandingkan baseline kelas mayoritas dengan regresi logistik pada target yang timpang itu, lengkap dengan matriks kebingungan dan dua metrik yang membedakan jenis kesalahannya.

python literasi_evaluasi.py
"""Literasi evaluasi: akurasi menipu, presisi dan recall menjawab biaya."""
import pandas as pd
from sklearn.dummy import DummyClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix, precision_score, recall_score
from sklearn.model_selection import train_test_split

data = pd.read_csv(
    "ukuran_udara.csv",
    na_values=["kosong", "-999.0"],
    dtype={"pm25": "string", "kelembapan": "string"},
)
data["pm25"] = data["pm25"].astype("float")
data["kelembapan"] = data["kelembapan"].str.replace(",", ".", regex=False).astype("float")
data["waktu"] = pd.to_datetime(data["waktu"], format="mixed", dayfirst=True)
data["stasiun"] = (
    data["stasiun"].str.strip().str.replace(r"\s+", " ", regex=True).str.title()
)
sah = data[data["pm25"] < 500].dropna(subset=["pm25", "suhu_c", "kelembapan"])
sah = sah.copy()
sah["sibuk"] = sah["waktu"].dt.hour.between(7, 9)     # kelas positif: jam sibuk

X = pd.get_dummies(sah[["stasiun", "suhu_c", "kelembapan"]], columns=["stasiun"])
y = sah["sibuk"]
X_latih, X_uji, y_latih, y_uji = train_test_split(
    X, y, test_size=0.25, random_state=42, stratify=y
)

baseline = DummyClassifier(strategy="most_frequent").fit(X_latih, y_latih)
model = LogisticRegression(max_iter=1000).fit(X_latih, y_latih)
prediksi = model.predict(X_uji)

print("prevalensi kelas positif di uji:", round(y_uji.mean(), 3))
print("akurasi baseline               :", round(accuracy_score(y_uji, baseline.predict(X_uji)), 3))
print("akurasi model                  :", round(accuracy_score(y_uji, prediksi), 3))
print("matriks (baris=benar, kolom=prediksi):")
print(confusion_matrix(y_uji, prediksi).tolist())
print(f"presisi: {precision_score(y_uji, prediksi, zero_division=0):.3f} | recall: {recall_score(y_uji, prediksi, zero_division=0):.3f}")
text Keluaran
prevalensi kelas positif di uji: 0.077
akurasi baseline               : 0.923
akurasi model                  : 0.923
matriks (baris=benar, kolom=prediksi):
[[12, 0], [1, 0]]
presisi: 0.000 | recall: 0.000

Keluaran ini adalah keseluruhan pelajaran topik. Akurasi model sama persis dengan baseline, yaitu 0.923, dan matriks kebingungan menjelaskan mengapa, yaitu model menebak semua baris sebagai negatif, sehingga satu baris positif yang ada luput. Presisi dan recall yang nol menyatakan model ini belum mendeteksi apa pun, dan akurasi tingginya hanyalah bayang-bayang ketimpangan kelas.

Matriks kebingungan dan dua jenis kesalahan#

Matriks kebingungan menyandingkan kebenaran dengan tebakan pada empat sel, yaitu benar positif, benar negatif, salah positif, dan salah negatif, dan matriks adalah sumber kebenaran setiap metrik turunannya. Pada keluaran di atas, sel [[12, 0], [1, 0]] menyatakan dua belas negatif yang benar, nol positif palsu, dan satu positif yang luput.

Dua jenis kesalahan membawa biaya yang berbeda dan tidak dapat dipertukarkan. Salah negatif pada deteksi peringatan polusi berarti pengguna yang terpapar tanpa diberi tahu, sedangkan salah positif berarti peringatan yang tidak perlu, dan keputusan kebijakan menentukan mana yang lebih mahal.

Presisi menjawab berapa banyak peringatan yang benar di antara semua peringatan yang diberikan, sedangkan recall menjawab berapa banyak peristiwa sungguhan yang tertangkap, dan keduanya bertukar posisi ketika ambang keputusan digeser. Ambang yang dinaikkan mengurangi peringatan palsu sekaligus menambah yang luput, dan pemilihannya adalah keputusan biaya, bukan angka bawaan.

Memilih metrik sesuai keputusan#

Tabel keputusan berikut menyambungkan pertanyaan pemangku kepentingan dengan metrik yang menjawabnya, dan pemilihannya dilakukan sebelum model dilatih.

Pertanyaan keputusanMetrik yang menjawab
Seberapa andal setiap peringatan yang dikirim?presisi
Berapa banyak peristiwa yang luput?recall
Apakah model mengalahkan menebak kelas mayoritas?akurasi dibanding baseline
Bagaimana pertukaran pada semua ambang?kurva presisi-recall
Berapa nilai keseluruhan dengan bobot biaya?kerugian rata-rata per keputusan

Dua baris terakhir menunjuk keputusan yang lebih kaya. Kurva presisi-recall menampilkan seluruh pertukaran ambang dalam satu gambar sehingga pemilihan ambang menjadi keputusan yang terbuka, sedangkan kerugian rata-rata menetapkan harga setiap jenis kesalahan dan menjumlahkannya, yang paling dekat dengan bahasa biaya pemangku kepentingan.

Kebiasaan yang menyertai adalah melaporkan prevalensi kelas bersama setiap metrik, karena presisi 0.5 pada kelas 1 persen dan pada kelas 50 persen menceritakan dua kehebatan yang berbeda.

Kesalahan umum#

Kesalahan pertama adalah melaporkan akurasi tunggal pada kelas timpang. Angka 0.923 pada keluaran di atas sama persis dengan menebak semua negatif, dan matriks kebingungan membeberkannya dalam satu baris.

Kesalahan kedua adalah memakai zero_division tanpa memahami pesannya. Bila tidak ada satu pun peringatan yang diberikan, presisi tidak terdefinisi, dan membiarkan angka bawaan tanpa menyebutnya menyembunyikan model yang diam.

Kesalahan ketiga adalah memilih metrik setelah melihat hasil. Metrik yang dipilih belakangan selalu memenangkan model yang kebetulan unggul padanya, sedangkan metrik yang ditetapkan sebelum melatih mengikuti biaya keputusan yang sudah disepakati.

Ringkasan#

  • Akurasi menipu pada kelas timpang, dan baseline kelas mayoritas mencapai 0.923 pada prevalensi 7.7 persen dengan model yang recall-nya nol.
  • Matriks kebingungan adalah sumber kebenaran, dan salah positif serta salah negatif membawa biaya yang berbeda.
  • Presisi menjawab keandalan peringatan dan recall menjawab yang luput, dan keduanya bertukar posisi seiring ambang keputusan.
  • Metrik dipilih dari pertanyaan keputusan sebelum model dilatih, dan prevalensi kelas menyertai setiap pelaporannya.

Referensi#