使用mgcv双变量te平滑:对协变量求均值提取纯时间趋势
关于mgcv中
te(year, month)建模及提取纯时间趋势的解答 1. 用te(year, month)建模随时间变化的季节性是否可行合理?
完全可行且合理。te(year, month)构造的双变量张量积平滑,核心优势是捕捉年份与月份的交互效应——也就是允许季节性模式随年份发生变化(比如某些月份的效应逐年增强/减弱,或者季节性峰值的时间逐年偏移)。
相比分开拟合单变量平滑s(year) + s(month)的方式,后者假设季节性模式是固定不变的(每年的月份效应都一致),而te(year, month)更适合处理季节性随时间演变的场景(比如长期气候数据、零售行业的季节性消费趋势变化等)。只要你的数据中确实存在季节性模式随年份变化的迹象,这种建模方式就非常合适。
2. 如何从双变量张量积模型中提取对month求均值后的纯时间趋势?
可以通过predict.gam()函数结合构造新数据的方式实现,具体步骤如下:
- 构造包含所有目标年份,且每个年份对应完整12个月的新数据集;
- 用训练好的模型对这个新数据集预测拟合值;
- 按年份分组,对每个年份的12个预测值取均值,得到的就是对month平均后的纯时间趋势。
示例代码(基于你的现有代码扩展):
set.seed(123) n <- 100 data <- gamSim(n = n, dist = "normal", scale = 2) data$year <- rep(1:(n/12), each = ceiling(n/12))[1:n] data$month <- rep(1:12, length.out = n) # 拟合双变量张量积模型 model <- gam(y ~ te(year, month), data = data) # 步骤1:构造新数据,覆盖所有年份,每个年份包含1-12月 unique_years <- unique(data$year) new_data <- expand.grid(year = unique_years, month = 1:12) # 步骤2:预测拟合值 new_data$pred <- predict(model, newdata = new_data) # 步骤3:按年份分组求均值,得到纯时间趋势 # 用dplyr实现分组聚合 library(dplyr) year_trend <- new_data %>% group_by(year) %>% summarise(pure_trend = mean(pred)) # 查看结果 print(year_trend) # 可视化纯时间趋势 plot(year_trend$year, year_trend$pure_trend, type = "l", xlab = "Year", ylab = "Pure Time Trend", main = "Time Trend (Averaged over Month)")
补充说明:
如果你不想依赖dplyr,用base R的aggregate函数也能完成分组求均值:
year_trend_base <- aggregate(pred ~ year, data = new_data, FUN = mean)
内容的提问来源于stack exchange,提问作者Mike Dunbar
相关产品推荐
相关产品推荐

