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?
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])
...
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:
positive.class
est utilisé uniquement dans binaire f1 predicted
et expected
ont des niveaux différents, predicted
recevra les niveaux expected
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)))))
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]
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.
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)