如果你也做过时间序列建模,大概率听过这句话:建模之前先做平稳性检验。我在刚入门的时候,对“平稳”的理解很肤浅,以为就是“数据不能有明显的涨跌趋势,画出来得贴着一条水平线”。后来用ARIMA拟合一个业务指标,训练集拟合优度很高,回测却一塌糊涂,才发现自己对“严平稳”和“宽平稳”这两个概念根本没过关——大多数时候,它们被混为一谈了。
这篇文章我想把严平稳和宽平稳掰开揉碎讲清楚:它们各自到底在说什么,为什么教科书要分两种,实践中到底该用哪个,以及我在真实项目里反复踩过的那些“平稳性陷阱”。如果你是做数据分析、量化策略、信号处理、工业过程监测的,这篇内容应该能帮你少走不少弯路。
1. 平稳性为什么是时间序列建模的第一道门槛
1.1 “规律不随时间漂移”是预测的前提
先说一个基本问题:我们凭什么预测未来?本质上,我们是在假设“过去观察到的规律,在未来依然成立”。如果数据的统计性质——均值、方差、相关性——随着时间不停改变,那你拟合出来的模型,只会是对过去一段历史的高度定制化描述,换个时间段就彻底失效。
平稳性就是把“规律不随时间漂移”这件事变成数学语言。一个随机过程 {X_t, t \in T} 如果满足平稳性,那么它的概率分布、数字特征就不受绝对时间位置的限制。只有在这个前提下,你才能从一条历史样本路径里估计出总体性质,并把模型外推到未来。
这也解释了为什么几乎所有经典时间序列模型(AR、MA、ARIMA、VAR)都先要求平稳或通过变换后平稳。模型参数估计的统计推断、置信区间、显著性检验,背后都依赖“样本矩估计总体矩”这条路,而平滑性的保证,正是这一做法正当性的基础。
1.2 非平稳数据会让模型做出哪些怪事
非平稳数据在模型里会产生很多看似“合理”的假象。最典型的就是把带漂移的随机游走误当成均值回归序列,回归结果出现高R方但实际毫无意义,经济学里叫伪回归。两个完全不相关的非平稳序列,回归系数很显著、R方很高,这种情况放在业务场景里极容易误导决策。
另一种假象出现在ARIMA训练集上。非平稳序列的均值、方差在变化,但ARIMA参数一旦定下来,就是用固定的系数去预测动态变化的系统。你拟合得越好,往往代表你把过去的随机噪声也刻进了模型,回测自然崩盘。所以平稳性检验不是走流程,是在拒绝“把随机性当规律”的建模错误。
2. 严平稳:最教科书、也最“难用”的定义
2.1 所有有限维分布都不随平移变化
严平稳(严格平稳)的定义听起来很完美:对任意正整数 n、任意时刻 t_1, t_2, \dots, t_n、任意滞后 h,随机向量 \left(X_{t_1}, X_{t_2}, \dots, X_{t_n}\right) 的联合分布与 \left(X_{t_1+h}, X_{t_2+h}, \dots, X_{t_n+h}\right) 的联合分布完全相同。
换成大白话就是:无论你从哪个时间点切一个窗口出来,窗口里整段序列的“行为模式”的分布都是一样的。注意,这里说的不是“均值一样”“方差一样”,而是完整的概率分布——一阶分布、二阶联合分布、三阶联合分布……全部要一样。这是一个极其苛刻的要求。
从定义可以推出严平稳过程的一阶矩和二阶矩(如果存在)与时间无关,也就是说严平稳听起来很“全面”,但现实里你几乎无法真正验证它,因为它要求你在每个时间窗口都重复采样整个分布。
2.2 为什么现实数据几乎无法直接验证严平稳
这是个很实际的问题:我们手里通常只有一条样本路径——某个业务指标从2020年1月到2024年12月的日度记录。你想检验“所有有限维分布是否平移不变”,但你并没有在同一时间点上观察到几千次不同的现实,理论上你需要做大量平行实验。
所以真实操作中,我们是在“赌”一个叫各态历经性(ergodicity)的性质:假设时间平均可以替代集合平均。用一条足够长的时间序列的统计量,去近似那个理论上只有无穷多条样本路径才能算出的总体分布。在这个假设下,我们才敢继续做统计分析。
这也是严平稳“理论上完美、实操上笨重”的原因。它不是不重要,而是很难被直接检验。工程上大家心照不宣的做法是:默认数据满足各态历经性,然后只验证一阶和二阶性质。于是宽平稳登场了。
2.3 白噪声:严平稳最容易理解的例子
如果让我举一个严平稳的落地例子,我第一个选白噪声。一组独立同分布的随机变量序列,比如 \varepsilon_t \sim N(0, \sigma^2),不管你把窗口切在哪个时间段,里面的联合分布都完全一样,因为它们本来就是独立的、同分布的。这直接满足严平稳条件。
白噪声在时间序列分析里是“宇宙基石”一样的存在。我们做残差分析时,总希望模型剩下的部分像白噪声——这说明信息已经提取干净了。如果残差里还能看出自相关、异方差性,那就说明模型没有充分刻画数据结构。理解白噪声能帮你直观感受“严平稳”到底在要求什么:整个序列的高阶相关性结构也得稳定,不只是均值和方差。
3. 宽平稳:统计软件和业务分析里真正的默认条款
3.1 只需要均值、方差、自协方差稳定
宽平稳(弱平稳,weak stationarity)的定义明显“怂”很多,只用前两阶矩说话:
- 均值恒定:E[X_t] = \mu 与 t 无关。
- 方差有限:E[X_t^2] < \infty,保证二阶矩存在。
- 自协方差只依赖滞后:Cov(X_t, X_{t+h}) = \gamma(h),与 t 无关。
最后一条是最核心的。它意味着:两个观测值相隔一定的时间间隔 h,它们的相关性只跟“间隔了多远”有关,跟“现在到底是哪一天”无关。你可以理解成:序列的波动幅度不一定只在一个范围内,但它内部的相关结构必须有重复模式。
大量经典模型,AR(p)、MA(q)、ARMA(p,q),都建立在宽平稳之上。原因很简单:模型预测需要估计的,正是均值、方差和自协方差函数。只要这些量不随时间漂移,模型就算放到未来也不会出现系统性偏差。
3.2 样本里怎么“看”宽平稳:滚动统计量与ACF
工程上判断一个序列是否具备宽平稳特征,最快的方法是看图、看统计量、看自相关图。
先把序列画出来,观察有没有整体向下的趋势,方差是否随时间扩张或收缩。然后计算滚动均值、滚动标准差,窗口长度根据数据周期来定。如果滚动均值在水平线附近波动,滚动标准差没有明显放大或收敛,那至少说明一阶矩和二阶矩“看起来”稳定。
再看ACF(自相关函数)图。宽平稳要求自相关系数只依赖于滞后阶数,所以ACF图会呈现“衰减”的模式。如果ACF衰减到噪声带里之后,又在某个固定间隔上反复出现峰值,比如12个月、24小时、7天,那周期性成分还在,宽平稳条件不成立。ACF图还有一个作用:它直接告诉你该选多少阶的MA项,这对后续建模非常有用。
3.3 为什么平稳性检验工具检验的是宽平稳
你打开Python的statsmodels库,跑adfuller或kpss,你会发现这些检验没有一个在检查“所有有限维分布”。它们检验的核心就是单位根是否存在、均值趋势是否稳定、方差结构是否恒定——这正是宽平稳的范畴。
不是工具做得不够高级,而是宽平稳已经覆盖了实际建模的绝大多数需求。做预测时,你最怕的是均值漂移、趋势突变、相关性结构变化;这些恰好都能体现在一阶矩和二阶矩上。至于三阶、四阶以上的分布形态,在大多数业务指标里对预测结果的影响有限,而且很难在小样本中稳定估计。所以几十年下来,大部分时间序列教科书讲的“平稳”,默认是宽平稳。
4. 两类平稳的关系:包含方向不同,还有两个常被忽略的反例
4.1 严平稳 + 二阶矩存在 = 宽平稳
如果严平稳成立,并且过程的二阶矩存在(也就是 E[X_t^2] < \infty),那么宽平稳一定成立。因为所有有限维分布平移不变,自然包含了一维分布、二维分布平移不变,于是均值、方差不随时间变,自协方差也只依赖于滞后阶数。
这里“二阶矩存在”这个前提很关键。很多教材在讲两者关系时,直接说“严平稳推出宽平稳”,省略了二阶矩这个条件。数学上,如果二阶矩不存在,严平稳推不出宽平稳,这个细节我们在4.3展开。实践中,绝大多数业务数据、传感器数据、金融收益率的二阶矩是有限的,所以“严平稳大概率宽平稳”这话大体没错,但口头上不能把前提丢掉。
4.2 反例一:ARCH/GARCH 过程是宽平稳但不严平稳
先说一个金融时间序列里极其重要的例子。GARCH(1,1)模型常被用来刻画收益率的波动率聚集现象:
X_t = \sigma_t \varepsilon_t,\quad \sigma_t^2 = \omega + \alpha X_{t-1}^2 + \beta \sigma_{t-1}^2
在系数满足一定约束时,比如 \alpha + \beta < 1,序列 X_t 无条件均值为0,无条件方差为常数,自协方差为0,也就是宽平稳。但如果你看条件分布,X_t 的条件方差\sigma_t^2 是随时间变化的,一波大波动后面通常跟着另一波大波动,这说明序列的联合分布并不是平移不变的——它不满足严平稳。
这个例子在量化交易里非常常用。你不会因为收益率序列通过了平稳性检验就认为市场行为恒定不变,因为波动率结构本身会变。
4.3 反例二:严平稳但非宽平稳的过程
反过来,考虑一个独立同分布的柯西分布序列。因为每一时刻都服从同一个柯西分布,序列显然严平稳。但柯西分布的期望和方差都不存在,二阶矩无限大,直接违反宽平稳中 E[X_t^2] < \infty 的条件,所以它不是宽平稳。
这类反例在真实业务里很少遇到,因为像柯西分布那种重尾分布,数据里若有极端值,那基本是灾难级的数据质量问题了。
从测度论角度看,严平稳注重“分布族不变”,宽平稳注重“前两阶矩不变”。两者各自有各自的边界,谁也不能完全替代谁。
4.4 高斯假设下两者等价
还有一个非常实用的结论:如果宽平稳过程是高斯过程,那它同时也满足严平稳。原因在于正态分布完全由均值和协方差决定,一阶矩和二阶矩确定了,整个有限维联合分布就确定了。高斯过程的任意有限维分布都是多元正态分布,只要均值向量和协方差矩阵不变,联合分布就不变。
所以很多线性时间序列模型的创新项假设要么白噪声、要么正态分布,在手头没有明确反证的情况下,宽平稳≈严平稳是被默认接受的。这给了工程实践一个相对宽松的理论底气:检验通过宽平稳,就可以当它平稳来建模。
5. ADF与KPSS搭配使用:判断流程和踩过的坑
5.1 两种检验的原假设正好相反,组合起来看
我现在的习惯是ADF和KPSS一起跑,两个结果交叉验证。ADF检验的原假设是“序列有单位根,非平稳”;KPSS检验的原假设是“序列是平稳的”。两者组合会出现四种状态:
| ADF结果 | KPSS结果 | 大概率结论 |
|---|---|---|
| 拒绝非平稳 | 不能拒绝平稳 | 序列平稳,可以直接建模 |
| 不能拒绝非平稳 | 拒绝平稳 | 序列非平稳,需要差分或去趋势 |
| 拒绝非平稳 | 拒绝平稳 | 可能结构突变、长记忆或样本问题 |
| 不能拒绝非平稳 | 不能拒绝平稳 | 数据量不足或序列信息弱,需谨慎 |
两种检验单独用都会误判,合并后用能显著减少错误。特别是当ADF说“平稳”但KPSS也说“不平稳”的时候,不要盲目相信ADF,先检查序列是否在中间段发生了结构突变,或者样本里有没有大型异常值。
Python里可以直接用statsmodels实现:
from statsmodels.tsa.stattools import adfuller, kpss def check_stationarity(x, alpha=0.05): adf_stat, adf_p, _, _, _, _ = adfuller(x, autolag="AIC") kpss_stat, kpss_p, _, _ = kpss(x, regression="ct", nlags="auto") print(f"ADF p-value: {adf_p:.4f}") print(f"KPSS p-value: {kpss_p:.4f}") adf_stationary = adf_p < alpha kpss_stationary = kpss_p >= alpha if adf_stationary and kpss_stationary: return "平稳" elif (not adf_stationary) and (not kpss_stationary): return "非平稳" else: return "需要进一步检查"注意,KPSS的regression参数我通常用"ct",因为很多业务序列即使没有明显趋势,也会有一点点漂移,用带趋势项的设定更稳健。如果你遇到那种均值强烈线性上升的序列,regression="ct"是合理的,否则会频繁把趋势误判为平稳。
5.2 ADF的滞后阶数选择和季节性陷阱
ADF检验结果对滞后期数非常敏感。滞后期选太少,残差自相关残留,检验偏差大;选太多,自由度损失,检验功效下降。我一般依赖autolag="AIC"自动选择,同时自己扫一圈1到最大滞后的结果,确认结论没有漂得很厉害。
更隐蔽的坑是季节性。ADF检验本质上检验的是长程趋势和单位根,它对固定周期的季节性识别能力很弱。我处理过一个日度降雨数据,ADF的p值小于0.05,看上去挺平稳,但ACF图上12阶滞后出现明显的峰值,说明年度季节成分还在。这种序列直接进入ARIMA,会导致预测结果在季节切换点大幅失效。正确做法是先做季节差分或STL分解,把周期成分拆掉,再跑平稳性检验。
5.3 样本量、异常值和结构突变对检验结果的影响
平稳性检验在小样本下极其不可靠。我的经验是,少于50个观测点,无论ADF还是KPSS都只能当参考;少于30个,基本别指望得出稳健结论。样本量不足时,检验功效很低,一个明显的随机游走也可能报“不平稳”报不出去。碰到这种情况,我会把低频数据聚合成更高的时间粒度,或者拉长观察窗口,而不是硬建模。
异常值的影响也不容忽视。一个极端尖峰会把自协方差估计拉上去,让ACF看起来像有长期相关性,或者让ADF计算出错误的单位根结论。遇到明显的毛刺,我会先记录原因,再决定是剔除、替换还是保留。如果是传感器偶尔跳数,直接剔掉;如果是真实业务大促带来的爆发,那得用哑变量或干预分析,而不是简单剔掉。
还有一个我反复遇到的场景:结构突变。序列前段平稳,中间突然系统切换,后段又平稳。整体上,ADF可能拒绝非平稳,KPSS也可能拒绝平稳,两边打架。这时候全局检验已经没意义,应该做分段检验,或者用Chow检验、Bai-Perron这类突变点检测方法。
6. 实战中如何把非平稳序列改造成宽平稳
6.1 先排除趋势和均值漂移:差分与去趋势
确认序列非平稳之后,优先区分它是“确定性趋势”还是“随机趋势”。确定性趋势,比如业务稳步增长,均值随时间是线性函数,用去趋势或引入时间变量解决。随机趋势,比如随机游走,均值没有确定路径,过去冲击的影响永远不会消退,用差分解决。
务实做法:先做一阶差分,再看序列是否平稳。如果一阶差分后出现负的自相关,说明可能过度差分;如果仍有趋势,再考虑二阶差分。我不建议单纯追求让p值小于0.05而盲目差分,差分每多一次,信息就损失一部分,模型解释力就下降。
6.2 方差不稳定:对数变换和方差平稳化
当序列的波动幅度随时间变化,比如金额持续增长,绝对波动也放大,残差方差不再恒定。宽平稳要求方差稳定,所以第一步往往是对数变换:对原始序列取log,把乘法波动变成加法波动。
对数值会自然出现0或负数的场景,可以用log1p或者加一个小的平移量。但加平移量直接影响水平,要谨慎。另一种常用的方差稳定变换是Box-Cox变换,它把对数、平方根、倒数统一到一个参数框架里。实操经验是:先用对数变换解决大部分问题,只有当对数还不够时才上Box-Cox。
6.3 周期性怎么办:季节差分与分解
周期性场景里,光做一阶差分往往不够,因为序列在不同周期的同一相位上仍然有强相关。比如销量数据里,每周五都有一个小高峰。这时候需要在差分之外做季节差分:X_t - X_{t-m},m是周期长度。
如果季节性和趋势同时存在,我习惯先用STL分解把序列拆成趋势项、季节项、残差项,然后对残差做平稳性检验和建模。STL的优势是灵活,周期项不一定是正弦波,也可以适应业务里不平滑的周期性模式。拆完再做ARIMA或别的模型,预测完再把季节项加回去,比直接对原序列建模要稳得多。
6.4 处理完再回头验证,把宽平稳当工程约束来用
最后一步永远是重新验证。你在处理完序列后,再跑一次ADF和KPSS,再看一遍ACF图,确认残差近似白噪声。同时看平方序列的ACF,如果平方ACF显示显著自相关,说明波动率还没有被捕捉,可能要给残差加GARCH类模型。
我在实际项目里的体会是:不要追求“数学上绝对严平稳”,而是把宽平稳当成一个工程约束——只要均值、方差、自相关结构在样本和合理预测区间内满足稳定性假设,模型就可以用。那些理论上完美的平稳性条件,是为了让我们清楚边界在哪里。越是在真实数据里摸爬滚打,越能体会到这个原则的实用价值。