如何用R循环实现迭代式单步小时电价滚动预测?
我来帮你实现这个滚动式的季节朴素(snaive)电价预测需求,下面是完整的可运行代码,附带详细解释,最后解答你关于循环是否最优的疑问:
完整实现代码
首先确保你加载了所需的包:
library(forecast) library(readxl)
然后是数据读取、初始化和滚动预测的核心代码:
# 1. 读取数据(替换为你的实际文件路径) dirDataPrices <- "./" # 这里替换成你的数据文件夹路径 df.elspot.prices.2014 <- as.data.frame(read_excel(paste0(dirDataPrices, "elspot-prices_2014_hourly_eur.xlsx"), skip = 2)) df.elspot.prices.2015 <- as.data.frame(read_excel(paste0(dirDataPrices, "elspot-prices_2015_hourly_eur.xlsx"), skip = 2)) # 2. 初始化训练集和测试集 train_data <- df.elspot.prices.2014$Price # 初始训练集为2014年全年数据 test_data <- df.elspot.prices.2015$Price # 测试集为2015年全年数据 total_days_2015 <- 365 # 2015年是平年,共365天 hour_per_day <- 24 # 3. 创建存储预测结果的容器 predictions <- numeric(length(test_data)) # 长度为8760,对应2015年所有小时 # 4. 滚动预测循环 for (day in 1:total_days_2015) { # 计算当前预测的小时索引范围 start_idx <- (day - 1) * hour_per_day + 1 end_idx <- day * hour_per_day # 将当前训练集转换为多季节时间序列对象 train_msts <- msts(train_data, seasonal.periods = c(24, 168), start = 2014) # 用snaive预测未来24小时 forecast_result <- snaive(train_msts, h = hour_per_day) # 将预测值存入结果向量 predictions[start_idx:end_idx] <- as.numeric(forecast_result$mean) # 将当天的实际电价追加到训练集,更新训练数据 train_data <- c(train_data, test_data[start_idx:end_idx]) # 可选:打印进度,方便跟踪 if (day %% 30 == 0) { cat("已完成", day, "天的预测\n") } } # 5. 整理预测结果并评估精度 # 创建包含实际值和预测值的数据框 results_df <- data.frame( Datetime = seq.POSIXt(as.POSIXct("2015-01-01 00:00"), as.POSIXct("2015-12-31 23:00"), by = "hour"), Actual = test_data, Predicted = predictions ) # 计算预测精度指标 accuracy_metrics <- accuracy(predictions, test_data) print("预测精度指标:") print(accuracy_metrics)
代码解释
- 数据读取:使用
read_excel读取两年的小时电价数据,注意skip=2要和你的文件格式匹配(跳过前两行表头)。 - 初始化:
train_data初始为2014年的电价序列,test_data是2015年的实际值,predictions向量用来存储所有预测结果。 - 循环逻辑:
- 每次循环处理一天的预测,计算当天对应的小时索引范围。
- 将当前训练集转换为
msts对象,因为电价数据有**日周期(24小时)和周周期(168小时)**两个季节性成分,snaive需要这个结构来识别季节模式。 - 调用
snaive预测未来24小时,将结果存入predictions的对应位置。 - 把当天的实际电价追加到训练集,实现"每日更新训练数据"的需求。
- 精度评估:使用
forecast包的accuracy函数计算MAE、RMSE、MAPE等常用指标,直观对比预测效果。
关于循环是否为最优方式的疑问
对于这种滚动式递推预测(recursive forecasting with updating training data),循环是非常合适的实现方式,原因如下:
- 直观易懂:循环的逻辑和你描述的预测流程完全对应,代码可读性强,容易调试和修改。
- 适配snaive模型:
snaive是基于历史季节模式的预测,每次更新训练集后都需要重新识别最新的季节趋势,循环能清晰完成这个过程。 - 性能可接受:2015年共365次循环,每次处理的是小时级时间序列,R的处理速度完全能胜任,不会有性能瓶颈。
如果你的数据量极大(比如几十年的分钟级数据),可以考虑用rollapply等向量化函数优化,但对于你的需求,循环是最优的选择——兼顾可读性和实现效率。
内容的提问来源于stack exchange,提问作者BalysLTU
相关产品推荐
相关产品推荐

