R - 混淆矩阵中缺失因子的条件替换
R - conditional replacement of missing factors in confusion matrix
我正在为大量样本点创建混淆矩阵,需要通过 R 包 caret
使用 confusionMatrix
函数循环遍历它们(我正在使用来自输出即我不能只使用 table
)。每组样本点应该有 三个 classes/factors,即我应该有 3x3 表,但是一些参考和预测数据包含少于两个 类 , 或非重叠 类 ex:
Class A B Class C
A 8 2 A 3
B 1 0
C 1 7
* columns = reference data, rows = predicted data
我需要相同数量的 classes/factors 到 运行 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/reference 数据是数值列表,所以我不会在这里重现它们;对于我上面提供的示例,您可以将其视为一个向量,例如:
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
但我似乎无法让它按照我想要的方式工作。有什么想法吗?
编辑:我正在使用的实际数据示例(通过 rasters/shapefiles)和错误消息;数据长度相同但没有参考数据被归类为“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
函数 returns n x n table 无论参考 and/or 预测向量中是否缺少某些级别。我想知道你是如何设法得到一个缺少一些参考数据列的混淆矩阵的。例如,使用内置的 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
在上面的例子中,ref
和 pred
列都被编码为具有 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
Reference
Prediction 0 2 4
0 0 0 35
2 0 0 31
4 0 0 34
我正在为大量样本点创建混淆矩阵,需要通过 R 包 caret
使用 confusionMatrix
函数循环遍历它们(我正在使用来自输出即我不能只使用 table
)。每组样本点应该有 三个 classes/factors,即我应该有 3x3 表,但是一些参考和预测数据包含少于两个 类 , 或非重叠 类 ex:
Class A B Class C
A 8 2 A 3
B 1 0
C 1 7
* columns = reference data, rows = predicted data
我需要相同数量的 classes/factors 到 运行 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/reference 数据是数值列表,所以我不会在这里重现它们;对于我上面提供的示例,您可以将其视为一个向量,例如:
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
但我似乎无法让它按照我想要的方式工作。有什么想法吗?
编辑:我正在使用的实际数据示例(通过 rasters/shapefiles)和错误消息;数据长度相同但没有参考数据被归类为“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
函数 returns n x n table 无论参考 and/or 预测向量中是否缺少某些级别。我想知道你是如何设法得到一个缺少一些参考数据列的混淆矩阵的。例如,使用内置的 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
在上面的例子中,ref
和 pred
列都被编码为具有 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
Reference Prediction 0 2 4 0 0 0 35 2 0 0 31 4 0 0 34