web-dev-qa-db-fra.com

Un moyen facile de compter la précision, le rappel et le score F1 en R

J'utilise un classifieur rpart dans R. La question est la suivante: j'aimerais tester le classifieur formé sur des données de test. C'est bon - je peux utiliser la fonction predict.rpart.

Mais je veux aussi calculer la précision, le rappel et le score F1. 

Ma question est la suivante: dois-je écrire des fonctions pour celles-ci moi-même ou existe-t-il une fonction dans R ou dans une bibliothèque CRAN pour cela?

13
Karel Bílek

La bibliothèque ROCR calcule tout cela et plus encore (voir aussi http://rocr.bioinf.mpi-sb.mpg.de ):

library (ROCR);
...

y <- ... # logical array of positive / negative cases
predictions <- ... # array of predictions

pred <- prediction(predictions, y);

# Recall-Precision curve             
RP.perf <- performance(pred, "prec", "rec");

plot (RP.perf);

# ROC curve
ROC.perf <- performance(pred, "tpr", "fpr");
plot (ROC.perf);

# ROC area under the curve
auc.tmp <- performance(pred,"auc");
auc <- as.numeric([email protected])

...
16
Itamar

en utilisant le paquet caret :

library(caret)

y <- ... # factor of positive / negative cases
predictions <- ... # factor of predictions

precision <- posPredValue(predictions, y, positive="1")
recall <- sensitivity(predictions, y, positive="1")

F1 <- (2 * precision * recall) / (precision + recall)

Une fonction générique qui fonctionne pour la classification binaire et multi-classe sans utiliser aucun package est:

f1_score <- function(predicted, expected, positive.class="1") {
    predicted <- factor(as.character(predicted), levels=unique(as.character(expected)))
    expected  <- as.factor(expected)
    cm = as.matrix(table(expected, predicted))

    precision <- diag(cm) / colSums(cm)
    recall <- diag(cm) / rowSums(cm)
    f1 <-  ifelse(precision + recall == 0, 0, 2 * precision * recall / (precision + recall))

    #Assuming that F1 is zero when it's not possible compute it
    f1[is.na(f1)] <- 0

    #Binary F1 or Multi-class macro-averaged F1
    ifelse(nlevels(expected) == 2, f1[positive.class], mean(f1))
}

Quelques commentaires sur la fonction:

  • Il est supposé qu'un F1 = NA est zéro 
  • positive.class est utilisé uniquement dans binaire f1 
  • pour les problèmes multi-classes, la F1 en moyenne macro est calculée
  • Si predicted et expected ont des niveaux différents, predicted recevra les niveaux expected
16
Adriano Rivolli

J'ai remarqué le commentaire à propos du score F1 nécessaire pour les classes binaires. Je soupçonne que c'est généralement le cas. Mais il y a quelque temps, j'ai écrit ceci dans lequel je faisais une classification en plusieurs groupes désignés par un nombre. Cela peut vous être utile ...

calcF1Scores=function(act,prd){
  #treats the vectors like classes
  #act and prd must be whole numbers
  df=data.frame(act=act,prd=prd);
  scores=list();
  for(i in seq(min(act),max(act))){
    tp=nrow(df[df$prd==i & df$act==i,]);        
    fp=nrow(df[df$prd==i & df$act!=i,]);
    fn=nrow(df[df$prd!=i & df$act==i,]);
    f1=(2*tp)/(2*tp+fp+fn)
    scores[[i]]=f1;
  }      
  print(scores)
  return(scores);
}

print(mean(unlist(calcF1Scores(c(1,1,3,4,5),c(1,2,3,4,5)))))
print(mean(unlist(calcF1Scores(c(1,2,3,4,5),c(1,2,3,4,5)))))
3
Chris

Nous pouvons simplement obtenir la valeur F1 de la fonction confusionMatrix de caret

result <- confusionMatrix(Prediction, Lable)

# View confusion matrix overall
result 

# F1 value
result$byClass[7] 
3
donghyeon kim

confusionMatrix () du paquet caret peut être utilisé avec un champ optionnel approprié "Positive" spécifiant quel facteur doit être pris comme facteur positif. 

confusionMatrix(predicted, Funded, mode = "prec_recall", positive="1")

Ce code donnera également des valeurs supplémentaires telles que la statistique F, la précision, etc.

1
nin

Vous pouvez également utiliser le package confusionMatrix() fourni par caret. La sortie inclut, entre autres, Sensitivity (également appelée rappel) et Pos Pred Value (également appelée précision). Alors, F1 peut être facilement calculé, comme indiqué ci-dessus, comme suit: F1 <- (2 * precision * recall) / (precision + recall)

1
lacrima