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

在R中训练LSTM模型时维度不匹配问题求助

R中LSTM预测每小时呼叫量的维度适配问题解决

问题背景

需在R中训练LSTM模型,预测未来两个月每小时呼叫量(Calls Count),指定call_day_of_week_name、call_month、Calls Count、call_year参与预测。初始尝试时因过滤未来日期的历史数据导致返回空数据集,触发报错:

Error in py_call_impl(callable, call_args$unnamed, call_args$named) :
ValueError: cannot reshape array of size 0 into shape (1,1,1)

注释过滤代码后改用全量历史数据,又出现维度不匹配报错:

Error in py_call_impl(callable, call_args$unnamed, call_args$named) :
ValueError: cannot reshape array of size 113472 into shape (1,1,1)

报错核心原因

  1. 第一个错误:未来日期无对应历史数据,过滤后current_data为空,导致x_train/y_train是空数组,无法完成reshape操作。
  2. 第二个错误:
    • 误用全量历史数据作为单天训练数据,x_train长度为113472,reshape为(113472,1,1)本身合法,但后续预测结果长度与predicted_data单天24个时间槽的维度不匹配。
    • 循环内重复训练模型完全不合理,既浪费计算资源,也不符合时间序列预测的逻辑。

分步解决方案

1. 重构数据准备逻辑

放弃“每天循环训练模型”的错误思路,用所有历史数据训练一次通用模型,再用模型对未来每个日期的小时级特征做预测。

2. 处理分类特征编码

call_day_of_week_name是分类变量,需转换为数值特征:

  • 标签编码:将星期几映射为0-6的数值
  • 独热编码:生成7个二进制特征(对应一周7天)

3. 正确构造LSTM输入维度

LSTM要求输入为三维数组:[样本数, 时间步长, 特征数]。这里的特征应包含:

  • 编码后的call_day_of_week_name
  • call_month
  • call_year
  • call_hour

4. 生成未来日期的小时级特征

为未来两个月的每个日期生成24小时对应的特征矩阵,作为模型的预测输入。

修正后的代码示例

# 1. 预处理历史数据:编码分类特征
library(keras)
library(dplyr)

# 标签编码星期几
filtered_data <- filtered_data %>%
  mutate(
    day_of_week_num = as.integer(factor(call_day_of_week_name, 
                                        levels = c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"))) - 1
  )

# 构造特征矩阵与目标变量
features <- filtered_data %>%
  select(day_of_week_num, call_month, call_year, call_hour) %>%
  as.matrix()
target <- filtered_data$`Calls Count`

# 归一化特征(LSTM对数据尺度敏感)
scaler_features <- scale(features)
scaler_target <- scale(matrix(target))

# 2. 调整输入维度为LSTM要求的三维:[样本数, 时间步长, 特征数]
# 这里时间步长设为1(单步预测),特征数为4
x_train <- array_reshape(scaler_features, dim = c(nrow(scaler_features), 1, ncol(scaler_features)))
y_train <- scaler_target

# 3. 构建并训练LSTM模型(仅训练一次)
model <- keras_model_sequential() %>%
  layer_lstm(units = 64, input_shape = c(1, ncol(scaler_features))) %>%
  layer_dense(units = 1)

model %>% compile(
  loss = 'mean_squared_error',
  optimizer = optimizer_adam(learning_rate = 0.001)
)

# 训练模型
history <- model %>% fit(
  x_train, y_train,
  epochs = 50,
  batch_size = 64,
  validation_split = 0.2
)

# 4. 生成未来日期的小时级特征
future_hours <- expand.grid(
  date = dates,
  call_hour = 0:23
) %>%
  mutate(
    call_day_of_week_name = weekdays(date),
    day_of_week_num = as.integer(factor(call_day_of_week_name, 
                                        levels = c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"))) - 1,
    call_month = as.integer(format(date, "%m")),
    call_year = as.integer(format(date, "%Y"))
  ) %>%
  select(day_of_week_num, call_month, call_year, call_hour) %>%
  as.matrix()

# 归一化未来特征(使用历史数据的scaler)
future_features_scaled <- scale(future_hours, center = attr(scaler_features, "scaled:center"), scale = attr(scaler_features, "scaled:scale"))

# 调整未来特征维度
x_pred <- array_reshape(future_features_scaled, dim = c(nrow(future_features_scaled), 1, ncol(future_features_scaled)))

# 5. 预测并反归一化结果
predictions_scaled <- model %>% predict(x_pred)
predictions <- predictions_scaled * attr(scaler_target, "scaled:scale") + attr(scaler_target, "scaled:center")

# 6. 将预测结果填充到predicted_data
# 按日期分组,将24小时预测值赋值到对应行
predicted_data[, 3:ncol(predicted_data)] <- matrix(predictions, nrow = length(dates), byrow = TRUE)

# 处理银行假日
predicted_data[predicted_data$date == as.Date("2023-08-28"), 3:ncol(predicted_data)] <- NA

关键说明

  • 不再在循环内重复训练模型,大幅提升效率;
  • 完整使用指定的4个变量作为特征,符合预测需求;
  • 解决了维度不匹配问题,预测结果与predicted_data的时间槽维度完全对齐;
  • 添加数据归一化步骤,提升LSTM模型的训练稳定性与预测精度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 07:23:09