我第一次使用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中运行完全正常的模型
更新结束
我将从?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"