纯AR(2)过程中STL检测虚假季节性的参数调整方法
AR(2)序列STL分解出现虚假季节性的参数调整问题
我在R环境中模拟了一个纯AR(2)过程,调用feasts包的STL(局部季节性分解)函数时,检测到存在强季节性,但该数据生成过程实际并无季节性特征。请问如何调整STL的参数,以避免检测出虚假季节性?
模拟代码
library(fable) library(fabletools) library(tsibble) library(tsibbledata) library(lubridate) library(dplyr) library(tidyr) library(feasts) # simulate an ar2 process set.seed(0) sd_epilson = 0.5 data = rnorm(500) for (i in 3:500){ data[i] = 10 + 0.5*data[i-1] + 0.3*data[i-2] + rnorm(1, 0, sd_epilson) } data = tail(data, 400) ts_data = ts(data, start=c(1970,1), frequency=12) %>% as_tsibble() train = ts_data[1:360,] test = ts_data[361:384,] # model with STL() train %>% model( stl = STL(value) ) %>% components() %>% autoplot()
会话信息
R version 4.2.3 (2023-03-15 ucrt) Platform: x86_64-w64-mingw32/x64 (64-bit) Running under: Windows 10 x64 (build 22635) Matrix products: default locale: [1] LC_COLLATE=English_United States.utf8 LC_CTYPE=English_United States.utf8 [3] LC_MONETARY=English_United States.utf8 LC_NUMERIC=C [5] LC_TIME=English_United States.utf8 attached base packages: [1] stats graphics grDevices utils datasets methods base other attached packages: [1] purrr_1.0.2 furrr_0.3.1 future_1.33.1 feasts_0.3.1 tidyr_1.3.0 dplyr_1.1.4 [7] lubridate_1.9.3 tsibbledata_0.4.1 tsibble_1.1.3 fable_0.3.3 fabletools_0.3.4 loaded via a namespace (and not attached): [1] Rcpp_1.0.11 progressr_0.14.0 pillar_1.9.0 compiler_4.2.3 tools_4.2.3 [6] digest_0.6.33 lifecycle_1.0.4 tibble_3.2.1 gtable_0.3.4 anytime_0.3.9 [11] timechange_0.2.0 pkgconfig_2.0.3 rlang_1.1.2 cli_3.6.2 rstudioapi_0.15.0 [16] parallel_4.2.3 xfun_0.41 withr_2.5.2 knitr_1.45 globals_0.16.2 [21] generics_0.1.3 vctrs_0.6.5 rappdirs_0.3.3 grid_4.2.3 tidyselect_1.2.0 [26] glue_1.6.2 listenv_0.9.0 R6_2.5.1 future.apply_1.11.1 parallelly_1.36.0 [31] fansi_1.0.6 distributional_0.3.2 ggplot2_3.4.4 farver_2.1.1 magrittr_2.0.3 [36] codetools_0.2-19 scales_1.3.0 ellipsis_0.3.2 colorspace_2.1-0 labeling_0.4.3 [41] utf8_1.2.4 munsell_0.5.0
更新(2024年1月2日)
我此前误读了STL的可视化结果,季节性分量旁的灰色竖条表明其变异程度远小于其他分量;通过feat_stl验证,该序列的季节性强度小于0.20。
验证代码:
train %>% features(value, feat_stl)
问题解答
核心原因分析
你最初误以为的“强虚假季节性”其实是可视化解读偏差:当序列frequency设为12时,STL会默认按12期周期拟合季节性分量——哪怕序列无季节性,算法也会提取该周期的微弱波动,但从feat_stl的结果(强度<0.20)来看,这属于弱/无季节性范畴(行业通用阈值:>0.6为强季节性,0.2~0.6为中等,<0.2为弱/无),STL并没有错误识别强季节性。
参数调整方案
如果要进一步抑制这种微弱的虚假季节性分量,可调整STL的以下参数:
增大季节性平滑窗口
seasonal参数控制季节性分量的平滑程度,值越大越不容易捕捉随机波动。默认值为7(必须是奇数),月度数据可尝试设置为13或更大奇数:train %>% model( stl = STL(value, seasonal = 13) ) %>% components() %>% autoplot()直接关闭季节性分量
若确定序列完全无季节性,可禁用季节性分量提取:train %>% model( stl = STL(value, seasonal = "none") ) %>% components() %>% autoplot()分解结果将只剩趋势和残差。
调整趋势平滑窗口
增大trend参数让趋势分量更平滑,减少趋势对季节性分量的干扰,间接降低虚假季节性强度,比如设置为21:train %>% model( stl = STL(value, trend = 21) ) %>% components() %>% autoplot()
额外建议
- 优先用
feat_stl的量化结果判断季节性强度,可视化中的季节性波动可能是坐标轴范围被其他分量拉大导致的视觉错觉; - 无季节性序列更适合用非季节性分解方法(如
decompose(type="additive")),STL本身为季节性序列设计,强行用于无季节性序列必然会生成微弱的季节性分量。
内容的提问来源于stack exchange,提问作者William Chiu
相关产品推荐
相关产品推荐

