将混淆矩阵的输出保存为.csv表格文件。

9

我有下面这段代码,输出结果类似于表格

 lvs <- c("normal", "abnormal")
 truth <- factor(rep(lvs, times = c(86, 258)),
                 levels = rev(lvs))
 pred <- factor(
                c(
                  rep(lvs, times = c(54, 32)),
                  rep(lvs, times = c(27, 231))),               
                levels = rev(lvs))

 xtab <- table(pred, truth)

 library(caret)
 confusionMatrix(xtab)

 confusionMatrix(pred, truth)
 confusionMatrix(xtab, prevalence = 0.25)   

我希望将以下输出结果的部分导出为.csv表格。
               Accuracy : 0.8285          
                 95% CI : (0.7844, 0.8668)
    No Information Rate : 0.75            
    P-Value [Acc > NIR] : 0.0003097       

                  Kappa : 0.5336          
 Mcnemar's Test P-Value : 0.6025370       

            Sensitivity : 0.8953          
            Specificity : 0.6279          
         Pos Pred Value : 0.8783          
         Neg Pred Value : 0.6667          
             Prevalence : 0.7500          
         Detection Rate : 0.6715          
   Detection Prevalence : 0.7645          
      Balanced Accuracy : 0.7616  

尝试将其写成.csv表格时出现错误消息:
write.csv(confusionMatrix(xtab),file="file.csv")
Error in as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors = stringsAsFactors) : 
cannot coerce class ""confusionMatrix"" to a data.frame

出于明显的原因,完全手动操作整个工作是不切实际的且容易出现人为错误。

有没有关于如何将其导出为.csv的建议?


你想要写的内容是不是以"键:值"的形式?根据错误提示,write.csv 函数需要一个数据框作为参数,因此你需要将结果转换成它可以接受的格式。 - steveb
只是为了澄清,您需要获取confusionMatrix的结果,并将所需的数据放入一个数据框中。 - steveb
@steveb 是的,我现在明白了。下面的 mroto 已经非常清楚地概述了它。 - Oposum
5个回答

8
使用 caret 包
results <- confusionMatrix(pred, truth)

as.table(results)会生成如下结果:

         Reference
Prediction  X1  X0
        X1  36  29
        X0 218 727

as.matrix(results,what="overall")返回:

Accuracy       7.554455e-01
Kappa          1.372895e-01
AccuracyLower  7.277208e-01
AccuracyUpper  7.816725e-01
AccuracyNull   7.485149e-01
AccuracyPValue 3.203599e-01
McnemarPValue  5.608817e-33

as.matrix(results, what = "classes")则会得到

Sensitivity          0.8953488
Specificity          0.6279070
Pos Pred Value       0.8783270
Neg Pred Value       0.6666667
Precision            0.8783270
Recall               0.8953488
F1                   0.8867562
Prevalence           0.7500000
Detection Rate       0.6715116
Detection Prevalence 0.7645349
Balanced Accuracy    0.7616279

使用这些命令和write.csv命令,您可以获得整个混淆矩阵信息。

7

好的,如果您检查confusionMatrix(xtab, prevalence = 0.25)的输出结果,它是一个列表:

cm <- confusionMatrix(pred, truth)
str(cm)

    List of 5
 $ positive: chr "abnormal"
 $ table   : 'table' int [1:2, 1:2] 231 27 32 54
  ..- attr(*, "dimnames")=List of 2
  .. ..$ Prediction: chr [1:2] "abnormal" "normal"
  .. ..$ Reference : chr [1:2] "abnormal" "normal"
 $ overall : Named num [1:7] 0.828 0.534 0.784 0.867 0.75 ...
  ..- attr(*, "names")= chr [1:7] "Accuracy" "Kappa" "AccuracyLower" "AccuracyUpper" ...
 $ byClass : Named num [1:8] 0.895 0.628 0.878 0.667 0.75 ...
  ..- attr(*, "names")= chr [1:8] "Sensitivity" "Specificity" "Pos Pred Value" "Neg Pred Value" ...
 $ dots    : list()
 - attr(*, "class")= chr "confusionMatrix"

从这里开始,您可以选择要创建CSV文件的适当对象,并创建一个数据框,该数据框将具有每个变量的列。在您的情况下,这将是:

tocsv <- data.frame(cbind(t(cm$overall),t(cm$byClass)))

# You can then use
write.csv(tocsv,file="file.csv")

谢谢,这非常接近。实际上,我稍微修改了您的代码以获得我想要的结果:tocsv<-as.data.frame(t(data.frame(cbind(t(cm$byClass),t(cm$overall))))) 但是,如果可以问一下,您为什么一开始就要进行转置呢?此外,在进入 tocsv 阶段之前有没有办法将数字值四舍五入?我知道之后我可以命名列,将其舍入,然后替换它,但我想知道是否有更有效的方法在初始阶段完成。 - Oposum
我注意到代码更改了原始行“95% CI:(0.7844,0.8668)”,并显示了这两行:“AccuracyLower 0.7844134380”和“AccuracyUpper 0.8667985207”。是否有办法保留原来的方式“95% CI:(0.7844,0.8668)”? - Oposum
1
默认情况下,byClassoverall被命名为数字向量,它们在当前形式下无法进行cbind操作。如果你对它们进行转置,你会创建一个名称与值并列的字符向量。至于是否要对它们进行四舍五入,可能是可以的,但通常最好的做法是如果你有新问题,请提出新的问题,而不是把它们塞在评论中。 - mtoto

2

我发现capture.output对我来说效果最好。

它只是将您的输出复制为.csv文件

(您也可以将其保存为.txt)

capture.output(
confusionMatrix(xtab, prevalence = 0.25),
 file = "F:/Home Office/result.csv")

0
如果A是一个caret::confusionMatrix对象,则:
broom::tidy(A) %>% writexl::write_xlsx("mymatrix.xlsx")


可选择将 writexl 替换为 write.csv()

还可以在单独的工作表中包含表格:

broom::tidy(A) %>% list(as.data.frame(A$table)) %>% writexl::write_xlsx("mymatrix.xlsx")

0

最简单的解决方案是使用readr::write_rds直接写出。您可以在保持confusionMatrix结构完整的同时导出和导入。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接