You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 00:15:50