Простой способ подсчета точности, отзыва и оценки F1 в R

Я использую классификатор rpart в R. Вопрос в том, что я хотел бы протестировать обученный классификатор на тестовых данных. Это нормально - я могу использовать функцию predict.rpart.

Но я также хочу рассчитать точность, отзывчивость и оценку F1.

Мой вопрос: должен ли я сам писать для них функции или есть ли для этого какая-либо функция в R или любой из библиотек CRAN?


person Karel Bílek    schedule 14.12.2011    source источник


Ответы (7)


Библиотека 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])

...
person Itamar    schedule 14.12.2011
comment
... а для F1-оценки performance(pred,"f") дает вектор F1-оценок - person smci; 04.03.2014
comment
и я предполагаю, что прогнозы также должны содержать оценки достоверности или вероятности для каждого прогноза? - person peschü; 18.03.2015
comment
Просто для пояснения: Performance использует объект prediction, который состоит из оценок (predictions) и меток (y) каждого случая. Помимо этого, нет никаких дополнительных цифр (например, уверенность и т. Д.). - person Itamar; 19.03.2015
comment
@itamar Можете ли вы помочь мне с вычислением площади под кривой точного отзыва. Мой вопрос здесь Спасибо. - person Newbie; 15.09.2016
comment
ROCR не работает, если в задаче более 2 классов для прогнозирования - person Matias; 01.08.2020
comment
@ peschü кажется правым. ROCR ожидает, что прогнозы будут значениями достоверности, чтобы можно было настроить порог отсечки и, следовательно, вычислить кривую ROC. Однако, если у вас нет значений достоверности из-за характера вашего классификатора, результаты будут очень запутанными. Вероятно, можно извлечь исходную оценку F1, но неясно, как это сделать. - person Migwell; 08.07.2021

используя пакет 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'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))
}

Некоторые комментарии о функции:

  • Предполагается, что F1 = NA равно нулю.
  • positive.class используется только в двоичном формате f1
  • для мультиклассовых задач вычисляется макро-усредненное F1
  • Если predicted и expected имели разные уровни, predicted получит expected уровни
person Adriano Rivolli    schedule 25.04.2016
comment
Привет спасибо. Я заметил, что есть предупреждение, когда, например, один из классов никогда не предсказывается. Как вы думаете, расчет еще в силе? - person agenis; 06.12.2017
comment
Спасибо, вы правы. Я сделал небольшое улучшение, чтобы исправить эту проблему. Теперь это работает правильно в таких случаях. - person Adriano Rivolli; 13.12.2017

Просто чтобы обновить это, когда я сейчас наткнулся на эту ветку, функция confusionMatrix в caret вычисляет все эти вещи автоматически.

cm <- confusionMatrix(prediction, reference = test_set$label)

# extract F1 score for all classes
cm[["byClass"]][ , "F1"] #for multiclass classification problems

Вы также можете заменить F1 любым из следующего, чтобы извлечь соответствующие значения:

Чувствительность, специфичность, положительное прогнозное значение, отрицательное прогнозное значение, точность, отзыв, F1, распространенность, обнаружение, скорость, распространенность обнаружения, сбалансированная точность

Я думаю, что это ведет себя немного иначе, когда вы решаете только проблему с двоичной классификацией, но в обоих случаях все эти значения вычисляются для вас, когда вы заглядываете внутрь объекта confusionMatrix в $byClass

person anguyen1210    schedule 26.09.2019

confusionMatrix () из пакета каретки можно использовать вместе с правильным необязательным полем «Положительный», указывающим, какой коэффициент следует принимать как положительный.

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

Этот код также предоставит дополнительные значения, такие как F-статистика, точность и т. Д.

person nin    schedule 24.08.2017
comment
или вы можете просто (режим = все) распечатать всю статистику. - person Zawir Amin; 02.04.2020
comment
Обратите внимание, что, как и в случае с большинством представленных здесь решений, это будет работать только в том случае, если вектор предсказанных классов и фактических классов имеют одинаковые уровни. - person GuillaumeL; 17.12.2020

Я заметил комментарий о том, что для бинарных классов требуется оценка 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)))))
person Chris    schedule 17.06.2015

Мы можем просто получить значение F1 из функции confusionMatrix каретки

result <- confusionMatrix(Prediction, Lable)

# View confusion matrix overall
result 

# F1 value
result$byClass[7] 
person donghyeon kim    schedule 24.08.2017
comment
Это не значение F1 - person Siddhu; 12.03.2019

Вы также можете использовать confusionMatrix(), предоставленный пакетом caret. Выходные данные включают, помимо прочего, Чувствительность (также известную как отзыв) и Pred Pred Value (также известную как точность). Тогда F1 можно легко вычислить, как указано выше, как: F1 <- (2 * precision * recall) / (precision + recall)

person Mewtwo    schedule 29.01.2017