É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?
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)))
Le package ROCR calculera l'AUC entre autres statistiques:
auc.tmp <- performance(pred,"auc"); auc <- as.numeric([email protected])
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
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")
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
Vous pouvez en savoir plus sur AUROC dans cet article de blog par Miron Kursa :
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
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:
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é.
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))
}
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)