平稳性、白噪声与自相关(ACF)
直觉
时间序列建模的第一问:这串数据「平稳」吗? 平稳序列的统计性质(均值、方差)不随时间漂移,才能用历史预测未来。价格一般不平稳(一路漂移),而收益率近似平稳。**自相关函数(ACF)**和 ADF 检验是判断平稳性的两把尺子。
平稳与白噪声
- 平稳(stationary):均值、方差不随时间变,自相关只依赖滞后阶数;
- 白噪声:最特殊的平稳序列——自相关全为 0(没有任何可预测结构)。
ACF
滞后 的自相关:
画出 随 变化(相关图):
- 平稳序列的 ACF 快速衰减到 0;
- 非平稳序列的 ACF 衰减很慢(长期记忆)。
「人话」解释:ADF 检验在看什么?
ADF( augmented Dickey-Fuller)检验「单位根」——原假设是「序列非平稳」。报告一个统计量与 p 值:p 越小越能拒绝非平稳(即越说明平稳)。 经验:p 小于 0.05 → 平稳。价格通常通不过(p 大),收益率能通过(p 小)。
可运行案例:价格 vs 收益的 ACF 与 ADF
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import acf, adfuller
df = pd.read_csv('/data/spy_daily.csv', parse_dates=['date']).set_index('date')
close = df['adj_close']
ret = np.log(close / close.shift(1)).dropna()
def corrgram(x, lags, ax, title):
a = acf(x, nlags=lags, fft=True)
ax.bar(range(lags + 1), a, width=0.4, color='#2563eb')
ci = 1.96 / np.sqrt(len(x))
ax.axhline(ci, color='r', ls='--', lw=0.8); ax.axhline(-ci, color='r', ls='--', lw=0.8)
ax.axhline(0, color='gray', lw=0.6); ax.set_title(title); ax.set_xlabel('lag')
fig, ax = plt.subplots(1, 2, figsize=(10, 3.6))
corrgram(close, 30, ax[0], '价格 ACF(衰减慢 → 非平稳)')
corrgram(ret, 30, ax[1], '收益 ACF(快速归零 → 平稳)')
plt.tight_layout(); plt.show()
ap = adfuller(close); ar = adfuller(ret)
print(f"价格 ADF: stat={ap[0]:7.2f} p={ap[1]:.3f} → {'非平稳(有单位根)' if ap[1] > 0.05 else '平稳'}")
print(f"收益 ADF: stat={ar[0]:7.2f} p={ar[1]:.3g} → {'非平稳' if ar[1] > 0.05 else '平稳'}")
print("\n→ 价格不平稳、收益平稳;所以建模对象是收益(或对数价格差分)。")
小结
- 平稳序列才能建模预测;价格非平稳、收益近似平稳;
- ACF 衰减快=平稳,衰减慢=非平稳;
- ADF 检验单位根,p 小则平稳。
下一节用 ARIMA 给平稳序列建立预测模型。