使用po('imputelearner')出现额外factor水平的技术咨询
在mlr3中插补因子后出现无观测值的额外'factor'水平的问题解决
问题原因
这个现象不是预期行为,根源出在classif.rpart分类器的预测逻辑上:当用它处理因子类型的缺失值插补时,模型输出的预测结果会被强制转换为因子,但内部处理时错误引入了名为factor的额外水平,且没有任何观测值对应这个水平,最终导致后续编码步骤生成了无用的var1.factor列。
解决方法
有两种直接有效的处理方式:
方法1:用fixfactors自动清理无用水平
在插补和编码之间加入po("fixfactors")预处理算子,它会自动剔除没有对应观测值的因子水平,完全避免无用编码列的生成:
library(mlr3verse) set.seed(42) data = data.table::data.table(y = runif(100), var1 = as.factor(c(NA, rep('a', 49), rep('b', 49), NA)), var2 = c(runif(50, min = 3, max = 5), runif(50)), var3 = runif(10)) task = TaskRegr$new("example", data, target = "y") # 修改预处理管道,加入fixfactors imp = po('imputelearner', lrn('classif.rpart')) pre = imp %>>% po("fixfactors") %>>% po('encode', method = 'treatment') task2 = pre$train(task)[[1L]] task2$missings() #> y var2 var3 var1.b #> 0 0 0 0
方法2:手动对齐因子水平
如果需要更精细的控制,可以在插补后手动修正因子的水平列表,确保和原变量一致:
imp = po('imputelearner', lrn('classif.rpart', predict_type = "response")) task3 = imp$train(list(task))[[1L]] # 手动修正var1的因子水平,移除无观测的'factor'水平 task3$col_info[task3$col_info$id == "var1", "levels"] = list(c("a", "b")) # 再执行编码 pre = po('encode', method = 'treatment') task2 = pre$train(task3)[[1L]]
验证效果
两种方法处理后,都会得到符合预期的结果:无用的var1.factor列被移除,编码后的特征仅保留var1.b,对应原因子的2个水平(处理编码会保留一个对比基准列)。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

