web-dev-qa-db-fra.com

Calculer l'ASC dans R?

Étant donné un vecteur de scores et un vecteur d'étiquettes de classe réelles, comment calculer une métrique AUC à un seul nombre pour un classificateur binaire en langage R ou en anglais simple?

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

R(Actual == 1))

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

41
Andrew

Comme mentionné par d'autres, vous pouvez calculer l'AUC en utilisant le package ROCR . Avec le package ROCR, vous pouvez également tracer la courbe ROC, la courbe de portance et d'autres mesures de sélection de modèle.

Vous pouvez calculer l'AUC directement sans utiliser de package en utilisant le fait que l'ASC est égale à la probabilité qu'un vrai positif soit noté plus qu'un vrai négatif.

Par exemple, si pos.scores est un vecteur contenant une vingtaine d'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 amorçant:

> aucs = replicate(1000,mean(sample(pos.scores,1000,replace=T) > sample(neg.scores,1000,replace=T)))
29
erik

Le package ROCR calculera l'AUC entre autres statistiques:

auc.tmp <- performance(pred,"auc"); auc <- as.numeric([email protected])
38
semaj

Avec le package pROC, vous pouvez utiliser la fonction auc() comme cet exemple de la page d'aide:

> data(aSAH)
> 
> # Syntax (response, predictor):
> auc(aSAH$outcome, aSAH$s100b)
Area under the curve: 0.7314
31
J. Win.

Sans forfaits supplémentaires:

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

17
AGS

J'ai trouvé certaines des solutions ici lentes et/ou déroutantes (et certaines d'entre elles ne gèrent pas les liens correctement), j'ai donc écrit mon propre data.table fonction basée 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
Ben

Vous pouvez en savoir plus sur AUROC dans cet article 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)
}

Testons-le:

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   
4

Combinaison de code de ISL 9.6.3 ROC Curves , avec @J. La réponse de Won à cette question et à quelques autres endroits, ce qui suit trace la courbe ROC et imprime l'AUC en bas à droite sur le tracé.

Sous probs se trouve un vecteur numérique des probabilités prédites pour la classification binaire et test$label contient les véritables étiquettes des données de test.

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 un tracé comme celui-ci:

enter image description here

4
arun

Dans le sens de la réponse d'erik, vous devriez également pouvoir calculer le ROC directement en comparant toutes les paires de valeurs possibles des scores positifs et négatifs:

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)

Certes moins efficace que l'approche par exemple ou pROC :: auc, mais plus stable que la première et nécessitant moins d'installation que la seconde.

Connexes: lorsque j'ai essayé, cela a donné des résultats similaires à la valeur de pROC, mais pas exactement les mêmes (moins 0,02); le résultat était plus proche de l'approche de l'échantillon avec un N très élevé. Si quelqu'un a des idées sur la raison pour laquelle cela pourrait être, je serais intéressé.

3
Max Ghenis

La réponse actuellement la mieux notée est incorrecte, car elle ne tient pas compte des liens. Lorsque les scores positifs et négatifs sont égaux, l'ASC devrait être de 0,5. Voici un exemple corrigé.

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
Jussi Kujala

J'utilise généralement la fonction ROC du package DiagnosisMed. J'aime le graphique qu'il produit. L'AUC est retourné avec son intervalle de confiance et il est également mentionné sur le graphique.

ROC(classLabels,scores,Full=TRUE)
2
George Dontas