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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 23:18:33