求助:R语言中caret包LDA模型predict函数输出预测值数量少于测试集观测数的问题
解决caret包LDA模型predict结果数量少于测试集的问题
我之前也碰到过一模一样的情况,大概率是测试集缺失值或者训练/测试数据结构不一致导致的,咱们一步步排查解决:
1. 优先检查测试集中的缺失值
caret封装的LDA模型(底层依赖MASS的lda)默认会自动移除带有缺失值的行(na.action = na.omit),这是最常见的原因。你可以先运行以下代码确认:
# 统计测试集各列的缺失值数量 colSums(is.na(testing)) # 查看所有包含缺失值的行 testing[!complete.cases(testing), ]
如果确实有缺失值,有两种解决思路:
方案A:提前清理缺失值
直接移除测试集的缺失行,或者用均值/中位数填充(推荐训练时同步处理):
# 移除缺失行 testing_clean <- testing[complete.cases(testing), ] # 或者用caret的preProcess填充缺失值,同时做标准化 modelo_temp <- train(as.factor(d_evento) ~ WCTA + RETA_div + EBITTA + MKTTL, data = training, method = "lda", trControl = control, preProcess = c("center", "scale", "impute"))
方案B:修改模型的缺失值处理规则
训练模型时指定保留缺失值(后续需要自己处理预测结果中的NA):
modelo_temp <- train(as.factor(d_evento) ~ WCTA + RETA_div + EBITTA + MKTTL, data = training, method = "lda", trControl = control, na.action = na.pass) # 预测时同样指定保留所有行 prediccion <- predict(modelo_t, datos_t, na.action = na.pass)
2. 验证训练集和测试集的结构一致性
有时候测试集的列名、数据类型和训练集不一致,也会导致predict时悄悄过滤行:
# 检查特征列名是否完全一致(排除响应变量d_evento) train_features <- setdiff(colnames(training), "d_evento") test_features <- setdiff(colnames(testing), "d_evento") all(train_features == test_features) # 检查各特征的数据类型是否一致 sapply(training[, train_features], class) sapply(testing[, test_features], class)
如果发现不一致,比如测试集多了列或者数据类型不对,要先统一两者的结构。
3. 定位被过滤的具体行
你可以对比测试集和预测结果的行名,找出被过滤的行,针对性排查异常:
# 获取预测结果对应的行名(用prob类型能保留行名) pred_rows <- rownames(predict(modelo_t, datos_t, type = "prob")) # 找出测试集中没被预测的行 missing_rows <- datos_t[!rownames(datos_t) %in% pred_rows, ] # 查看这些行的特征,找异常 str(missing_rows)
为什么MASS的LDA没问题?
大概率是你在使用MASS的lda时,测试集刚好没有缺失值,或者你手动处理过缺失值;而caret的train在交叉验证过程中,默认的缺失值处理规则和直接调用MASSlda的场景不同,导致predict时过滤了行。
内容的提问来源于stack exchange,提问作者Ricky
相关产品推荐
相关产品推荐

