如何使用AICc评估时间序列集成模型的效果?
用AICc评估fpp3中时间序列集成模型的方法
问题原因
通过mutate(combination = (Ets1 + Ets2)/2)创建的集成模型属于model_combination类,当前fabletools::glance()未为该类实现AICc计算方法,因此触发报错。
解决方案
方案一:手动计算集成模型的AICc
AICc的计算核心依赖对数似然值和参数数量,可基于单个模型的结果手动推导集成模型的AICc:
- 提取单个ETS模型的对数似然、残差自由度等核心信息
- 计算集成模型的整体对数似然(简单平均集成的似然为各模型似然加权后的对数)
- 确定集成模型的有效参数数(可采用单个模型参数数的平均值,或参考Burnham & Anderson的合成准则)
- 代入AICc公式完成计算
代码示例:
library(fpp3) library(dplyr) # 加载数据并拟合模型 Time_Series <- aus_airpassengers fit <- Time_Series %>% model( Ets1 = ETS(Passengers ~ season() + trend()), Ets2 = ETS(Passengers ~ trend()) ) %>% mutate(combination = (Ets1 + Ets2)/2) # 获取单个模型的统计信息 single_model_stats <- glance(fit) %>% filter(.model != "combination") # 提取关键参数 n <- nrow(Time_Series) loglik_ets1 <- single_model_stats$logLik[single_model_stats$.model == "Ets1"] loglik_ets2 <- single_model_stats$logLik[single_model_stats$.model == "Ets2"] # 计算单个模型的参数数:k = 样本量 - 残差自由度 k_ets1 <- n - single_model_stats$df.residual[single_model_stats$.model == "Ets1"] k_ets2 <- n - single_model_stats$df.residual[single_model_stats$.model == "Ets2"] # 计算集成模型的对数似然(权重均为0.5) ensemble_loglik <- log(0.5 * exp(loglik_ets1) + 0.5 * exp(loglik_ets2)) # 取参数数的平均值作为集成模型的有效参数数 ensemble_k <- (k_ets1 + k_ets2) / 2 # 计算AICc ensemble_aicc <- -2 * ensemble_loglik + 2 * ensemble_k * n / (n - ensemble_k - 1) # 整合所有模型的AICc结果 final_results <- bind_rows( single_model_stats %>% select(.model, AICc), tibble(.model = "combination", AICc = ensemble_aicc) ) %>% arrange(AICc) print(final_results)
方案二:用时间序列交叉验证间接评估
AICc本质是对预测误差的渐近估计,若更侧重预测性能,时间序列交叉验证可直接给出模型的预测精度(如RMSE、MAE),完全符合《Forecasting Principles and Practice》中以预测为目标的评估思路:
代码示例:
# 时间序列交叉验证(滚动预测) cv_accuracy <- Time_Series %>% stretch_tsibble(.init = 10, .step = 1) %>% model( Ets1 = ETS(Passengers ~ season() + trend()), Ets2 = ETS(Passengers ~ trend()), combination = (Ets1 + Ets2)/2 ) %>% forecast(h = 1) %>% accuracy(Time_Series) %>% select(.model, RMSE, MAE, MAPE) %>% arrange(RMSE) print(cv_accuracy)
内容的提问来源于stack exchange,提问作者Russ Conte
相关产品推荐
相关产品推荐

