mlr3回归任务中目标变量缺失值插补问题求助
mlr3回归任务目标变量缺失值插补方案(适配RollingWindowCV)
针对你遇到的回归任务目标变量缺失、且需配合RollingWindowCV重采样的问题,以下是几种可行的解决方法:
方法1:手动时序预处理后创建任务
时间序列场景下,目标变量的缺失通常适合用时序相关的插补逻辑(如前向填充、滑动窗口均值),预处理后再创建回归任务是最直接的方式:
library(mlr3) library(mlr3temporal) library(dplyr) library(tidyr) # 假设你的数据集是df,目标列是T.means.hr df_processed <- df %>% # 前向填充(适合时序数据),也可替换为滑动窗口均值等逻辑 fill(T.means.hr, .direction = "down") %>% # 处理开头的缺失值(用第一个非缺失值填充) mutate(T.means.hr = ifelse(is.na(T.means.hr), first(T.means.hr[!is.na(T.means.hr)]), T.means.hr)) # 创建无缺失的回归任务 task <- as_task_regr(df_processed, target = "T.means.hr", id = "Airtemp") # 后续正常使用RollingWindowCV resampling <- rsmp("rolling_window", window_size = 10, horizon = 1)
方法2:自定义PipeOp处理目标变量
如果想把目标变量插补整合到mlr3的管道中(方便和其他预处理步骤联动),可以自定义一个PipeOp专门处理目标列:
library(mlr3pipelines) # 自定义目标变量插补PipeOp PipeOpImputeTarget <- R6::R6Class("PipeOpImputeTarget", inherit = PipeOpTaskPreproc, public = list( initialize = function(id = "impute_target", param_vals = list()) { super$initialize(id, param_vals = param_vals) } ), private = list( .train_task = function(task) { # 训练阶段记录目标列的插补基准值(这里用均值,可替换为时序逻辑) target_col <- task$target_names impute_val <- task$data() %>% pull(target_col) %>% mean(na.rm = TRUE) self$state$impute_val <- impute_val # 填充训练集目标列缺失值 task$data()[, target_col] <- replace_na(task$data()[, target_col], impute_val) task }, .predict_task = function(task) { # 预测阶段用训练时的基准值填充 target_col <- task$target_names task$data()[, target_col] <- replace_na(task$data()[, target_col], self$state$impute_val) task } ) ) # 实例化PipeOp并构建完整管道 po_impute_target <- PipeOpImputeTarget$new() graph <- po_impute_target %>>% po("missind") %>>% po("imputehist") %>>% lrn("regr.ranger") # 创建带缺失值的初始任务 task <- as_task_regr(df, target = "T.means.hr", id = "Airtemp") # 配合RollingWindowCV重采样 resampling <- rsmp("rolling_window", window_size = 10, horizon = 1) rr <- resample(task, graph, resampling)
方法3:正确切换变量角色实现插补
你之前尝试的角色切换思路是可行的,只是操作步骤有误,正确流程如下:
# 1. 创建临时任务,将所有列设为特征 task_temp <- as_task_classif(df, id = "Airtemp_temp") task_temp$col_roles$target <- character(0) # 清空目标角色 task_temp$col_roles$feature <- colnames(df) # 所有列标记为特征 # 2. 用现有PipeOp插补所有特征(包括原目标列) graph_impute <- po("missind") %>>% po("imputehist") task_imputed <- graph_impute$train(list(task_temp))[[1]] # 3. 将原目标列改回目标角色 task_imputed$col_roles$target <- "T.means.hr" task_imputed$col_roles$feature <- setdiff(task_imputed$col_roles$feature, "T.means.hr") # 4. 转换为回归任务 task_final <- as_task_regr(task_imputed$data(), target = "T.means.hr", id = "Airtemp") # 后续使用RollingWindowCV resampling <- rsmp("rolling_window", window_size = 10, horizon = 1)
注意:这种方法适合非时序的插补逻辑(如直方图插补),如果是时序数据,更推荐方法1或自定义时序逻辑的PipeOp,避免破坏时序相关性。
内容的提问来源于stack exchange,提问作者Nucore
相关产品推荐
相关产品推荐

