【问题标题】:Easy way of counting precision, recall and F1-score in R在 R 中计算精度、召回率和 F1 分数的简单方法
【发布时间】:2012-01-19 22:12:29
【问题描述】:

我在 R 中使用 rpart 分类器。问题是 - 我想在测试数据上测试经过训练的分类器。这很好 - 我可以使用 predict.rpart 函数。

但我还想计算精度、召回率和 F1 分数。

我的问题是 - 我是否必须自己为这些函数编写函数,或者 R 或任何 CRAN 库中是否有任何函数?

【问题讨论】:

    标签: r classification auc precision-recall


    【解决方案1】:

    使用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))
    }
    

    关于函数的一些cmets:

    • 假设 F1 = NA 为零
    • positive.class 仅用于 二进制 f1
    • 对于多类问题,计算宏观平均 F1
    • 如果predictedexpected 有不同的级别,predicted 将收到expected 级别

    【讨论】:

    • 嗨,谢谢。我注意到有一个警告,例如其中一个类永远不会被预测。您认为计算仍然有效吗?
    • 谢谢,你是对的。我做了一些改进来解决这个问题。现在它在这种情况下工作正常。
    【解决方案2】:

    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(auc.tmp@y.values)
    
    ...
    

    【讨论】:

    • ... 对于 F1-score performance(pred,"f") 给出了 F1-scores 的向量
    • 我猜预测也必须包含每个预测的置信度或概率分数?
    • 澄清一下:Performance 使用由每个案例的分数 (predictions) 和标签 (y) 构建的 prediction 对象。除此之外没有其他数字(例如信心等)。
    • @itamar 你能帮我计算精确召回曲线下的面积吗?我的问题是here 谢谢。
    • 如果问题中要预测的类超过 2 个,则 ROCR 不起作用
    【解决方案3】:

    只是为了更新这一点,因为我现在遇到了这个帖子,caret 中的 confusionMatrix 函数会自动为您计算所有这些内容。

    cm <- confusionMatrix(prediction, reference = test_set$label)
    
    # extract F1 score for all classes
    cm[["byClass"]][ , "F1"] #for multiclass classification problems
    

    您也可以将以下任何内容替换为“F1”以提取相关值:

    “灵敏度”、“特异性”、“Pos Pred Value”、“Neg Pred Value”、“Precision”、“Recall”、“F1”、“Prevalence”、“Detection”、“Rate”、“Detection Prevalence” ", "平衡精度"

    我认为,当您只处理二元分类问题时,其行为会略有不同,但在这两种情况下,当您查看 $byClass 下的confusionMatrix 对象内部时,都会为您计算所有这些值。

    【讨论】:

      【解决方案4】:

      caret 包中的confusionMatrix() 可以与适当的可选字段“Positive”一起使用,该字段指定应将哪个因素视为正因素。

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

      此代码还将提供附加值,例如 F-statistic、Accuracy 等。

      【讨论】:

      • 或者您可以只 (mode = "everything") 打印所有统计信息。
      【解决方案5】:

      我注意到有关二元类需要 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)))))
      

      【讨论】:

        【解决方案6】:

        我们可以简单地从插入符号的confusionMatrix函数中得到F1值

        result <- confusionMatrix(Prediction, Lable)
        
        # View confusion matrix overall
        result 
        
        # F1 value
        result$byClass[7] 
        

        【讨论】:

        • 不是F1值
        【解决方案7】:

        您也可以使用caret 包提供的confusionMatrix()。输出包括敏感度(也称为召回率)和 Pos Pred 值(也称为精度)。如上所述,F1 可以很容易地计算为: F1 &lt;- (2 * precision * recall) / (precision + recall)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-04-16
          • 1970-01-01
          • 2017-05-28
          • 2017-06-21
          • 2019-11-16
          • 2012-11-26
          • 2020-10-02
          相关资源
          最近更新 更多