R – 混淆矩阵中缺失因子的条件替换

我正在为一个大型样本点数据集创建混淆矩阵,并需要使用R包caret中的confusionMatrix函数对它们进行循环(我使用的是输出中的准确性指标,即我不能仅使用table)。每个样本点集应该有三个类/因子,即我应该有3×3的表格,然而一些参考和预测数据包含少于两个类,或者类别不重叠,例如:

 Class  A  B             Class  C   A    8  2               A    3   B    1  0   C    1  7* 列 = 参考数据,行 = 预测数据

我需要相同数量的类/因子来运行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 Creference.data[1] = A A A A A A A A A A B B B B B B B B Bpredicted.data[2] = A A Areference.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))   ...   ...   }# 显然会将实际数据放入循环/索引中

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

编辑:我使用的实际数据示例(通过栅格/形状文件)和错误消息;数据长度相同,但没有参考数据被分类为’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) <- c("0","2","4")factor(ref.data[[4]]@data$CLASS_ID, levels = c("0","2","4")),这个错误仍然存在…


回答:

caret包中的confusionMatrix函数会返回一个n x n的表格,无论参考和/或预测向量中是否缺少某些级别。我想知道你是如何设法得到一个混淆矩阵,其中一些参考数据列缺失的。例如,使用内置的iris数据框架:

library(caret)set.seed(2)dat = data.frame(ref=iris$Species, pred=sample(iris$Species))# 从参考数据中移除两个级别dat1 = dat[dat$ref=="setosa", ]# 获取混淆矩阵cm1 = confusionMatrix(dat1$pred, dat1$ref)cm1$table
            ReferencePrediction   setosa versicolor virginica  setosa         15          0         0  versicolor     15          0         0  virginica      20          0         0
# 参考和预测之间没有重叠dat2 = dat[dat$ref=="setosa" & dat$pred=="versicolor", ]# 获取混淆矩阵cm2 = confusionMatrix(dat2$pred, dat2$ref)cm2$table
            ReferencePrediction   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)

Error in confusionMatrix.default(dat2$pred, dat2$ref) : The data must contain some levels that overlap the reference.

更新: 如果您在参考向量和预测向量中设置相同的因子级别,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
          ReferencePrediction  0  2  4         0  0  0 35         2  0  0 31         4  0  0 34

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注