时间序列预测fc=1时触发下标越界警告,如何消除该警告?
解决TSLM预测步长fc=1时的「subscript out of bounds」警告
问题原因
当设置fc=1时,forecast(h=fc)仅生成1个时间点的预测值,但传入accuracy()的测试集包含远多于1行的数据。fabletools::accuracy()在尝试对齐预测值与测试集的时间序列时,因长度不匹配触发了下标越界警告;而fc=3时,测试集前3行的时间范围刚好能与预测值完全匹配,因此无警告。
解决方案
方案1:规范划分训练/测试集+匹配时间范围
用时间索引而非行号分割数据集,确保训练集与测试集的时间连续,同时在计算精度时仅取测试集中对应预测步长的时间范围:
time_series_data <- read.csv('https://raw.githubusercontent.com/InfiniteCuriosity/forecasting_jobs/main/Total_Nonfarm.csv') train_amount <- 0.60 fc <- 1 library(tidyverse) library(fpp3) # 数据预处理 time_series_data <- time_series_data %>% mutate(Date = yearmonth(Label), Value = Value, Change = difference(Value)) %>% select(Date, Value, Change) %>% as_tsibble(index = Date) %>% slice(-1) # 用时间索引划分训练/测试集 train_row <- round(train_amount * nrow(time_series_data)) train_end_date <- time_series_data %>% slice(train_row) %>% pull(Date) time_series_train <- time_series_data %>% filter(Date <= train_end_date) time_series_test <- time_series_data %>% filter(Date > train_end_date) # 取测试集中与预测步长对应的前fc行 test_subset <- time_series_test %>% slice(1:fc) # 建模、预测、计算精度 Linear1_error_list <- time_series_train %>% model(TSLM(Value ~ season() + trend())) %>% forecast(h = fc) %>% accuracy(test_subset)
方案2:使用time_split自动分割数据集
fabletools提供的time_split()函数可更规范地按时间分割序列,避免手动处理行号的问题:
time_series_data <- read.csv('https://raw.githubusercontent.com/InfiniteCuriosity/forecasting_jobs/main/Total_Nonfarm.csv') train_amount <- 0.60 fc <- 1 library(tidyverse) library(fpp3) # 数据预处理 time_series_data <- time_series_data %>% mutate(Date = yearmonth(Label), Value = Value, Change = difference(Value)) %>% select(Date, Value, Change) %>% as_tsibble(index = Date) %>% slice(-1) # 自动分割训练/测试集 data_split <- time_series_data %>% time_split(prop = train_amount) time_series_train <- training(data_split) time_series_test <- testing(data_split) %>% slice(1:fc) # 建模、预测、计算精度 Linear1_error_list <- time_series_train %>% model(TSLM(Value ~ season() + trend())) %>% forecast(h = fc) %>% accuracy(time_series_test)
关键说明
两种方案的核心都是确保预测结果的时间点与传入accuracy()的测试集时间点完全匹配,避免因长度或时间范围不匹配导致的内部下标错误。
内容的提问来源于stack exchange,提问作者Russ Conte
相关产品推荐
相关产品推荐

