4. 时间序列分析基础:平稳性与非平稳性、ACF与PACF、差分操作与单位根检验
各位同学,咱们今天聊时间序列分析。说实话,我刚入行那会儿,觉得这玩意儿就是数学公式堆砌。直到我在电力市场里栽了跟头——用非平稳数据直接建模,预测结果惨不忍睹。从那以后,我才真正重视起这些基础概念。
时间序列分析,说白了就是研究数据随时间变化的规律。在容量市场里,价格序列、负荷序列、机组可用率序列,这些都是典型的时间序列。你想想看,如果连数据的基本性质都搞不清楚,后面的建模不就是空中楼阁吗?
4.1 平稳性与非平稳性
平稳性,是时间序列分析的第一道门槛。什么叫平稳?我个人的理解是:数据的统计性质不随时间变化。具体来说,均值恒定、方差恒定、自协方差只与时间间隔有关,与具体时间点无关。
严平稳 vs 弱平稳
- 严平稳:联合分布不随时间平移而变化。要求太苛刻,实际中几乎用不到。
- 弱平稳:均值、方差为常数,自协方差只与滞后阶数有关。这是咱们建模时常用的假设。
我在项目中遇到过这样的情况:某地区的容量出清价格看起来挺平稳,但仔细一查,2019年政策调整后均值明显上移了。这就是典型的非平稳——均值发生了结构性变化。
非平稳序列有什么特征?趋势、季节性、周期性,这些都会破坏平稳性。举个例子,夏季负荷高峰期的容量价格,明显高于春秋季,这就是季节性。如果你不处理,模型会把季节性当成规律来学,结果就是预测偏差很大。
避坑指南:我曾经用非平稳的容量价格序列直接拟合ARIMA模型,结果R²高达0.95,但回测时一塌糊涂。后来才发现,这是伪回归——两个不相关的非平稳序列,回归结果也可能显著。记住:非平稳数据不能直接建模。
4.2 自相关函数(ACF)与偏自相关函数(PACF)
这两个函数,是识别时间序列依赖结构的利器。ACF衡量的是当前值与滞后值之间的相关性,包括间接影响。PACF则剔除了中间变量的影响,只保留直接关系。
怎么理解?你想想看,今天的容量价格和昨天的价格相关,可能还和前天的价格相关。但昨天的价格已经包含了前天的信息,所以PACF能帮你找出真正的直接依赖。
| 函数 | 含义 | 用途 |
|---|---|---|
| ACF | 当前值与滞后k期值的相关性(含间接影响) | 识别MA模型的阶数 |
| PACF | 剔除中间滞后项影响后的直接相关性 | 识别AR模型的阶数 |
我习惯的做法是:先画ACF和PACF图,观察拖尾和截尾特征。如果ACF拖尾、PACF在p阶后截尾,那可能是AR(p)模型。反过来,ACF在q阶后截尾、PACF拖尾,那就是MA(q)。如果都拖尾,那就得考虑ARMA了。
小技巧:实际数据往往没那么理想。我建议你多画几个滞后阶数,别只看前几阶。有时候季节性会导致ACF在周期倍数处出现峰值,比如24小时、168小时(一周),这些都要留意。
4.3 差分操作
差分,是处理非平稳序列最常用的方法。一阶差分就是当前值减去上一期值,二阶差分就是在一阶差分的基础上再差分一次。说白了,就是看变化量的变化量。
为什么差分有效?因为很多非平稳序列的增量是平稳的。比如容量价格有随机游走特征,价格本身不平稳,但价格变化量(收益率)往往是平稳的。我做过一个项目,某市场的容量价格序列一阶差分后,ADF检验的p值从0.45降到了0.001以下,效果立竿见影。
# Python示例:差分操作
import pandas as pd
import numpy as np
# 模拟非平稳序列
np.random.seed(42)
n = 200
trend = np.linspace(0, 5, n)
noise = np.random.normal(0, 1, n)
series = trend + noise # 有趋势的非平稳序列
# 一阶差分
diff_1 = np.diff(series, n=1)
# 二阶差分
diff_2 = np.diff(series, n=2)
print(f"原始序列方差: {np.var(series):.4f}")
print(f"一阶差分方差: {np.var(diff_1):.4f}")
print(f"二阶差分方差: {np.var(diff_2):.4f}")
不过要注意,差分次数不是越多越好。过度差分会引入额外的噪声,而且会丢失信息。我一般最多差分到二阶,如果还不平稳,那就要考虑其他方法了,比如对数变换、季节差分。
注意:差分后,原始序列的长期关系会被破坏。如果你需要做长期预测,差分模型可能不太合适。我曾经犯过这个错——差分后模型拟合得很好,但预测未来12个月的价格时,误差越来越大。后来改用带季节分量的模型才解决问题。
4.4 单位根检验
单位根检验,是判断序列是否平稳的统计方法。最常用的是ADF检验(Augmented Dickey-Fuller test)。原假设是序列存在单位根(非平稳),备择假设是序列平稳。
怎么解读结果?看p值。如果p值小于0.05,拒绝原假设,认为序列平稳。如果p值大于0.05,不能拒绝原假设,序列非平稳,需要差分。
# Python示例:ADF检验
from statsmodels.tsa.stattools import adfuller
# 对原始序列进行ADF检验
result_original = adfuller(series)
print(f"原始序列 ADF统计量: {result_original[0]:.4f}")
print(f"p值: {result_original[1]:.4f}")
# 对一阶差分序列进行ADF检验
result_diff = adfuller(diff_1)
print(f"一阶差分 ADF统计量: {result_diff[0]:.4f}")
print(f"p值: {result_diff[1]:.4f}")
除了ADF,还有KPSS检验。注意,KPSS的原假设是序列平稳,和ADF正好相反。我建议两个都做,交叉验证。如果ADF说非平稳、KPSS说平稳,那可能是序列有趋势但围绕趋势波动,这种情况可以考虑去趋势后再分析。
经验之谈:在容量市场数据中,我经常遇到结构突变的问题。比如2018年某省容量市场规则调整后,价格序列的均值发生了跳跃。这时候普通的ADF检验可能失效,需要用Zivot-Andrews检验,它能检测带结构突变的单位根。嗯,这个稍微进阶一点,但遇到政策变化时特别有用。
知识体系总览
下面这张图,是我梳理的本章知识结构。你可以把它当作一个检查清单,看看自己是否掌握了每个环节。
这张图把四个核心概念串起来了。你从平稳性出发,判断数据是否需要处理;然后用ACF/PACF识别模型结构;最后用差分和单位根检验来验证和修正。每一步都有对应的工具和方法,环环相扣。
好了,这一章的内容就到这里。记住:时间序列分析不是一锤子买卖,需要反复迭代、验证。我每次拿到新数据,都会先做一遍平稳性检验,画ACF/PACF图,再决定用什么模型。这个习惯帮我避免了很多坑。
公众号:蓝海资料掘金营,微信deep3321