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

在R中向ARIMA/LM输入分组数据并还原原列的最优方法

针对多类别时间序列预测后还原的优化方案

首先,先帮你修正下原代码里的几个小问题:一是你创建df时用了<-给列赋值,这会导致列名变成类似id <- rep(...)的无效名称,应该用=;二是代码里用到的taxonomy列没有在数据框里定义,我假设你是想基于cat1和cat2组合成分类标识,先补上这部分。

回到你的核心问题:多类别数据聚合后预测,再还原回原数据集结构。这里有几个更优的思路和实现方法:

1. 分组时保留完整的类别元数据

在聚合分组的时候,不要只保留时间序列数值,同时记录每个分组对应的所有类别属性(event, cat1, cat2, venue等),这样预测完成后,可以直接把预测结果和这些属性关联,再扩展到对应的时间维度,轻松还原到原始数据结构。

优化后的代码示例:

library(plyr)
library(xts)
library(forecast)

# 修正数据框创建,添加taxonomy列,修正列赋值方式
df <- data.frame( 
  id = rep(seq(2694065, length=62, by = 1),10), 
  listing_date = rep(seq(as.Date("2017-06-01"), length=62, by = "day"),10), 
  event = sample(c("Baseball","Minors","Music",NA), 620, replace = TRUE), 
  event_date = rep(seq(as.Date("2017-09-01"), length=62, by = "day"),10), 
  ticket_ct = sample(10:11000, size=620, replace = TRUE), 
  price = sample(10:600, size=620, replace = TRUE), 
  cat1 = sample(c("Sox", "Twins", "Phil", "Band1", "Band2"),620,replace = TRUE), 
  cat2 = sample(c("Mets", "Hops", NA, "Phil"),620, replace = TRUE), 
  venue = sample(c("Stadium","BallPark", "Concert Hall"),620, replace = TRUE) 
)
# 定义taxonomy(这里用cat1+cat2组合,你可以根据实际需求调整)
df$taxonomy <- paste(df$cat1, df$cat2, sep = "_")

# 分组时保留所有列,而不是只取时间序列数据
list1 <- dlply(df, .(id, taxonomy), function(group) {
  # 保存分组的元数据和时间序列数据
  list(
    meta = group[1, c("event", "cat1", "cat2", "venue")], # 每个分组的类别属性(同组内一致)
    ts_data = xts(x=group[,c("ticket_ct","price")], order.by=group[,"listing_date"])
  )
})

# 调整ARIMA预测函数,同时返回分组元数据和预测结果
arimafunc <- function(group_obj) {
  fity <- auto.arima(group_obj$ts_data$ticket_ct)
  forecast_result <- forecast(fity, h=31)
  # 将预测结果转换为数据框,方便后续合并
  forecast_df <- as.data.frame(forecast_result)
  forecast_df$listing_date <- seq(max(index(group_obj$ts_data)) + 1, by = "day", length.out = 31)
  # 提取当前分组的id和taxonomy
  group_key <- strsplit(names(group_obj), "\\.")[[1]]
  forecast_df$id <- as.numeric(group_key[1])
  forecast_df$taxonomy <- group_key[2]
  # 合并元数据
  forecast_df <- cbind(forecast_df, group_obj$meta)
  # 重命名预测列为ticket_ct,和原始数据统一
  forecast_df$ticket_ct <- forecast_df$`Point Forecast`
  return(forecast_df[, c("id", "listing_date", "taxonomy", "ticket_ct", "event", "cat1", "cat2", "venue")])
}

# 运行预测
forecasts <- lapply(list1, arimafunc)

# 将所有预测结果合并成一个数据框,再和原始数据合并,得到完整的数据集
full_forecast_df <- do.call(rbind, forecasts)
original_with_forecast <- rbind(
  df[, c("id", "listing_date", "taxonomy", "ticket_ct", "event", "cat1", "cat2", "venue", "price")],
  full_forecast_df
)

2. 采用分层时间序列(Hierarchical Time Series)方法

如果你的类别之间存在层级关系(比如cat1是一级分类,cat2是二级分类),可以使用分层时间序列的专用工具,比如hts包或者fable包,这类工具可以帮你在不同层级上做预测,同时保证预测结果的一致性,并且可以直接还原到最细粒度的分组。

比如用fable的示例(更现代的时间序列工具):

library(fable)
library(tsibble)
library(dplyr)

# 将数据转换为tsibble格式(时间序列专用数据框)
df_ts <- df %>%
  as_tsibble(key = c(id, taxonomy), index = listing_date)

# 分层时间序列预测
hier_forecast <- df_ts %>%
  model(arima = ARIMA(ticket_ct)) %>%
  forecast(h = 31)

# 直接得到细粒度的预测结果,可以和原始数据合并
full_data <- bind_rows(
  df_ts %>% select(id, listing_date, taxonomy, ticket_ct, price, event, cat1, cat2, venue),
  hier_forecast %>% select(id, listing_date, taxonomy, ticket_ct = .mean, event, cat1, cat2, venue)
)

这种方法不需要手动处理分组和还原,工具会自动帮你处理层级关系,预测结果直接对应到每个原始分组。

3. 针对缺失值的预处理建议

在聚合前,建议先对每个分组的缺失值做简单处理(比如用同组的均值/中位数填充,或者用插值法),这样ARIMA模型的输入数据质量更高,预测结果更可靠。比如用dplyr的分组填充:

df_clean <- df %>%
  group_by(id, taxonomy) %>%
  mutate(ticket_ct = ifelse(is.na(ticket_ct), mean(ticket_ct, na.rm = TRUE), ticket_ct)) %>%
  ungroup()

后续线性模型预测price的注意事项

当你还原得到包含预测ticket_ct的完整数据集后,可以把ticket_ct(包括原始值和预测值)作为特征,结合event, cat1, cat2, venue等类别特征,用线性模型(比如lm或者正则化模型glmnet)来预测price。注意要区分训练数据(原始有price的部分)和预测数据(只有ticket_ct和类别特征的部分)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:09:06