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

如何在caret中用虚拟变量按组训练时间序列模型并维持时间切片逻辑

解决方案:通用多组时间序列滚动预测实现

针对你的需求,我们可以通过手动生成训练/测试索引的方式替代timeslice的默认参数设置,这样既可以合并多组数据用虚拟变量建模,又能严格保证每个组的一步超前预测逻辑,而且完全不需要手动调整参数适配组数量。

步骤1:数据预处理与排序

首先生成虚拟变量,同时保留group和period用于后续索引生成,并且必须确保数据按组和时间周期排序,保证时序的正确性:

library(data.table)
library(caret)
set.seed(503)

# 生成原始数据
foo <- data.table(group = rep(LETTERS[1:6], 150),
                  y = rnorm(n = 6 * 150, mean = 5, sd = 2),
                  x1 = rnorm(n = 6 * 150, mean = 5, sd = 10),
                  x2 = rnorm(n = 6 * 150, mean = 25, sd = 10),
                  x3 = rnorm(n = 6 * 150, mean = 50, sd = 10),
                  x4 = rnorm(n = 6 * 150, mean = 0.5, sd = 10),
                  x5 = sample(c(1, 0), size = 6 * 150, replace = T))
foo[, period := 1:.N, by = group]

# 生成组虚拟变量,保留group和period用于索引
dat <- cbind(foo, model.matrix(~ group - 1, data = foo))
# 按组+周期排序,确保时序连续
setorder(dat, group, period)

步骤2:自动计算通用参数

我们先提取关键参数,所有计算都基于组数量和单组窗口长度,完全不需要手动硬编码:

n_groups <- length(unique(dat$group))          # 组数量
window_length_per_group <- 115                 # 单组训练窗口长度
n_periods_per_group <- max(dat$period)         # 单组总周期数
initial_window <- window_length_per_group * n_groups # 初始训练集总大小
n_reps <- n_periods_per_group - window_length_per_group # 滚动预测次数

步骤3:手动生成训练/测试索引

通过循环生成每次滚动的训练集和测试集索引,确保每次测试集都是所有组的下一个周期观测,严格对应一步超前预测:

train_indices <- list()
test_indices <- list()

for(i in 1:n_reps){
  # 训练集:包含所有组的前 (window_length_per_group + i -1) 个周期数据
  train_periods <- 1:(window_length_per_group + i - 1)
  train_indices[[i]] <- which(dat$period %in% train_periods)
  
  # 测试集:包含所有组的第 (window_length_per_group + i) 个周期数据
  test_period <- window_length_per_group + i
  test_indices[[i]] <- which(dat$period == test_period)
}

步骤4:配置trainControl并训练模型

我们用method = "cv"模式,传入手动生成的索引,这样就能完全控制滚动逻辑:

timecontrol <- trainControl(
  method = "cv",
  index = train_indices,
  indexOut = test_indices,
  selectionFunction = "best",
  savePredictions = 'final'
)

# 批量训练三个模型
model_list <- list()
model_list[["xgbTree"]] <- train(
  y ~ . - group - period, # 排除原始group和period,用虚拟变量替代
  data = dat,
  method = "xgbTree",
  trControl = timecontrol
)

model_list[["earth"]] <- train(
  y ~ . - group - period,
  data = dat,
  method = "earth",
  trControl = timecontrol
)

model_list[["cubist"]] <- train(
  y ~ . - group - period,
  data = dat,
  method = "cubist",
  trControl = timecontrol
)

为什么这个方案更优?

  1. 通用性极强:不管组数量是6还是其他数值,只要修改window_length_per_group,其他参数会自动适配,完全不需要手动调整initialWindow或horizon。
  2. 严格的时序逻辑:手动生成的索引确保每次测试集都是每个组的下一个周期观测,完美符合一步超前预测的需求。
  3. 效率更高:不需要循环每个组训练,直接在合并后的数据集上一次性训练,减少代码冗余和计算时间。

注意事项

  • 必须保证数据按group和period排序,否则索引会失效。
  • 训练公式中要排除原始的group和period变量,避免冗余。
  • 训练cubist模型前需要先安装Cubist包:install.packages("Cubist")

内容的提问来源于stack exchange,提问作者Felipe Alvarenga

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:12:59