R语言线性模型使用因子特征时predict()函数报错如何解决?
问题根因
报错的核心原因是模型训练阶段Smoker_YN、Male_YN、Caesarean_YN这几个二值列被识别为因子类型,R原生lm()函数拟合因子预测变量时,会自动为非参照水平添加数字后缀生成衍生变量名(比如二值因子Smoker_YN的第二个水平会被重命名为Smoker_YN1),但测试集里的对应列是原始数值型,不存在衍生后的列名,因此预测时匹配不到变量。
你之前直接提取LinearModel$finalModel做预测也放大了这个问题:caret的train返回的完整模型对象自带预处理对齐逻辑,但底层的lm对象没有保留这部分逻辑,直接调用会跳过变量校验对齐步骤。
解决方法
方案1(优先推荐):用caret返回的完整模型对象做预测
不需要提取finalModel,直接用train生成的LinearModel对象调用predict,caret会自动对齐训练集和测试集的变量规则:
lmPredictions <- predict(LinearModel, newdata = test)
90%以上的同类问题都可以通过这个方法直接解决。
方案2:强制明确二值列为数值类型,重新训练模型
如果方案1无效,可在训练前强制指定所有二值列为数值类型,避免被误识别为因子:
# 校验并转换训练集列类型 str(train) train$Smoker_YN <- as.numeric(train$Smoker_YN) train$Male_YN <- as.numeric(train$Male_YN) train$Caesarean_YN <- as.numeric(train$Caesarean_YN) # 同步转换测试集列类型 test$Smoker_YN <- as.numeric(test$Smoker_YN) test$Male_YN <- as.numeric(test$Male_YN) test$Caesarean_YN <- as.numeric(test$Caesarean_YN) # 重新训练模型 set.seed(3) control <- trainControl(method="cv", number = 5) LinearModel <- train(LungCap ~ ., data = train, method = "lm", trControl = control) LM <- LinearModel$finalModel # 再执行预测即可 lmPredictions <- predict(LM, newdata = test)
方案3(兜底方案):修改lm对象的变量名规则
如果你必须使用已训练好的finalModel对象做预测,可以手动修改模型的系数名和变量属性,对齐测试集列名:
# 清除系数名的数字后缀 names(LM$coefficients) <- gsub("(Smoker_YN|Male_YN|Caesarean_YN)1", "\\1", names(LM$coefficients)) # 同步更新模型的terms属性变量列表 attr(LM$terms, "variables") <- list( as.name("LungCap"), as.name("Age"), as.name("Height"), as.name("Smoker_YN"), as.name("Male_YN"), as.name("Caesarean_YN") ) # 再执行预测即可 lmPredictions <- predict(LM, newdata = test)
内容的提问来源于stack exchange,提问作者Jairaj Ranchod
相关产品推荐
相关产品推荐

