跳到主要内容

平稳性、白噪声与自相关(ACF)

直觉

时间序列建模的第一问:这串数据「平稳」吗? 平稳序列的统计性质(均值、方差)不随时间漂移,才能用历史预测未来。价格一般不平稳(一路漂移),而收益率近似平稳。**自相关函数(ACF)**和 ADF 检验是判断平稳性的两把尺子。

平稳与白噪声

  • 平稳(stationary):均值、方差不随时间变,自相关只依赖滞后阶数;
  • 白噪声:最特殊的平稳序列——自相关全为 0(没有任何可预测结构)。

ACF

滞后 kk 的自相关:

ρk=Cov(xt,xtk)Var(xt)\rho_k = \frac{\text{Cov}(x_t, x_{t-k})}{\text{Var}(x_t)}

画出 ρk\rho_kkk 变化(相关图):

  • 平稳序列的 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 给平稳序列建立预测模型。