2.2 季节性 Seasonality:固定周期


2.2 季节性 Seasonality:固定周期的"指纹"模式

本节摘要:季节性是固定周期(7 天、12 个月、24 小时)重复出现的有规律模式。本节给出季节性的工程定义、季节性子序列图的画法,并通过 ACF 在 lag=7、14、21 等位置出现周期峰来识别周季节性。

读完你能做什么

阅读完本节,你应当能够:

  1. 写出季节性的工程定义,强调"周期固定"这一关键词。
  2. 用季节性子序列图(seasonal subseries plot)把周期模式直观化。
  3. 通过 ACF 在固定 lag 处的周期峰识别周/月/年季节性。

本节跳出 2.1 的"长方向"视角,把焦点切到"短周期"。先给季节性下定义,再用代码画子序列图、读 ACF 周期峰,最后区分硬季节性 / 软季节性 / 多重季节性。

一、季节性的工程定义

季节性是这样一类信号:它在已知长度的固定周期内重复出现,且周期长度不会随时间漂移。常见周期:

周期 典型场景
24 小时 城市用电、网页流量、外卖订单
7 天 线下零售、APP DAU、餐厅客流
12 个月 服装销售、旅游人数、农产品产量
1 年 / 4 季 空调销量、滑雪场收入、流感就诊量

注意:上面这些周期的"固定"是日历意义上的固定——每天 24 小时、每周 7 天、每年 12 个月。业务上"双 11 那种每年只有一天的活动"严格说不是季节性(周期太长、信号太窄),更接近"脉冲事件"或"日历效应",要单独处理。

二、季节性子序列图:把周期模式画出来

可视化季节性最经典的方法是季节性子序列图——把同一周期位置的所有观测画在一张小盒图或折线图上:

import pandas as pd import numpy as np import matplotlib.pyplot as plt # 构造 2 年日数据:明显周季节性 + 趋势 + 噪声 rng = np.random.default_rng(3) n = 365 * 2 trend = np.linspace(100, 200, n) weekly = np.tile([0, -10, -10, -5, 5, 25, 30], n // 7 + 1)[:n] y = trend + weekly + rng.normal(0, 3, n) s = pd.Series(y, index=pd.date_range("2023-01-02", periods=n)) # 周一开头 # 关键:把"星期几"作为分类轴 s_df = s.to_frame("y") s_df["weekday"] = s_df.index.dayofweek # 0=周一, 6=周日 # 季节性子序列图:每周对应的观测画在第 1 张图,每个星期几画在第 2 张图 fig, axes = plt.subplots(2, 1, figsize=(10, 6)) axes[0].plot(s.index, s.values, lw=0.6) axes[0].set_title("原始时序(含周季节性)") axes[1].boxplot([s_df[s_df.weekday == d]["y"].values for d in range(7)], labels=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]) axes[1].set_title("按星期几的盒图(季节性模式可见)") plt.tight_layout()

输出上,原始时序图看起来是缠绕的曲线,但盒图会清晰地展示"周末高、工作日低"或"周一低谷、周五高峰"等模式。季节性子序列图比原始时序图更容易一眼看出"是否存在季节性"以及"季节性长什么样"

三、用 ACF 在固定 lag 处找周期峰

第二种识别季节性的方法是看自相关函数(ACF)。如果序列有周季节性,ACF 在 lag=7、14、21、28…这些位置会出现明显的局部峰。

from statsmodels.tsa.stattools import acf acf_vals = acf(s, nlags=35, fft=True) # 把 lag=7、14、21、28 处的值打印出来 for lag in [1, 7, 14, 21, 28]: print(f"ACF(lag={lag}) = {acf_vals[lag]:.3f}") # 预期:ACF(7) 较高,ACF(14) 也较高,但比 ACF(7) 略低;非 7 倍数的 lag 接近 0

如果你的数据有月季节性,ACF 在 lag=12(月度)或 lag=365(年度)会出现峰;如果有日季节性,lag=24(小时数据)或 lag=1440(分钟数据)会出现峰。**关键不是峰绝对值多大,而是峰是否出现在"7 / 12 / 24 / 365"等业务周期位置**。

💡 关键直觉:ACF 峰的位置比峰值大小更值得看。一个 lag=7 处的小峰(0.2)也比 lag=3 处的大峰(0.6)更能说明"周季节性"。

四、季节性的"硬"识别 vs "软"识别

工程上分两类识别:

  • 硬季节性:日历事件完全决定——比如"每周一到周五 9 点早高峰的地铁客流量"。这种序列的 ACF 在固定 lag 处的峰非常显著。
  • 软季节性:受外部因素调节——比如"周末效应在夏季比冬季更明显"。这种序列的 ACF 峰存在但会被干扰,更适合用 STL 分解、Prophet 的 seasonal Fourier 项建模。

五、多重季节性

复杂业务里常常同时有多个周期。比如电商平台同时有:

  • 24 小时周期(白天 vs 夜晚)
  • 7 天周期(工作日 vs 周末)
  • 12 个月周期(双 11、618、年货节)

这种"多重季节性"对 SARIMA 这种"只能建模一个季节周期"的方法是个挑战——MSTL(Multiple STL)、Prophet 的多 Fourier 项、NeuralForecast 的 NHITS 等新一代方法就是为了处理多重季节性而设计的。第七章会再展开。

本节要点回顾

  • 季节性的关键词:固定周期。日历意义而不是物理意义。
  • 可视化方法:季节性子序列图(按周期位置分组画盒图)比原始折线图更直观。
  • ACF 识别:看 lag=7/12/24/365 处的局部峰。峰位置比峰值大小更重要。
  • 硬季节性 vs 软季节性:硬季节性是日历决定;软季节性受外部因素调节。
  • 多重季节性:MSTL、Prophet 多 Fourier 项等新一代方法是答案。
  • 下一节线索:2.3 看另一种重复模式——周期性。它和季节性像但有一个关键区别:周期长度不固定。

图:固定周期 vs 非固定周期的 ACF 指纹

图:固定周期 vs 非固定周期的 ACF 指纹


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U