4、自相关与偏自相关:ACF与PACF的定义、如何解读ACF/PACF图、利用ACF/PACF识别模型阶数
好,咱们进入时间序列分析里一个非常核心的环节——自相关(ACF)和偏自相关(PACF)。
说实话,我刚入行那会儿,看到ACF/PACF图就头大。一堆竖线,上下还有两条蓝线,完全不知道它在说什么。后来踩了不少坑,才慢慢摸清楚门道。
今天我就把这块掰开揉碎了讲给你听。保证你学完就能看懂图,还能用它来定模型阶数。
4.1 自相关函数(ACF)到底是什么?
先问个问题:今天的股价和昨天的股价有没有关系?
大概率是有的。如果昨天涨了,今天可能继续涨。这种“自己跟自己过去”的相关性,就叫自相关。
ACF(Autocorrelation Function)就是用来量化这种关系的。它计算的是:
- 当前时刻 t 的值,与 t-1 时刻的值之间的相关系数
- 当前时刻 t 的值,与 t-2 时刻的值之间的相关系数
- ……以此类推,直到 t-k 时刻
数学上,对于滞后 k 的自相关系数,公式是:
ρ(k) = Cov(Y_t, Y_{t-k}) / Var(Y_t)
说白了,就是看相隔 k 个时间点的两个值,它们线性相关的程度有多强。
重要性质:
- ρ(0) 永远等于 1(自己和自己的相关性当然是 1)
- ρ(k) 的取值范围在 [-1, 1] 之间
- 对于平稳序列,ACF 会随着 k 增大而衰减到 0
4.2 偏自相关函数(PACF)又是什么?
ACF 有个问题——它会把间接影响也算进去。
举个例子:
假设今天的气温(t)受昨天(t-1)影响,昨天又受前天(t-2)影响。那么今天和前天之间,其实是有相关性的。但这种相关性是“间接”的,是通过昨天传递过来的。
PACF 要做的,就是剔除中间变量的干扰。
偏自相关函数(Partial Autocorrelation Function)衡量的是:在剔除掉 t-1, t-2, ..., t-k+1 的影响之后,Y_t 和 Y_{t-k} 之间的纯相关性。
我习惯这么理解:
- ACF 是“总账”,包含直接和间接关系
- PACF 是“净账”,只看直接关系
4.3 如何解读ACF/PACF图?
好,理论说完了。咱们来看实战中最常用的东西——ACF/PACF 图。
你想想看,拿到一张图,上面一堆竖线,还有两条蓝色的置信区间边界线。怎么看?
我总结了一个口诀:“看截尾,看拖尾,看周期”。
4.3.1 截尾(Cut-off)
如果某个滞后阶数之后,竖线突然掉到置信区间内(也就是蓝色线以内),并且后面基本都在里面,这叫截尾。
比如 PACF 在滞后 2 阶之后全部掉进区间,那就叫“PACF 在 2 阶截尾”。
4.3.2 拖尾(Tailing off)
如果竖线是慢慢衰减的,像一条尾巴拖在后面,这叫拖尾。
比如 ACF 从滞后 1 阶开始逐渐变小,但始终没有突然截断,那就是“ACF 拖尾”。
4.3.3 周期性
如果每隔固定的滞后阶数(比如 12、24、36)出现一个明显的峰值,说明数据有季节性周期。
我的个人经验:
看 ACF/PACF 图时,别只看前几阶。我建议至少看到滞后 40 阶。因为有些季节性周期可能藏在后面。我曾经在分析电商销售数据时,ACF 图在滞后 7 阶有个小峰值,一开始没在意,后来才发现那是周周期效应。
4.4 利用ACF/PACF识别模型阶数
这是最实用的部分。ACF 和 PACF 的形态,直接告诉我们该用 AR 模型还是 MA 模型,以及阶数是多少。
我整理了一个对照表,你直接拿去用:
| 模型 | ACF 形态 | PACF 形态 |
|---|---|---|
| AR(p) | 拖尾(逐渐衰减) | p 阶后截尾 |
| MA(q) | q 阶后截尾 | 拖尾(逐渐衰减) |
| ARMA(p, q) | 拖尾 | 拖尾 |
怎么用?举个例子:
- 如果 PACF 在滞后 2 阶后截尾,ACF 拖尾 → 用 AR(2) 模型
- 如果 ACF 在滞后 1 阶后截尾,PACF 拖尾 → 用 MA(1) 模型
- 如果两者都拖尾 → 用 ARMA 模型,阶数需要进一步判断
避坑指南:
我曾经犯过一个错误:看到 PACF 在滞后 3 阶后截尾,就立刻定了 AR(3)。结果模型拟合效果很差。
后来发现,样本量太小(只有 50 个点),导致置信区间太宽,截尾的判断不可靠。
建议:样本量至少 100 以上,ACF/PACF 图才有参考价值。如果样本少,配合 AIC/BIC 准则一起判断更稳妥。
4.5 实战:用Python画ACF/PACF图
光说不练假把式。咱们用 statsmodels 来画图,看看实际数据长什么样。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
# 生成模拟数据:AR(2) 过程
np.random.seed(42)
n = 200
ar_params = np.array([0.6, -0.3])
ma_params = np.array([0.0])
from statsmodels.tsa.arima_process import ArmaProcess
ar = np.r_[1, -ar_params]
ma = np.r_[1, ma_params]
arma_process = ArmaProcess(ar, ma)
y = arma_process.generate_sample(nsample=n)
# 画 ACF 和 PACF
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 6))
plot_acf(y, lags=30, ax=ax1, alpha=0.05)
ax1.set_title('ACF 图')
plot_pacf(y, lags=30, ax=ax2, alpha=0.05, method='ywm')
ax2.set_title('PACF 图')
plt.tight_layout()
plt.show()
运行这段代码,你会看到:
- ACF 图:缓慢衰减,拖尾
- PACF 图:在滞后 2 阶后,竖线全部掉进蓝色置信区间内
这正好对应我们前面说的 AR(2) 模型的特征。
4.6 核心知识体系
下面这张图,是我自己梳理的 ACF/PACF 知识框架。你把它存下来,以后看图的时候对照着用。
4.7 几个容易踩的坑
最后,分享几个我实战中遇到的坑,你注意避开:
- 不要只看前几阶:有时候季节性周期藏在滞后 12、24 阶,只看前 10 阶会漏掉。
- 样本量不够别硬看:少于 100 个数据点,ACF/PACF 的置信区间会很不稳定。
- 非平稳序列先差分:如果序列有明显的趋势或季节性,ACF 会衰减得很慢。先做差分,再看图。
- 不要迷信截尾:有时候截尾点并不明显。这时候配合 AIC/BIC 准则一起判断,比单看图更靠谱。
嗯,ACF 和 PACF 这块就讲到这里。你只要记住那个口诀——“看截尾,看拖尾,看周期”,再结合对照表,模型阶数基本就能定下来了。