【问题标题】:R - conditional replacement of missing factors in confusion matrixR - 混淆矩阵中缺失因子的条件替换
【发布时间】:2018-06-22 09:58:51
【问题描述】:

我正在为大量样本点数据集创建混淆矩阵,并且需要通过 R 包 caret 使用 confusionMatrix 函数循环遍历它们(我正在使用输出中的准确度指标,即我可以'不要只使用table)。每组样本点应该有 三个 类/因子,即我应该有 3x3 表,但是一些参考和预测数据包含少于两个类或不重叠的类,例如:

 Class  A  B             Class  C
   A    8  2               A    3
   B    1  0
   C    1  7
* columns = reference data, rows = predicted data

我需要相同数量的类/因子来运行confusionMatrix,所以我想做的是有条件地用零替换缺失的因子,如下所示:

 Class  A  B  C          Class  A  B  C
   A    8  2  0            A    0  0  3
   B    1  0  0            B    0  0  0
   C    1  7  0            C    0  0  0

我使用的预测/参考数据是数值的数字列表,所以我不会在这里复制它们;对于我上面提供的示例,您可以将其视为一个向量,例如:

predicted.data[1] = A A A A A A A A A A B C C C C C C C C
reference.data[1] = A A A A A A A A A A B B B B B B B B B
predicted.data[2] = A A A
reference.data[2] = C C C 

我尝试按照以下方式创建某种条件if 语句:

   tab <- table(predicted.data, reference.data)
   if(nrow(tab) != ncol(tab){
   classes <- c("A","B","C")
   missing <- setdiff(classes,names(tab))
   ...
   ...
   }

# would put in a loop/index actual data obviously 

但我似乎无法让它按我想要的方式工作。有什么想法吗?

编辑:我正在使用的实际数据示例(通过栅格/形状文件)和错误消息;数据长度相同,但没有参考数据被归类为“2”:

> mask.vals[[4]]
  [1] 0 4 0 0 0 2 4 0 4 0 4 0 0 0 0 0 4 0 4 2 0 0 0 0 0 0 0 4 0 0 0 0 0 0 4 0 
0 0 0 0 0 0 0 2 2 0 2 0 4 0 0 4 2 0 0 4 0 0 0 0 0 0 0 2 0 2 0 2 4 0 4
 [72] 4 0 0 0 0 4 4 0 0 0 0 0 0 0 4 0 0 0 0 4 4 4 4 0 4 4 4 4 4 0 4 4 4 0 4 0 
0 4 4 4 4 4 4

> ref.data[[4]]@data$CLASS_ID
  [1] 0 4 4 4 4 4 4 4 4 4 4 4 4 4 0 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
 [72] 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
4 4 4 4 4 4 4

> confusionMatrix(data = mask.vals[[4]], reference = ref.data[[4]]@data$CLASS_ID)

Error in confusionMatrix.default(data = mask.vals[[4]], reference = ref.data[[4]]@data$CLASS_ID) : 
  the data cannot have more levels than the reference

即需要从这里开始:

> table(mask.vals[[4]], ref.data[[4]]@data$CLASS_ID)
        0  4          
   0    2  67              
   2    0  9
   4    0  36

到这里:

        0  2  4          
   0    2  0  67              
   2    0  0  9
   4    0  0  36

即使我为数据定义了三个级别(例如levels(ref.data[[4]]@data$CLASS_ID) &lt;- c("0","2","4")factor(ref.data[[4]]@data$CLASS_ID, levels = c("0","2","4")),此错误仍然存​​在...

【问题讨论】:

  • raster 包没有confusionMatrix 函数。你在用caret::confusionMatrix吗?如果您有三个类,那么混淆矩阵不是 3x3 表吗?如果您发布一个可重现的示例(即我们可以用来重现并希望能解决您的问题的数据示例和代码),将会更容易为您提供帮助。

标签: r matrix machine-learning classification confusion-matrix


【解决方案1】:

caretconfusionMatrix 函数返回一个 n x n 表,无论参考和/或预测向量中是否缺少某些级别。我想知道您是如何设法获得一个缺少一些参考数据列的混淆矩阵。比如使用内置的iris数据框:

library(caret)

set.seed(2)
dat = data.frame(ref=iris$Species, pred=sample(iris$Species))

# Remove two levels from the reference data
dat1 = dat[dat$ref=="setosa", ]

# Get the confusion matrix
cm1 = confusionMatrix(dat1$pred, dat1$ref)

cm1$table
            Reference
Prediction   setosa versicolor virginica
  setosa         15          0         0
  versicolor     15          0         0
  virginica      20          0         0
# No overlap between reference and prediction
dat2 = dat[dat$ref=="setosa" & dat$pred=="versicolor", ]

# Get the confusion matrix
cm2 = confusionMatrix(dat2$pred, dat2$ref)

cm2$table
            Reference
Prediction   setosa versicolor virginica
  setosa          0          0         0
  versicolor     15          0         0
  virginica       0          0         0

在上面的示例中,refpred 列都被编码为具有原始三个级别 Species 的因子。我们可以重新编码它们以删除空级别:

dat2$ref = droplevels(dat2$ref)
dat2$pred = droplevels(dat2$pred)

您可以看到每一列中只有一个因子水平:

lapply(dat2, levels)    
$ref [1] "setosa"

$pred [1] "versicolor"

但是如果你运行 confusionMatrix 它现在会抛出一个错误,因为两个向量的级别之间没有重叠:

cm3 = confusionMatrix(dat2$pred, dat2$ref)

confusionMatrix.default(dat2$pred, dat2$ref) 中的错误:数据 必须包含一些与引用重叠的级别。

更新:如果您在参考向量和预测向量中设置相同的因子水平,confusionMatrix 将起作用。您已经更新了问题,但它仍然无法重现,因此很难确定您的工作流程中哪里出了问题。现在,这里有一个与您在问题中显示的示例类似的示例,并且在设置公因子水平后按预期工作。

library(caret)

set.seed(2)
mask.vals = sample(c(0,2,4), 100, replace=TRUE)
ref.data = rep(4,100)

cm = confusionMatrix(mask.vals, ref.data)
Error in confusionMatrix.default(mask.vals, ref.data) : 
  the data cannot have more levels than the reference
mask.vals = factor(mask.vals, levels=c(0,2,4))
ref.data = factor(ref.data, levels=c(0,2,4))

cm = confusionMatrix(mask.vals, ref.data) 

cm$table
          Reference
Prediction  0  2  4
         0  0  0 35
         2  0  0 31
         4  0  0 34

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-25
    • 2022-01-05
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多