趋近智
为时间序列生成自相关函数(ACF)和偏自相关函数(PACF)图,并分析它们以推荐可能的模型阶数。在拟合ARIMA模型之前,此过程非常重要,因为这些图提供了关于平稳时间序列内在结构('p'和'q'参数)的线索。
我们假设您已经准备好一个平稳时间序列。如果您从非平稳数据开始,则应已应用差分等变换(如第2章所述)以达到平稳性。本次练习中,我们将使用人工生成的平稳数据集,以清楚地展示预期的模式。
您需要以下Python库:
numpy 用于数值运算和生成样本数据。pandas 用于数据处理(如果直接使用NumPy数组,对于此特定的绘图示例而言,其重要性较低)。statsmodels 用于ACF/PACF计算和绘图函数。plotly.graph_objects 用于按要求创建图表(我们将根据statsmodels的计算手动构建这些图表)。import numpy as np
import pandas as pd
import statsmodels.api as sm
from statsmodels.tsa.stattools import acf, pacf
# 我们将根据要求使用plotly进行可视化
# 注意:statsmodels有其基于matplotlib的plot_acf/plot_pacf函数,
# 但我们将提取数据来创建Plotly图表。
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# 设置随机种子以保证结果可重现
np.random.seed(42)
# 生成一个样本平稳AR(2)过程:
# y_t = 0.7*y_{t-1} - 0.3*y_{t-2} + noise
ar_params = np.array([0.7, -0.3])
ma_params = np.array([]) # 没有MA(移动平均)分量
ar = np.r_[1, -ar_params] # 添加零滞后系数
ma = np.r_[1, ma_params] # 添加零滞后系数
# 生成500个数据点
n_samples = 500
# 使用ArmaProcess生成数据(statsmodels的一部分)
from statsmodels.tsa.arima_process import ArmaProcess
ar_process = ArmaProcess(ar, ma)
sample_data = ar_process.generate_sample(nsample=n_samples)
# 转换为pandas Series(可选,但常见做法)
ts = pd.Series(sample_data)
print("生成的样本数据(前5个值):")
print(ts.head())
print(f"\n生成的数据是否平稳(基于生成过程)?是的,AR(2)过程参数在平稳区域内。")
# 通常您会在真实数据上运行ADF检验
# from statsmodels.tsa.stattools import adfuller
# adf_result = adfuller(ts)
# print(f'ADF Statistic: {adf_result[0]}')
# print(f'p-value: {adf_result[1]}') # 低的p-值表示平稳性
ACF测量时间序列yt与其滞后值yt−k在不同滞后k下的相关性。我们使用statsmodels.tsa.stattools中的acf函数来计算这些值和相应的置信区间。
滞后k处的显著峰值表示相隔k个周期的观测值之间存在强相关性。对于MA(q)过程,ACF图预计在滞后q之前有显著峰值,然后突然截断(落入置信区间内)。对于AR(p)过程,ACF通常衰减更慢(通常呈几何式衰减或正弦波模式)。
# 计算ACF和置信区间
# nlags指定要计算的滞后数量;alpha指定置信水平(0.05表示95%)
acf_values, confint = acf(ts, nlags=20, alpha=0.05)
# 置信区间数组confint的形状为(nlags+1, 2)
# 下限 = confint[:, 0] - acf_values
# 上限 = confint[:, 1] - acf_values
# 注意:acf_values[0]始终为1(与滞后0的相关性)
lags = np.arange(len(acf_values))
conf_lower = confint[:, 0] - acf_values
conf_upper = confint[:, 1] - acf_values
# 为ACF创建Plotly图
fig_acf = go.Figure()
# 添加置信区间带(不包括滞后0)
fig_acf.add_trace(go.Scatter(
x=np.concatenate([lags[1:], lags[1:][::-1]]), # 多边形形状的x坐标
y=np.concatenate([conf_upper[1:], conf_lower[1:][::-1]]), # 多边形形状的y坐标
fill='toself',
fillcolor='#a5d8ff', # 浅蓝色
line=dict(color='rgba(255,255,255,0)'), # 无边框线
hoverinfo="skip",
showlegend=False,
name='置信区间'
))
# 添加ACF条/茎(不包括滞后0)
fig_acf.add_trace(go.Scatter(
x=lags[1:],
y=acf_values[1:],
mode='markers',
marker=dict(color='#1c7ed6', size=8), # 蓝色点
name='ACF'
))
# 添加从茎到x轴的垂直线
for i in range(1, len(acf_values)):
fig_acf.add_shape(type='line',
x0=lags[i], y0=0,
x1=lags[i], y1=acf_values[i],
line=dict(color='#495057', width=1.5)) # 灰色线
# 添加滞后0点(始终为1)
fig_acf.add_trace(go.Scatter(
x=[lags[0]], y=[acf_values[0]], mode='markers', marker=dict(color='#1c7ed6', size=8), showlegend=False
))
fig_acf.add_shape(type='line', x0=lags[0], y0=0, x1=lags[0], y1=acf_values[0], line=dict(color='#495057', width=1.5))
# 更新布局
fig_acf.update_layout(
title='自相关函数(ACF)',
xaxis_title='滞后',
yaxis_title='自相关',
yaxis_range=[-1, 1.1], # 确保y轴覆盖整个范围加上滞后0
xaxis=dict(tickmode='linear', dtick=1), # 显示整数滞后
plot_bgcolor='white',
height=350,
margin=dict(l=50, r=20, t=50, b=40)
)
# 显示图表(在笔记本环境中)或保存它
# fig_acf.show() # 取消注释以交互方式显示
生成的AR(2)数据的ACF图。蓝色阴影区域表示95%置信区间。此区域外的相关性具有统计学意义。
PACF测量在移除中间滞后(yt−1,yt−2,...,yt−k+1)的影响后,yt与yt−k之间的相关性。我们使用statsmodels.tsa.stattools中的pacf函数。
对于AR(p)过程,PACF图预计在滞后p之前有显著峰值,然后突然截断。这是因为PACF移除了较短滞后的影响,隔离了AR参数所描述的直接关系。对于MA(q)过程,PACF通常衰减更慢。
# 计算PACF和置信区间
# method='ywm'是默认方法,通常推荐使用
pacf_values, confint_pacf = pacf(ts, nlags=20, alpha=0.05, method='ywm')
# 提取置信区间,与ACF类似
lags_pacf = np.arange(len(pacf_values))
conf_lower_pacf = confint_pacf[:, 0] - pacf_values
conf_upper_pacf = confint_pacf[:, 1] - pacf_values
# 为PACF创建Plotly图
fig_pacf = go.Figure()
# 添加置信区间带(不包括滞后0)
fig_pacf.add_trace(go.Scatter(
x=np.concatenate([lags_pacf[1:], lags_pacf[1:][::-1]]),
y=np.concatenate([conf_upper_pacf[1:], conf_lower_pacf[1:][::-1]]),
fill='toself',
fillcolor='#a5d8ff', # 浅蓝色
line=dict(color='rgba(255,255,255,0)'),
hoverinfo="skip",
showlegend=False,
name='置信区间'
))
# 添加PACF条/茎(不包括滞后0)
fig_pacf.add_trace(go.Scatter(
x=lags_pacf[1:],
y=pacf_values[1:],
mode='markers',
marker=dict(color='#7048e8', size=8), # 紫罗兰色点
name='PACF'
))
# 添加从茎到x轴的垂直线
for i in range(1, len(pacf_values)):
fig_pacf.add_shape(type='line',
x0=lags_pacf[i], y0=0,
x1=lags_pacf[i], y1=pacf_values[i],
line=dict(color='#495057', width=1.5)) # 灰色线
# 添加滞后0点(根据PACF定义始终为1,但有时在图中省略)
# 对于PACF,我们将省略滞后0处的线/标记,因为它不如ACF那样是标准做法
# fig_pacf.add_trace(go.Scatter(
# x=[lags_pacf[0]], y=[pacf_values[0]], mode='markers', marker=dict(color='#7048e8', size=8), showlegend=False
# ))
# 更新布局
fig_pacf.update_layout(
title='偏自相关函数(PACF)',
xaxis_title='滞后',
yaxis_title='偏自相关',
yaxis_range=[-1, 1.1], # 确保y轴覆盖整个范围
xaxis=dict(tickmode='linear', dtick=1), # 显示整数滞后
plot_bgcolor='white',
height=350,
margin=dict(l=50, r=20, t=50, b=40)
)
# fig_pacf.show() # 取消注释以交互方式显示
生成的AR(2)数据的PACF图。蓝色阴影区域表示95%置信区间。
现在,让我们解读从样本AR(2)数据生成的图:
ACF图分析:
PACF图分析:
结论:
以下是基于平稳数据ACF/PACF模式的快速参考指南:
| 过程 | ACF模式 | PACF模式 | 建议模型 |
|---|---|---|---|
| AR(p) | 拖尾(几何/正弦波) | 在滞后p后截断 | ARIMA(p, 0, 0) |
| MA(q) | 在滞后q后截断 | 拖尾(几何/正弦波) | ARIMA(0, 0, q) |
| ARMA(p,q) | 拖尾 | 拖尾 | ARIMA(p, 0, q) |
(请记住,ARIMA(p, d, q)中的“d”与达到平稳性所需的差分有关,这在分析ACF/PACF图之前确定。)
现在轮到您自己应用这些方法了。
y_t = 0.6 * noise_{t-1} + noise_t),类似于我们上面生成AR(2)数据的方式。“解读ACF和PACF图通常更像一门艺术而非精确科学,尤其是在处理噪声数据时。有时模式并不完全清晰。然而,它们为识别候选模型提供了不可或缺的起点,您将在接下来的章节中学习如何拟合和评估这些模型。”
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造