如何通过月度虚拟变量去除周度时间序列的季节性
周度谷歌搜索量时间序列去季节化方案
针对你处理的52周频率谷歌搜索量对数收益率序列,以下是3种可直接落地的去季节化方法:
方法1:直接从STL分解结果提取季节调整序列
你已经完成STL分解的步骤,不需要额外建模即可得到去季节结果:STL分解会把原序列拆分为趋势项+季节项+残差项,原序列减去季节项就是消除季节性后的序列。
# 若假设季节性不随年份变化,保持s.window="periodic"即可;若允许季节性缓慢变化,可将s.window设为7/13等奇数 decomp <- stl(gold, s.window = "periodic") # 计算季节调整后序列 gold_sa <- gold - decomp$time.series[, "seasonal"] # 效果验证 plot(gold, col = "grey60", main = "去季节效果对比") lines(gold_sa, col = "red")
这个方法计算速度快,适合后续直接做时间序列建模的场景。
方法2:周度虚拟变量回归法(文献常用方法)
该方法通过回归剥离每个周次的固定季节效应,回归残差即为去季节后的序列,优势是可以直接输出每个周的季节效应系数,方便做结果汇报。
# 提取每个观测对应的年内周次(1-52) week_label <- cycle(gold) # 构造回归数据集,周次转为因子后自动生成虚拟变量,lm会自动规避虚拟变量陷阱 reg_data <- data.frame( svi_return = as.numeric(gold), week = as.factor(week_label) ) # 周度虚拟变量回归 season_fit <- lm(svi_return ~ week, data = reg_data) # 提取残差,还原为时间序列格式 gold_sa_reg <- ts(season_fit$residuals, frequency = 52, start = c(2018, 1), end = c(2021, 52)) # 若后续处理原始SVI值(非对数收益率),可在回归中加入趋势项避免误剥离趋势成分 # trend_term <- 1:length(gold) # season_fit <- lm(svi_return ~ week + trend_term, data = reg_data)
在固定季节性的假设下,该方法和STL取周期窗口的去季节结果几乎一致。
方法3:稳健STL季节调整
如果序列存在部分异常值,可以用带稳健估计的STL分解,降低异常值对季节分量估计的干扰:
library(forecast) # 稳健STL分解,robust参数开启会降低离群点权重 decomp_robust <- stl(gold, s.window = 13, t.window = 104, robust = TRUE) # 直接调用seasadj函数提取季节调整序列 gold_sa_robust <- seasadj(decomp_robust)
注意:周度数据偶尔会出现一年53周的情况,你当前使用的2018-2021年样本均为52周,不存在索引对齐问题;如果后续扩展样本遇到53周的年份,可将第53周的季节效应设为相邻第52周和第1周的均值,避免报错。
内容的提问来源于stack exchange,提问作者Keeran04
相关产品推荐
相关产品推荐

