Calculer L'AUC dans R?

étant donné un vecteur de scores et un vecteur des étiquettes de classe réelles, Comment calculez-vous une métrique AUC à numéro unique pour un classificateur binaire dans la langue R ou en anglais simple?

Page 9 de " AUC: une meilleure mesure..." semble exiger de connaître les étiquettes de classe, et voici un exemple dans MATLAB là où je ne comprends pas

R(Actual == 1))

Parce que R (à ne pas confondre avec le langage R) est défini un vecteur de mais aussi la fonction?

37
demandé sur AGS 2011-02-05 00:24:26

10 réponses

comme mentionné par d'autres, vous pouvez calculer L'AUC en utilisant le ROCR paquet. Avec le paquet ROCR, vous pouvez également tracer la courbe ROC, la courbe lift et d'autres mesures de sélection de modèles.

vous pouvez calculer la SSC directement sans utiliser Aucun paquet en utilisant le fait que la SSC est égale à la probabilité qu'un vrai positif soit noté plus grand qu'un vrai négatif.

Par exemple, si pos.scores est un vecteur contenant un score exemples positifs, et neg.scores est un vecteur contenant les exemples négatifs alors l'ASC est approximée par:

> mean(sample(pos.scores,1000,replace=T) > sample(neg.scores,1000,replace=T))
[1] 0.7261

donnera une approximation de L'AUC. Vous pouvez également estimer la variance de L'AUC en bootstrapping:

> aucs = replicate(1000,mean(sample(pos.scores,1000,replace=T) > sample(neg.scores,1000,replace=T)))
30
répondu erik 2011-02-15 05:44:00

Le ROCR paquet calculer la CUA parmi d'autres statistiques:

auc.tmp <- performance(pred,"auc"); auc <- as.numeric(auc.tmp@y.values)
34
répondu semaj 2013-12-01 12:18:22

Avec le paquet pROC vous pouvez utiliser la fonction

> data(aSAH)
> 
> # Syntax (response, predictor):
> auc(aSAH$outcome, aSAH$s100b)
Area under the curve: 0.7314
26
répondu J. Win. 2018-05-22 20:21:03

sans aucun paquet supplémentaire:

true_Y = c(1,1,1,1,2,1,2,1,2,2)
probs = c(1,0.999,0.999,0.973,0.568,0.421,0.382,0.377,0.146,0.11)

getROC_AUC = function(probs, true_Y){
    probsSort = sort(probs, decreasing = TRUE, index.return = TRUE)
    val = unlist(probsSort$x)
    idx = unlist(probsSort$ix)  

    roc_y = true_Y[idx];
    stack_x = cumsum(roc_y == 2)/sum(roc_y == 2)
    stack_y = cumsum(roc_y == 1)/sum(roc_y == 1)    

    auc = sum((stack_x[2:length(roc_y)]-stack_x[1:length(roc_y)-1])*stack_y[2:length(roc_y)])
    return(list(stack_x=stack_x, stack_y=stack_y, auc=auc))
}

aList = getROC_AUC(probs, true_Y) 

stack_x = unlist(aList$stack_x)
stack_y = unlist(aList$stack_y)
auc = unlist(aList$auc)

plot(stack_x, stack_y, type = "l", col = "blue", xlab = "False Positive Rate", ylab = "True Positive Rate", main = "ROC")
axis(1, seq(0.0,1.0,0.1))
axis(2, seq(0.0,1.0,0.1))
abline(h=seq(0.0,1.0,0.1), v=seq(0.0,1.0,0.1), col="gray", lty=3)
legend(0.7, 0.3, sprintf("%3.3f",auc), lty=c(1,1), lwd=c(2.5,2.5), col="blue", title = "AUC")

enter image description here

16
répondu AGS 2013-09-28 21:01:36

j'ai trouvé que certaines des solutions ici sont lentes et / ou déroutantes (et certaines ne gèrent pas les liens correctement) donc j'ai écrit ma propre data.table fonction auc_roc () dans mon package R mltools.

library(data.table)
library(mltools)

preds <- c(.1, .3, .3, .9)
actuals <- c(0, 0, 1, 1)

auc_roc(preds, actuals)  # 0.875

auc_roc(preds, actuals, returnDT=TRUE)
   Pred CountFalse CountTrue CumulativeFPR CumulativeTPR AdditionalArea CumulativeArea
1:  0.9          0         1           0.0           0.5          0.000          0.000
2:  0.3          1         1           0.5           1.0          0.375          0.375
3:  0.1          1         0           1.0           1.0          0.500          0.875
6
répondu Ben 2017-08-28 20:02:09

dans la lignée de la réponse d'erik, vous devriez également pouvoir calculer le ROC directement en comparant toutes les paires de valeurs possibles à partir de pos.scores et nég.scores:

score.pairs <- merge(pos.scores, neg.scores)
names(score.pairs) <- c("pos.score", "neg.score")
sum(score.pairs$pos.score > score.pairs$neg.score) / nrow(score.pairs)

certainement moins efficace que la méthode d'échantillonnage ou la méthode pROC::auc, mais plus stable que la première et nécessitant moins d'installation que la seconde.

Lié: quand j'ai essayé ceci il a donné des résultats similaires à la valeur de pROC, mais pas exactement le même (off par 0.02 ou ainsi); le résultat était plus près de l'échantillon approche à très haut N. Si quelqu'un a des idées pourquoi je serais intéressé.

3
répondu Max Ghenis 2013-01-15 14:10:55

combinaison du code de ISL 9.6.3 courbes ROC, avec @J. Gagné.'S réponse à cette question et quelques autres endroits, les graphiques suivants la courbe ROC et imprime L'AUC en bas à droite sur la parcelle.

en dessous de probs est un vecteur numérique des probabilités prédites pour la classification binaire et test$label contient les véritables étiquettes des données d'essai.

require(ROCR)
require(pROC)

rocplot <- function(pred, truth, ...) {
  predob = prediction(pred, truth)
  perf = performance(predob, "tpr", "fpr")
  plot(perf, ...)
  area <- auc(truth, pred)
  area <- format(round(area, 4), nsmall = 4)
  text(x=0.8, y=0.1, labels = paste("AUC =", area))

  # the reference x=y line
  segments(x0=0, y0=0, x1=1, y1=1, col="gray", lty=2)
}

rocplot(probs, test$label, col="blue")

cela donne une intrigue comme ceci:

enter image description here

3
répondu arun 2016-07-20 22:15:28

j'utilise habituellement la fonction ROC du paquet diagnostiqué. J'aime le graphique qu'il produit. L'aire sous la courbe est retournée avec son intervalle de confiance et elle est également mentionnée sur le graphique.

ROC(classLabels,scores,Full=TRUE)
2
répondu George Dontas 2011-02-05 08:50:34

actuellement, la réponse la plus élevée est incorrecte, car elle ne tient pas compte des liens. Lorsque les scores positif et négatif sont égaux, la SSC doit être de 0,5. Ci-dessous est corrigé exemple.

computeAUC <- function(pos.scores, neg.scores, n_sample=100000) {
  # Args:
  #   pos.scores: scores of positive observations
  #   neg.scores: scores of negative observations
  #   n_samples : number of samples to approximate AUC

  pos.sample <- sample(pos.scores, n_sample, replace=T)
  neg.sample <- sample(neg.scores, n_sample, replace=T)
  mean(1.0*(pos.sample > neg.sample) + 0.5*(pos.sample==neg.sample))
}
2
répondu Jussi Kujala 2017-01-04 07:45:04

vous pouvez en savoir plus sur AUROC dans ce billet de blog par Miron Kursa:

https://mbq.me/blog/augh-roc/

Il fournit une fonction rapide pour AUROC:

# By Miron Kursa https://mbq.me
auroc <- function(score, bool) {
  n1 <- sum(!bool)
  n2 <- sum(bool)
  U  <- sum(rank(score)[!bool]) - n1 * (n1 + 1) / 2
  return(1 - U / n1 / n2)
}

nous allons tester:

set.seed(42)
score <- rnorm(1e3)
bool  <- sample(c(TRUE, FALSE), 1e3, replace = TRUE)

pROC::auc(bool, score)
mltools::auc_roc(score, bool)
ROCR::performance(ROCR::prediction(score, bool), "auc")@y.values[[1]]
auroc(score, bool)

0.51371668847094
0.51371668847094
0.51371668847094
0.51371668847094

auroc() est 100 fois plus rapide que pROC::auc() et computeAUC().

auroc() est 10 fois plus rapide que mltools::auc_roc() et ROCR::performance().

print(microbenchmark(
  pROC::auc(bool, score),
  computeAUC(score[bool], score[!bool]),
  mltools::auc_roc(score, bool),
  ROCR::performance(ROCR::prediction(score, bool), "auc")@y.values,
  auroc(score, bool)
))

Unit: microseconds
                                                             expr       min
                                           pROC::auc(bool, score) 21000.146
                            computeAUC(score[bool], score[!bool]) 11878.605
                                    mltools::auc_roc(score, bool)  5750.651
 ROCR::performance(ROCR::prediction(score, bool), "auc")@y.values  2899.573
                                               auroc(score, bool)   236.531
         lq       mean     median        uq        max neval  cld
 22005.3350 23738.3447 22206.5730 22710.853  32628.347   100    d
 12323.0305 16173.0645 12378.5540 12624.981 233701.511   100   c 
  6186.0245  6495.5158  6325.3955  6573.993  14698.244   100  b  
  3019.6310  3300.1961  3068.0240  3237.534  11995.667   100 ab  
   245.4755   253.1109   251.8505   257.578    300.506   100 a   
0
répondu Kamil Slowikowski 2018-05-06 16:40:38