将分类变量设为因子后测试集水平缺失导致模型预测报错
问题解决:predict.glm报错“object 'revenu3' not found”
错误根源
这个错误的核心原因是训练集与测试集的revenu因子水平不匹配:当你仅在训练集将revenu转为因子时,模型会基于训练集的现有类别生成哑变量(比如训练集只有revenu1、revenu2,则生成revenu2这一个哑变量);但测试集单独转因子时,若存在训练集没有的revenu3类别,会额外生成revenu3哑变量,导致模型预测时找不到对应变量,触发报错。
具体解决方案
方案1:先统一全量数据的因子水平,再划分数据集
这是最稳妥的做法,确保所有子集的因子水平完全一致:
mydata <- read.csv("rodeo.csv") # 先在全量数据集上定义分类变量为因子 mydata$emploi <- as.factor(mydata$emploi) mydata$revenu <- as.factor(mydata$revenu) mydata$rodeo <- as.factor(mydata$rodeo) # 再执行数据集划分 set.seed(200) n <- nrow(mydata) id.train <- sample(1:n, 300, replace=FALSE) id.valid <- sample(setdiff(1:n, id.train), 100, replace=FALSE) id.test <- setdiff(setdiff(1:n, id.train), id.valid) mydata.train <- mydata[id.train,] mydata.valid <- mydata[id.valid,] mydata.test <- mydata[id.test,]
方案2:手动对齐已划分数据集的因子水平
如果不想重新划分数据集,可强制将测试集的因子水平与训练集保持一致:
# 对齐revenu的因子水平 mydata.test$revenu <- factor(mydata.test$revenu, levels = levels(mydata.train$revenu)) # 同步对齐其他分类变量 mydata.test$emploi <- factor(mydata.test$emploi, levels = levels(mydata.train$emploi)) mydata.test$rodeo <- factor(mydata.test$rodeo, levels = levels(mydata.train$rodeo))
注:若测试集存在训练集没有的类别,该类别会被标记为NA,但不会触发变量找不到的错误。
方案3:使用caret的predict方法替代predict.glm
直接调用caret训练得到的model对象的predict方法,它会自动处理因子水平对齐问题,比predict.glm更安全:
# 输出两类的概率 prob.predict <- predict(model, mydata.test, type = "prob") # 若仅需正类概率,取对应列(根据你的new_achat水平调整列索引) prob.predict <- predict(model, mydata.test, type = "prob")[,2]
内容的提问来源于stack exchange,提问作者ebrahimi
相关产品推荐
相关产品推荐

