Разница между AUPRC в карете и PRROC - PullRequest
0 голосов
/ 14 ноября 2018

Я работаю в очень несбалансированной проблеме классификации и использую AUPRC в качестве метрики в каретке.Я получаю очень разные результаты для набора тестов в AUPRC из каретки и в AUPRC из пакета PRROC.

Для простоты в воспроизводимом примере используется набор данных PimaIndiansDiabetes из пакета mlbench:

rm(list=ls())
library(caret)
library(mlbench)
library(PRROC)

#load data, renaming it to 'datos'
data(PimaIndiansDiabetes)
datos=PimaIndiansDiabetes[,1:9]

# training and test
set.seed(998)
inTraining <- createDataPartition(datos[,9], p = .8, list = FALSE)
training <-datos[ inTraining,]
testing <- datos[ -inTraining,]

#training

 control=trainControl(method = "cv",summaryFunction = prSummary,
 classProbs = TRUE)
 set.seed(998)
 rf.tune <-train(training[,1:8],training[,9],method ="rf",   
 trControl=control,metric="AUC")

#evaluating AUPRC in test set

 matriz=cbind(testing[,9],predict(rf.tune,testing[,1:8],type="prob"),
 predict(rf.tune,testing[,1:8]))
 names(matriz)=c("obs",levels(testing[,9]),"pred")
 prSummary(matriz,levels(testing[,9]))


 #calculating AUPRC through pr.curve

#checking positive class
 confusionMatrix(predict(rf.tune,testing[,1:8]),testing[,9],
 mode  = "prec_recall")#'Positive' Class : neg 

#preparing data for pr.curve
indice_POS=which(testing[,9]=="neg")
indice_NEG=which(testing[,9]=="pos")

#the classification scores of  only the data points belonging to the 
#positive class
 clas_score_POS=predict(rf.tune,testing[,1:8],type="prob")[indice_POS,1]

 #the classification scores of  only the data points belonging to the 
 #negative class
 clas_score_NEG=predict(rf.tune,testing[,1:8],type="prob")[indice_NEG,2]

 pr.curve(clas_score_POS,clas_score_NEG)

Значение из PRROC равно 0,9053432, а из каретки prSummary равно 0,8714607.В моем несбалансированном случае различия более широкие (AUPRC = 0,1688446 с повторной выборкой SMOTE -via control$sampling <- "smote" - и 0,01429 с PRROC.)

Это из-за различных методов вычисления AUPRC в этих пакетах или I 'я делаю что-то не так?

ОБНОВЛЕНО: Я не могу найти ошибки в своем коде.После ответа missuse я хотел бы сделать несколько замечаний:

Когда вы делаете prSummary(matriz,levels(testing[,9])), вы получаете

 AUC      Precision    Recall         F 
0.8714607 0.7894737 0.9000000 0.8411215

, что соответствует

confusionMatrix(predict(rf.tune,testing[,1:8]),testing[,9],mode  = "prec_recall")
Confusion Matrix and Statistics

          Reference
Prediction neg pos
       neg  90  23
       pos  10  30

               Accuracy : 0.7843          
                 95% CI : (0.7106, 0.8466)
    No Information Rate : 0.6536          
    P-Value [Acc > NIR] : 0.0003018       

                  Kappa : 0.4945          
 Mcnemar's Test P-Value : 0.0367139       

              Precision : 0.7965          
                 Recall : 0.9000          
                     F1 : 0.8451          
             Prevalence : 0.6536          
         Detection Rate : 0.5882          
   Detection Prevalence : 0.7386          
      Balanced Accuracy : 0.7330          

       'Positive' Class : neg  

И с:

> MLmetrics::PRAUC(y_pred = matriz$neg, y_true = ifelse(matriz$obs == "neg", 1, 0))
[1] 0.8714607

Как вы можете видеть в последней строке, класс «Positive» - это «neg», и я думаю, что missuse рассматриваетположительный класс как «pos», поэтому у нас разные метрики.Более того, когда вы печатаете обученную ВЧ, результаты также соответствуют ожидаемой AUC ~ 0,87:

> rf.tune
Random Forest 

615 samples
  8 predictor
  2 classes: 'neg', 'pos' 

No pre-processing
Resampling: Cross-Validated (10 fold) 
Summary of sample sizes: 554, 553, 553, 554, 554, 554, ... 
Resampling results across tuning parameters:

  mtry  AUC        Precision  Recall  F        
  2     0.8794965  0.7958683  0.8525  0.8214760
  5     0.8786427  0.8048463  0.8325  0.8163032
  8     0.8528028  0.8110820  0.8325  0.8192225

Меня не беспокоит разница 0,87 Caret-0,9PRROC в этом случае, но я 'Я очень беспокоюсь о 0,1688446 карет / 0,01429 PRROC в несбалансированном корпусе.Может ли это быть из-за того, что числовое расхождение при разных реализациях усиливается в несбалансированном случае?И если в реализациях есть числовые различия, то как они совпадают 0.8714607 в тестовом наборе?

1 Ответ

0 голосов
/ 15 ноября 2018

Я надеюсь, что вы допустили несколько ошибок в своем коде.

Прежде всего caret::prSummary использует MLmetrics::PRAUC для вычисления AUPRC.Это должно быть определено так:

MLmetrics::PRAUC(y_pred = matriz$pos, y_true = ifelse(matriz$obs == "pos", 1, 0))

#output
0.7066323

с использованием вероятности положительного класса и числового вектора 0/1 истинных классов (1 для положительного)

Тот же результат получается с помощью:

caret::prSummary(matriz, levels(testing[,9])[2])

MLmetrics::PRAUC использует ROCR::prediction для построения кривой:

pred_obj <- ROCR::prediction(matriz$pos, ifelse(matriz$obs == "pos", 1, 0))
perf_obj <- ROCR::performance(pred_obj, measure = "prec", 
                              x.measure = "rec")

и кривая выглядит следующим образом:

ROCR::plot(perf_obj, ylim = c(0,1))

enter image description here

когда используется PRROC::pr.curve, существует несколько способов определения входных данных.Одним из них является предоставление вектора вероятностей для положительного класса для положительных наблюдений и вектора вероятностей для положительного класса для отрицательных наблюдений:

preds <- predict(rf.tune,
                 testing[,1:8],
                 type="prob")[,2] #prob of positive class
preds_pos <- preds[testing[,9]=="pos"] #preds for true positive class
preds_neg <- preds[testing[,9]=="neg"] #preds for true negative class

PRROC::pr.curve(preds_pos, preds_neg)
#truncated output
0.7254904

этих двух чисел (полученных с помощью PRROC::pr.curve иMLmetrics::PRAUC) не совпадают

, однако кривая

plot(PRROC::pr.curve(preds_pos, preds_neg, curve = TRUE))

enter image description here

выглядит так же, как приведенная выше, полученная с использованием ROCR::plot.

Для проверки:

res <- PRROC::pr.curve(preds_pos, preds_neg, curve = TRUE)

ROCR::plot(perf_obj, ylim = c(0,1), lty = 2, lwd = 2)
lines(res$curve[,1], res$curve[,2], col = "red", lty = 5)

enter image description here

они одинаковы.Поэтому разница в полученной области обусловлена ​​различными реализациями в упомянутых пакетах.

Эти реализации можно проверить, посмотрев на источник:

MLmetrics:::Area_Under_Curve #this one looks pretty straight forward 
PRROC:::compute.pr #haven't the time to study this one but if I had to bet I'd say this one is more accurate for step like curves.
...