average precision

precision

Pada post kali ini, saya ingin mempopulerkan metrics yang menurut saya masih sangat underrated, terutama ketika kita bermain dengan dataset yang distribusi jumlah data antar kelasnya berbeda jauh alias imbalanced. Perkenalkan bintang utama tulisan kita kali ini, average precision!

Loh, memang apa salahnya kalau kita menghitung performa model machine learning kita untuk problem tersebut hanya dengan menggunakan akurasi saja?

Misalkan kita punya data dengan jumlah 10000. Namun hanya 40 data yang mempunyai label positif, sedangkan 9960 sisanya adalah kelas negatif. Dengan komposisi data seperti ini, kita bisa mendapat akurasi lebih dari 99% hanya dengan melakukan prediksi kelas negatif semua, seperti gambar di bawah.

training error
Inspired by xkcd random number generator

Tentunya angka 99% tersebut tidak fair, dan model yang menghasilkan angka tersebut juga tidak berguna, karena kita lebih tertarik terhadap kemampuan model kita untuk memprediksi kelas yang positif. (Untuk tips/trik dalam menghadapi tipe problem seperti ini, bisa dilihat di post sebelumnya).

Oleh karena itu, kita membutuhkan metrics yang bisa lebih merepresentasikan performa model kita. Metrics pertama yang bisa kita pakai adalah precision dan recall. Precision menghitung berapa banyak jumlah data yang benar2 positif dari semua data yang kita prediksi sebagai positif, atau dengan kata lain true positive / (true positive + false positive). Recall menghitung berapa banyak data positif yang diprediksi sebagai positif, atau dalam rumus true positive / (true positive + false negative).

Kedua hal ini mungkin akan lebih jelas kalau melihat contoh tabel confusion matrix berikut:

confusion matrix

Precision untuk kelas positif di atas adalah 10 / (10+90) atau 0.1 sedangkan recall-nya adalah 10 / (10+30) atau 0.25. Angka yang mungkin terlihat jauh lebih buruk dari angka 99 persen di atas, tapi lebih akurat dalam merepresentasikan performa dari model kita.

Sering terdapat trade off ketika kita ingin mengoptimalkan salah satu dari metrics tersebut. Misalnya, untuk mendapatkan recall 100 persen kita cukup prediksi semua data sebagai positif, tapi tentunya hal ini akan membuat precision nilainya hancur lebur.

total recall
Sayangnya belum ada film dengan judul Total Precision dengan bintang utama Steven Seagal

Begitu pula sebaliknya, untuk mendapatkan precision yang tinggi, kita bisa hanya memasukkan prediksi yang kita benar-benar yakin sebagai kelas positif, akibatnya ada banyak data yang diprediksi sebagai negatif sehingga recall-nya yang sekarang menjadi jelek. Di sinilah kita harus memilih, mana yang mau lebih diprioritaskan, precision atau recall.

Beberapa problem lebih membutuhkan nilai precision yang tinggi. Misalkan untuk diagnosis penyakit, karena rumah sakit memiliki resource yang terbatas, lebih baik kita hanya memasukkan orang yang kita benar-benar yakin mengidap suatu penyakit (high precision), karena kalaupun kita salah diagnosis, orang tersebut bisa mencari rumah sakit lain.

Sedangkan untuk fraud detection, lebih baik recall-nya tinggi (banyak aktivitas fraud yang terdeteksi) walaupun akibatnya banyak transaksi valid yang kita mark sebagai fraud. Alasannya adalah legitimate user yang kita mark sebagai fraud tetap bisa melakukan validasi transaksinya, misalkan dengan memasukkan kode yg dikirim ke hape-nya oleh sistem 3-D secure visa (walaupun mungkin ini bisa menyebabkan friction tambahan ke customer sehingga conversion rate berkurang).

Kedua nilai ini bisa digabung lagi menjadi ke satu angka, misalkan untuk melakukan komparasi antar model yang berbeda. Salah satu cara untuk menggabungkannya adalah F1 score, alias harmonic means dari precision dan recall. Rumusnya kira-kira seperti berikut 2*precision*recall / (precision+recall).

Tapi kemudian timbul pertanyaan lain, karena sebenarnya nilai precision dan/atau recall ini bisa berbeda2 tergantung dari berapa threshold yang dipakai oleh classifier kita. Misalkan dengan threshold 0.5 kita mendapat 0.7 precision untuk 0.3 recall. Ternyata dengan mengurangi threshold menjadi 0.4, recall-nya naik menjadi 0.6 (2 kali lipat), sedangkan precision-nya hanya turun menjadi 0.66. Tentunya kalau dilihat secara singkat threshold kedua in general lebih baik dibanding yang pertama. Bagaimana kita bisa tahu threshold mana yang lebih baik untuk model kita?

Untuk mendapat gambaran lengkap dari performa model kita di semua level threshold, kita bisa menggunakan Precision-Recall curve (PR curve). Kalau di sklearn, kita cukup masukkan hasil prediksi model kita yang dalam berupa score prediction (misalkan output dari method predict_proba) dan target labelnya ke dalam fungsi sklearn.metrics.precision_recall_curve.

pr curve1

Sumbu x adalah recall, dan sumbu y adalah precision. Dari gambar kurva di atas, kita bisa dengan cepat mengambil kesimpulan. Ketika nilai recall-nya rendah sekali (< 0.1) nilai precision bisa sangat tinggi, hampir 1. Sedangkan ketika nilai recall-nya tinggi sekali (> 0.99), nilai precision-nya menjadi rendah sekali, hampir 0.4. Tapi lihat, ketika nilainya recall-nya sekitar 0.8, kita bisa mendapat nilai precision yang juga cukup tinggi, sekitar 0.8. Sepertinya kompromi yang baik untuk kedua nilai tersebut.

Nah, bagaimana kalau kita ingin membandingkan antar 2 model mana yang lebih baik dengan menggunakan PR curve? Cara yang biasa dilakukan adalah dengan menghitung luas area di bawah kurva. Angka inilah yang disebut sebagai average precision.

Kalau di ranah information retrieval atau ranking, average precision ini nilainya dirata-ratakan lagi sejumlah query yang dites. Maka dia akan berubah menjadi mean average precision (MAP). Angka inilah yang kemudian akan dibandingkan untuk mendapatkan algoritma dengan performa yang terbaik. (Khusus untuk problem ranking, ini cuma dilakukan kalau misalnya labelnya hanya positif dan negatif. sedangkan jika labelnya adalah urutan yang sebenarnya, maka biasanya metrics lain seperti normalized discounted cumulative gain (NDCG) yang digunakan)

Kalau kalian memiliki lebih dari satu class (multi-class classification), average precision bisa dihitung dengan menggunakan binary classifier untuk setiap kelasnya. Kemudian nilai dari setiap kelasnya dirata-rata sehingga mendapat angka MAP-nya.

pr_curve_caffenet
Contoh PR curve dari semua kelas untuk problem object detection.

Kira-kira demikian yang bisa saya share, semoga berguna di dunia nyata. Salam.

Iklan

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout /  Ubah )

Foto Google+

You are commenting using your Google+ account. Logout /  Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout /  Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout /  Ubah )

Connecting to %s