Легкий способ подсчета точности, отзыва и F1-балла в R
Я использую классификатор rpart
в R. Вопрос: я бы хотел протестировать обученный классификатор на тестовые данные. Это нормально - я могу использовать функцию predict.rpart
.
Но я также хочу рассчитать точность, отзыв и оценку F1.
Мой вопрос: нужно ли мне писать функции для себя, или есть ли какая-либо функция в R или любой из библиотек CRAN для этого?
Ответы
Ответ 1
Библиотека ROCR вычисляет все эти и более (см. также 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])
...
Ответ 2
используя пакет 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)
Общей функцией, которая работает для двоичной и многоклассовой классификации без использования какого-либо пакета, является:
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 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))
}
Некоторые комментарии о функции:
- Предполагается, что F1 = NA равно нулю
positive.class
используется только в
двоичный f1
- для задач с несколькими классами вычисляется усредненное по макросу F1
- Если
predicted
и expected
имели разные уровни, predicted
получит уровни expected
Ответ 3
Я заметил комментарий о том, что оценка F1 необходима для двоичных классов. Я подозреваю, что это обычно так. Но некоторое время назад я написал это, в котором я делал классификацию в несколько групп, обозначенных номером. Это может пригодиться вам...
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)))))
Ответ 4
confusionMatrix() из пакета caret можно использовать вместе с соответствующим необязательным полем "Позитивный", определяющим, какой фактор следует принимать как положительный фактор.
confusionMatrix(predicted, Funded, mode = "prec_recall", positive="1")
Этот код также даст дополнительные значения, такие как F-статистика, точность и т.д.
Ответ 5
Мы можем просто получить значение F1 из функции weight confusionMatrix
result <- confusionMatrix(Prediction, Lable)
# View confusion matrix overall
result
# F1 value
result$byClass[7]
Ответ 6
Вы также можете использовать confusionMatrix()
, предоставляемый пакетом caret
. Выход включает в себя, между другими, Чувствительность (также известную как отзыв) и Pos Pred Value (также известную как точность). Тогда F1 можно легко вычислить, как указано выше, как:
F1 <- (2 * precision * recall) / (precision + recall)
Ответ 7
Просто чтобы обновить это, когда я наткнулся на эту тему, функция confusionMatrix
в caret
автоматически вычисляет все эти вещи для вас.
cm <- confusionMatrix(prediction, reference = test_set$label)
# extract F1 score for all classes
cm[["byClass"]][ , "F1"] #for multiclass classification problems
Вы можете подставить "F1" выше для любого из следующих действий, чтобы также извлечь соответствующие значения:
"Sensitivity", "Specificity", "Pos Pred Value", "Neg Pred Value", "Precision", "Recall", "F1", "Prevalence", "Detection", "Rate", "Detection Prevalence", "Balanced Accuracy"
Я думаю, что это ведет себя немного по-другому, когда вы делаете только двоичную задачу классификации, но в обоих случаях все эти значения вычисляются для вас, когда вы смотрите внутрь объекта confusionMatrix, в $byClass