Menghitung presisi dan daya ingat dalam R

8

Misalkan saya sedang membangun classifier regresi logistik yang memprediksi apakah seseorang sudah menikah atau lajang. (1 = menikah, 0 = tunggal) Saya ingin memilih titik pada kurva presisi-ingat yang memberi saya setidaknya 75% presisi, jadi saya ingin memilih ambang dan , sehingga:t1t2

  • Jika output dari classifier saya lebih besar dari , saya output "menikah".t1
  • Jika output di bawah , saya output "tunggal".t2
  • Jika output di antara keduanya, saya output "Saya tidak tahu".

Beberapa pertanyaan:

  1. Saya pikir di bawah definisi standar presisi, presisi akan mengukur ketepatan kelas menikah saja (yaitu, presisi = # kali saya benar memprediksi menikah / total # kali saya memprediksi menikah). Namun, apa yang benar-benar ingin saya lakukan adalah mengukur presisi keseluruhan (yaitu, total # kali saya memprediksi dengan benar menikah atau lajang / total # kali saya memprediksi menikah atau lajang). Apakah ini hal yang boleh dilakukan? Jika tidak, apa yang harus saya lakukan?
  2. Apakah ada cara untuk menghitung kurva presisi / recall "keseluruhan" ini dalam R (misalnya, menggunakan paket ROCR atau pustaka lain)? Saat ini saya menggunakan paket ROCR, tetapi tampaknya hanya memberi saya presisi / penarikan kelas tunggal.
raegtin
sumber

Jawaban:

7

Saya menulis sebuah fungsi untuk tujuan ini, berdasarkan latihan dalam buku Data Mining with R:

# Function: evaluation metrics
    ## True positives (TP) - Correctly idd as success
    ## True negatives (TN) - Correctly idd as failure
    ## False positives (FP) - success incorrectly idd as failure
    ## False negatives (FN) - failure incorrectly idd as success
    ## Precision - P = TP/(TP+FP) how many idd actually success/failure
    ## Recall - R = TP/(TP+FN) how many of the successes correctly idd
    ## F-score - F = (2 * P * R)/(P + R) harm mean of precision and recall
prf <- function(predAct){
    ## predAct is two col dataframe of pred,act
    preds = predAct[,1]
    trues = predAct[,2]
    xTab <- table(preds, trues)
    clss <- as.character(sort(unique(preds)))
    r <- matrix(NA, ncol = 7, nrow = 1, 
        dimnames = list(c(),c('Acc',
        paste("P",clss[1],sep='_'), 
        paste("R",clss[1],sep='_'), 
        paste("F",clss[1],sep='_'), 
        paste("P",clss[2],sep='_'), 
        paste("R",clss[2],sep='_'), 
        paste("F",clss[2],sep='_'))))
    r[1,1] <- sum(xTab[1,1],xTab[2,2])/sum(xTab) # Accuracy
    r[1,2] <- xTab[1,1]/sum(xTab[,1]) # Miss Precision
    r[1,3] <- xTab[1,1]/sum(xTab[1,]) # Miss Recall
    r[1,4] <- (2*r[1,2]*r[1,3])/sum(r[1,2],r[1,3]) # Miss F
    r[1,5] <- xTab[2,2]/sum(xTab[,2]) # Hit Precision
    r[1,6] <- xTab[2,2]/sum(xTab[2,]) # Hit Recall
    r[1,7] <- (2*r[1,5]*r[1,6])/sum(r[1,5],r[1,6]) # Hit F
    r}

Di mana untuk tugas klasifikasi biner apa pun, ini mengembalikan presisi, daya ingat, dan F-stat untuk setiap klasifikasi dan akurasi keseluruhan seperti:

> pred <- rbinom(100,1,.7)
> act <- rbinom(100,1,.7)
> predAct <- data.frame(pred,act)
> prf(predAct)
      Acc     P_0       R_0       F_0       P_1       R_1       F_1
[1,] 0.63 0.34375 0.4074074 0.3728814 0.7647059 0.7123288 0.7375887

Menghitung P, R, dan F untuk setiap kelas seperti ini memungkinkan Anda melihat apakah satu atau yang lain memberi Anda lebih banyak kesulitan, dan mudah untuk kemudian menghitung statistik P, R, F secara keseluruhan. Saya belum pernah menggunakan paket ROCR, tetapi Anda bisa dengan mudah memperoleh kurva ROC yang sama dengan melatih classifier pada rentang beberapa parameter dan memanggil fungsi untuk pengklasifikasi pada titik di sepanjang rentang.

Robert E Mealey
sumber
Saya pikir Anda mendapat kode presisi dan ingat bertukar. Itu harus r [1,5] <- xTab [2,2] / sum (xTab [2,])
danioyuan
6

Seperti yang dikatakan Robert dengan benar, Akurasi adalah jalan yang harus ditempuh. Saya hanya ingin menambahkan bahwa dimungkinkan untuk melakukan penghitungan dengan ROCR. Lihatlah bantuan (kinerja) untuk memilih ukuran yang berbeda.

Misalnya, dalam ROCR hanya satu ambang keputusan yang digunakan yang disebut cutoff . Kode berikut memplot akurasi vs cutoff dan mengekstrak cutoff untuk akurasi maksimum.

require(ROCR)

# Prepare data for plotting
data(ROCR.simple)
pred <- with(ROCR.simple, prediction(predictions, labels))
perf <- performance(pred, measure="acc", x.measure="cutoff")

# Get the cutoff for the best accuracy
bestAccInd <- which.max(perf@"y.values"[[1]])
bestMsg <- paste("best accuracy=", perf@"y.values"[[1]][bestAccInd], 
              " at cutoff=", round(perf@"x.values"[[1]][bestAccInd], 4))

plot(perf, sub=bestMsg)

yang mengakibatkan

masukkan deskripsi gambar di sini

Untuk beroperasi dengan dua ambang batas untuk membuat wilayah tengah ketidakpastian (yang merupakan cara yang valid untuk pergi jika keadaan / aplikasi target memungkinkannya) seseorang dapat membuat dua objek kinerja dengan ROCR

  1. cutoff vs True Positive Rate (tpr) alias presisi untuk kelas positif
  2. cutoff vs True Negative Rate (tnr) alias presisi untuk kelas negatif

Pilih cutoff yang sesuai dari vektor kinerja (menggunakan metode R yang) dan gabungkan mereka untuk mencapai keseimbangan yang diinginkan. Ini harus langsung, maka saya meninggalkannya sebagai latihan untuk pembaca.

Satu catatan terakhir: Apa perbedaan antara Akurasi dan ketepatan penghitungan untuk kedua kelas secara terpisah dan misalnya menggabungkannya dalam rata-rata (terbobot)?

Akurasi menghitung rata-rata tertimbang, di mana bobot untuk kelas c setara dengan jumlah instance dengan kelas c. Ini berarti bahwa jika Anda mengalami kemiringan kelas berat (misalnya 98% negatif) dapat dengan mudah "mengoptimalkan" akurasi dengan menetapkan prediksi label negatif untuk semua instance. Dalam kasus seperti itu, rata-rata polos non-tertimbang dari kedua precision kelas mencegah permainan metrik. Dalam kasus kelas yang seimbang, kedua metode perhitungan tentu saja menghasilkan hasil yang sama.

steffen
sumber