R语言confusionMatrix报错解决:数据层级不可多于参考值
解决caret包
confusionMatrix函数报错问题 问题背景
我有一个名为PowderyMildewEpidemic的数据框,完成逻辑回归预测后,使用caret包的confusionMatrix生成混淆矩阵时触发报错:
Error in confusionMatrix.default(as.factor(ifelse(Mildew.predict2 > 0.5, : the data cannot have more levels than the reference
检查发现预测值和真实值的nlevels返回均为0:
nlevels(ifelse(Mildew.predict2 > 0.5, 1, 0)) nlevels(PowderyMildewEpidemic[11:12, ]$Agree)
数据详情
structure(list(Year = c(1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000), Outbreak = c("Yes", "No", "No", "Yes", "No", "Yes", "No", "Yes", "No", "Yes", "No", "No"), MaxTemp = c(30.14, 30.66, 26.31, 28.43, 29.57, 31.25, 30.35, 30.71, 30.71, 33.07, 31.5, 29.5), RelHumidity = c(82.86, 79.57, 89.14, 91, 80.57, 67.82, 61.76, 81.14, 61.57, 59.76, 68.29, 79.14)), row.names = c(NA, -12L), spec = structure(list(cols = list(Year = structure(list(), class = c("collector_double", "collector")), Outbreak = structure(list(), class = c("collector_character", "collector")), MaxTemp = structure(list(), class = c("collector_double", "collector")), RelHumidity = structure(list(), class = c("collector_double", "collector"))), default = structure(list(), class = c("collector_guess", "collector")), delim = ","), class = "col_spec"), class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"))
运行代码
PowderyMildewEpidemic$Agree <- ifelse(PowderyMildewEpidemic$Outbreak == "Yes", 1, 0) # 1997年预测 # train2:使用1987-1996年数据训练 train2 <- PowderyMildewEpidemic[1:10, ] # 逻辑回归模型 Mildew.lr2 <- glm(formula = Agree ~ MaxTemp + RelHumidity, data = train2, family = "binomial") summary(Mildew.lr2) # 预测 Mildew.predict2 <- predict(Mildew.lr2, PowderyMildewEpidemic[11:12, ], type = "response") Mildew.predict2 # 1997年预测结果 Mildew.predict2[1] # 1997年逻辑回归分类矩阵 confusionMatrix(as.factor(ifelse(Mildew.predict2 > 0.5, 1, 0)), as.factor(PowderyMildewEpidemic[11:12, ]$Agree))
报错原因
核心问题在于测试集的真实值水平不完整:你选取的11-12行数据中,Outbreak均为"No",因此Agree列全为0。直接转成因子后,真实值仅包含0这一个水平;而预测值经过ifelse(Mildew.predict2 > 0.5, 1, 0)处理后,可能同时出现0和1两个水平,导致预测值的水平数多于真实值,触发confusionMatrix的报错机制。
另外,ifelse返回的是数值型向量,直接用nlevels()检测会返回0,因为数值型不是因子类型,这也是你看到nlevels均为0的原因。
解决方案
手动指定因子的levels参数,确保预测值和真实值的因子水平完全一致,且覆盖所有可能的类别(0和1),即使测试集中没有某个类别也要明确指定:
# 统一指定因子水平为c(0,1) pred_factor <- factor(ifelse(Mildew.predict2 > 0.5, 1, 0), levels = c(0, 1)) true_factor <- factor(PowderyMildewEpidemic[11:12, ]$Agree, levels = c(0, 1)) # 生成混淆矩阵 confusionMatrix(pred_factor, true_factor)
这样处理后,真实值的因子会保留0和1两个水平(即使测试集中没有1),预测值的水平也与之匹配,就能正常生成混淆矩阵,同时还能正确展示所有类别的预测结果(比如1类的预测情况会显示为0)。
内容的提问来源于stack exchange,提问作者c200402
相关产品推荐
相关产品推荐

