使用confusionMatrix`data`和`reference`的错误应该是相同级别的因子

问题描述 投票:1回答:1

我第一次使用R(在R Studio中),因此对任何愚蠢的错误表示歉意。

我正在运行机器学习模型。在我的脚本中,出现以下错误,

Error: `data` and `reference` should be factors with the same levels. 
4. stop("`data` and `reference` should be factors with the same levels.", call. = FALSE) 
3. confusionMatrix.default(Y.pr, Y.ob) 

当我进入confusionMatrix时,我有点困惑。

数据(我的Y.pr)变量存储在数据部分下,而引用(我的Y.ob)变量存储在值下。当我单击参考时,它显示

num [1:8593] 0 0 1 1 1 0 0 0 1 1 ...

我展开时的数据变量如下所示。

Large matrix (8593 elements, 604.6 kb)
- attr(*, "dimnames")= List of 2
..$ : chr [1:8593] "34371" "34372" "34373" "34374" ...
..$ : NULL

对我来说,没有任何意义。我猜是Null引起了问题?

更新

使用相同的数据,我可以在Python中运行完全正常的模型

更新结束

r confusion-matrix
1个回答
0
投票

我将从?confusionMatrix的示例开始研究错误,然后采取一种从错误中恢复的方法。

前置

此答案逐步解决问题的方式是通过将级别分配给非factor变量。如果您不确定地知道数字水平相对于pred的含义,则您的临床研究已经结束:任何结果都是可疑且不可辩驳的。其余的答案假设您对级别有所确定(或者您只是在玩游戏,并且没有正式的学习或调查或任何有关此数据的信息)。即使原始数据不是factor,验证关键是“ 1”和“ 2”(或任何数字)的含义也是至关重要的一步。

示范

library(caret)
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))

head(truth)
# [1] normal normal normal normal normal normal
# Levels: abnormal normal
head(pred)
# [1] normal normal normal normal normal normal
# Levels: abnormal normal

正常(理想)执行:

confusionMatrix(pred, truth)
# Confusion Matrix and Statistics
#           Reference
# Prediction abnormal normal
#   abnormal      231     32
#   normal         27     54
#                                           
#                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          
#                                           
#        'Positive' Class : abnormal        

但是,如果第二个参数不是一个因数呢?

truth_num <- as.integer(truth)
head(truth_num)
# [1] 2 2 2 2 2 2
confusionMatrix(pred, truth_num)
# Error: `data` and `reference` should be factors with the same levels.

修复

我们需要做的是将truth_num带回到一个因数。

[首先,理论:如果它是某个点factor并以某种方式转换为integer,那么它就是一堆1s和2s(最初是其水平上的指数)。如果不是一个因素,那么实际上可以是任何数字,但最重要的是:我们知道哪个(整数)是哪个(级别)吗?如果您猜错了,那么您的测试将给出绝对错误的结果(没有错误/警告)。

table(pred)
# pred
# abnormal   normal 
#      263       81 
table(truth_num)
# truth_num
#   1   2 
# 258  86 

仅查看相对比例建议 truth_num的水平应该与c("abnormal", "normal")中的水平相同。 (但是请再次阅读我关于追赶结果的最高记录;不要相信比例,请返回源数据以找出哪个是哪个。)这就是我们设置的方式。从索引到因子有几种方法,这里有两种:

### one way
truth_num_fac <- factor(truth_num)
levels(truth_num_fac)
# [1] "1" "2"
head(truth_num_fac)
# [1] 2 2 2 2 2 2
# Levels: 1 2
levels(truth_num_fac) <- levels(pred)
head(truth_num_fac)
# [1] normal normal normal normal normal normal
# Levels: abnormal normal

### another way
dput(head(pred))
# structure(c(2L, 2L, 2L, 2L, 2L, 2L), .Label = c("abnormal", "normal"
# ), class = "factor")
truth_num_fac <- structure(truth_num, .Label = levels(pred), class = "factor")
head(truth_num_fac)
# [1] normal normal normal normal normal normal
# Levels: abnormal normal

无论哪种方法,测试现在都可以进行。

confusionMatrix(pred, truth_num_fac)
# Confusion Matrix and Statistics
#           Reference
# Prediction abnormal normal
#   abnormal      231     32
#   normal         27     54
#                                           
#                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          
#                                           
#        'Positive' Class : abnormal        
#                                           

如果......

  • 级别正确,但是您会看到此警告:

    confusionMatrix(pred, truth_num_fac)
    # Warning in confusionMatrix.default(pred, truth_num_fac) :
    #   Levels are not in the same order for reference and data. Refactoring data to match.
    # Confusion Matrix and Statistics
    ### ...
    

    这表示您的级别不相同。解决方法并不难:

    levels(pred)
    # [1] "abnormal" "normal"
    levels(truth_num_fac)
    # [1] "normal"   "abnormal"                     <---- abnormal should be first, according to pred
    truth_num_fac <- relevel(truth_num_fac, "abnormal")
    confusionMatrix(pred, truth_num_fac)
    # Confusion Matrix and Statistics
    
  • 级别不正确?尽管测试结果会大不相同,但您不会收到任何错误或警告;这并不意味着您应该追求理想的结果,但是如果它们严重错误,则值得关注:

    ### setup for backwards data
    truth_num_fac_backwards <- structure(truth_num, .Label = rev(levels(pred)), class = "factor")
    truth_num_fac_backwards <- relevel(truth_num_fac_backwards, "abnormal")
    head(truth_num_fac_backwards)
    # [1] abnormal abnormal abnormal abnormal abnormal abnormal
    # Levels: abnormal normal
    
    confusionMatrix(pred, truth_num_fac_backwards)
    # Confusion Matrix and Statistics
    #           Reference
    # Prediction abnormal normal
    #   abnormal       32    231
    #   normal         54     27
    #                                           
    #                Accuracy : 0.1715              <----- OUCH
    #                  95% CI : (0.1332, 0.2156)
    #     No Information Rate : 0.75            
    #     P-Value [Acc > NIR] : 1               
    #                                           
    #                   Kappa : -0.3103         
    #  Mcnemar's Test P-Value : <2e-16          
    #                                           
    #             Sensitivity : 0.37209         
    #             Specificity : 0.10465         
    #          Pos Pred Value : 0.12167         
    #          Neg Pred Value : 0.33333         
    #              Prevalence : 0.25000         
    #          Detection Rate : 0.09302         
    #    Detection Prevalence : 0.76453         
    #       Balanced Accuracy : 0.23837         
    #                                           
    #        'Positive' Class : abnormal        
    #   
    

    解决此问题的正确方法是返回并验证哪个级别。可能是您做对了,结果告诉您,情况并非很好。 (我认为)其他任何修复方法都是追求结果:确保您第一次获得正确的数据,请勿更改数据以符合您的预期结果。

  • 我试图将数字向量转换为factor,但是levels(...)返回NULL

    这很可能是因为您的非数字矢量不是factor,而是character。此修复程序应该很容易:

    ### setup for fake character data
    pred_chr <- pred
    pred_chr <- as.character(pred)
    head(pred_chr)
    # [1] "normal" "normal" "normal" "normal" "normal" "normal"
    
    ### the remedy
    pred_chr_fac <- factor(pred_chr)
    head(pred_chr_fac)
    # [1] normal normal normal normal normal normal
    # Levels: abnormal normal
    levels(pred_chr_fac)
    # [1] "abnormal" "normal"  
    
© www.soinside.com 2019 - 2024. All rights reserved.