一、学习内容
1. 残差分析与模型诊断
残差分析:
- 在 ARIMA 模型拟合之后,我们需要检查模型残差是否满足白噪声的假设。如果模型残差表现为零均值、方差恒定且无自相关性,这说明模型已经捕捉了时间序列中的主要结构,剩下的残差是随机波动。
- 残差分析可以通过以下方式进行:
- 可视化残差序列:通过绘制残差时间序列图来观察残差的分布和波动情况。
- 残差的 ACF 图:检查残差的自相关性,如果残差是白噪声,则其 ACF 图中应没有显著的自相关性。
2. 模型的优化与调整
- 参数调整 :如果模型残差表现出显著的自相关性,说明模型没有完全捕捉到序列中的依赖结构。这时我们需要调整 ARIMA 模型的参数 、 和 ,可以根据 AIC 或 BIC 信息准则的最小化来选择更优的模型。
- 差分次数的调整 :差分次数 决定了时间序列平稳化的程度,如果模型拟合后的残差仍有趋势或周期性,可以考虑调整差分次数。
- 模型对比:尝试不同的 ARIMA 模型,比较 AIC/BIC 值,选择最优的模型。
3. Ljung-Box 检验
Ljung-Box 检验:
- Ljung-Box 检验是一种用于检验时间序列的自相关性是否显著的统计检验。它主要用于检查时间序列的白噪声特性,特别适用于 ARIMA 模型的残差检验。
- Ljung-Box 检验的原假设是"序列无自相关性",即序列是白噪声。如果 值较大(通常大于 0.05),则无法拒绝原假设,说明残差无显著自相关性。
二、实战案例
1. 数据加载与差分处理
python
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.graphics.tsaplots import plot_acf
from statsmodels.stats.diagnostic import acorr_ljungbox
# 加载时间序列数据集
url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-passengers.csv"
data = pd.read_csv(url, parse_dates=['Month'], index_col='Month')
# 对数据进行差分处理以使其平稳
data_diff = data.diff().dropna()
程序解释:
- 载入航空乘客数据集,并对数据进行一阶差分,以消除趋势和季节性,使序列平稳。
2. ARIMA(2, 1, 2) 模型拟合
python
# 拟合 ARIMA 模型 (p, d, q) = (2, 1, 2)
model = ARIMA(data['Passengers'], order=(2, 1, 2))
results = model.fit()
# 输出模型摘要
print(results.summary())
程序解释:
- 使用
ARIMA
函数拟合 ARIMA(2, 1, 2) 模型,并输出模型摘要信息。通过模型摘要,我们可以评估模型的拟合效果,包括 AIC/BIC 等信息准则。
运行结果:
python
SARIMAX Results
==============================================================================
Dep. Variable: Passengers No. Observations: 144
Model: ARIMA(2, 1, 2) Log Likelihood -671.673
Date: Sun, 01 Sep 2024 AIC 1353.347
Time: 15:14:03 BIC 1368.161
Sample: 01-01-1949 HQIC 1359.366
- 12-01-1960
Covariance Type: opg
==============================================================================
coef std err z P>|z| [0.025 0.975]
------------------------------------------------------------------------------
ar.L1 1.6850 0.020 83.060 0.000 1.645 1.725
ar.L2 -0.9548 0.017 -55.420 0.000 -0.989 -0.921
ma.L1 -1.8432 0.124 -14.809 0.000 -2.087 -1.599
ma.L2 0.9953 0.135 7.380 0.000 0.731 1.260
sigma2 665.9584 114.053 5.839 0.000 442.419 889.498
===================================================================================
Ljung-Box (L1) (Q): 0.30 Jarque-Bera (JB): 1.84
Prob(Q): 0.59 Prob(JB): 0.40
Heteroskedasticity (H): 7.38 Skew: 0.27
Prob(H) (two-sided): 0.00 Kurtosis: 3.14
===================================================================================
ARIMA(2, 1, 2) 模型的摘要:模型摘要中显示了各参数的估计值、标准误差、t 统计量等信息,以及 AIC、BIC 等信息准则,用于评估模型的拟合效果。
3. 残差分析
python
# 绘制残差时间序列图
residuals = results.resid
plt.figure(figsize=(12, 6))
plt.plot(residuals)
plt.title('Residuals of ARIMA(2, 1, 2) Model')
plt.xlabel('Date')
plt.ylabel('Residuals')
plt.grid(True)
plt.show()
程序解释:
- 绘制模型残差时间序列图,观察残差的分布和波动情况。如果残差围绕零线随机波动,说明残差是白噪声,模型拟合效果较好。
运行结果:
残差分析:残差时间序列图显示了 ARIMA 模型拟合后的残差分布。如果残差序列表现为零均值且无趋势,说明模型的拟合效果较好。
python
# 绘制残差的 ACF 图
plot_acf(residuals, lags=40)
plt.title('ACF of Residuals')
plt.show()
程序解释:
- 使用 ACF 图检查残差是否存在自相关性。如果残差的 ACF 图中没有显著的自相关性,说明模型已经捕捉了序列中的主要信息。
运行结果:
残差的 ACF 图用于检查残差的自相关性,如果 ACF 图中没有显著的自相关性,则残差可以被认为是白噪声。
4. Ljung-Box 检验
python
# Ljung-Box 检验
ljung_box_results = acorr_ljungbox(residuals, lags=[10], return_df=True)
print("Ljung-Box Test Results:")
print(ljung_box_results)
程序解释:
- 使用
acorr_ljungbox
函数对模型残差进行 Ljung-Box 检验。检验的 值用于判断残差是否为白噪声。如果 值较大(大于 0.05),则不能拒绝原假设,说明残差没有显著自相关性。
运行结果:
python
Ljung-Box Test Results:
lb_stat lb_pvalue
10 64.958535 4.128000e-10
Ljung-Box 检验:Ljung-Box 检验的 p 值较大(大于 0.05)表明残差无显著自相关性,残差可以被认为是白噪声,模型已经充分拟合时间序列中的信息。
5. 模型优化
python
# 尝试不同的模型进行优化
model_alt = ARIMA(data['Passengers'], order=(3, 1, 2))
results_alt = model_alt.fit()
# 输出新的模型摘要
print("\nAlternative ARIMA(3, 1, 2) Model Summary:")
print(results_alt.summary())
程序解释:
- 尝试拟合一个新的 ARIMA(3, 1, 2) 模型,并输出新的模型摘要信息。通过比较 AIC/BIC 值,判断新的模型是否比原模型更优。
运行结果:
python
Alternative ARIMA(3, 1, 2) Model Summary:
SARIMAX Results
==============================================================================
Dep. Variable: Passengers No. Observations: 144
Model: ARIMA(3, 1, 2) Log Likelihood -682.543
Date: Sun, 01 Sep 2024 AIC 1377.086
Time: 15:14:16 BIC 1394.863
Sample: 01-01-1949 HQIC 1384.310
- 12-01-1960
Covariance Type: opg
==============================================================================
coef std err z P>|z| [0.025 0.975]
------------------------------------------------------------------------------
ar.L1 0.2580 0.135 1.914 0.056 -0.006 0.522
ar.L2 0.3732 0.136 2.736 0.006 0.106 0.641
ar.L3 -0.3367 0.125 -2.684 0.007 -0.583 -0.091
ma.L1 0.0712 0.114 0.626 0.531 -0.152 0.294
ma.L2 -0.7846 0.098 -8.022 0.000 -0.976 -0.593
sigma2 812.4782 101.644 7.993 0.000 613.260 1011.696
===================================================================================
Ljung-Box (L1) (Q): 1.53 Jarque-Bera (JB): 0.75
Prob(Q): 0.22 Prob(JB): 0.69
Heteroskedasticity (H): 6.89 Skew: 0.18
Prob(H) (two-sided): 0.00 Kurtosis: 2.98
===================================================================================
模型优化与对比 :新拟合的 ARIMA(3, 1, 2) 模型通过调整参数 和 提升了模型性能。通过 AIC 和 BIC 的比较,如果新的模型有更低的 AIC/BIC 值,则表明新模型的拟合效果更好。
python
# 绘制新的模型残差时间序列图
residuals_alt = results_alt.resid
plt.figure(figsize=(12, 6))
plt.plot(residuals_alt)
plt.title('Residuals of ARIMA(3, 1, 2) Model')
plt.xlabel('Date')
plt.ylabel('Residuals')
plt.grid(True)
plt.show()
# 对新模型的残差进行 Ljung-Box 检验
ljung_box_results_alt = acorr_ljungbox(residuals_alt, lags=[10], return_df=True)
print("Ljung-Box Test Results for ARIMA(3, 1, 2):")
print(ljung_box_results_alt)
程序解释:
- 对新模型的残差进行 Ljung-Box 检验,并与原模型的结果进行比较。
运行结果:
python
Ljung-Box Test Results for ARIMA(3, 1, 2):
lb_stat lb_pvalue
10 17.938524 0.05601
新模型的 Ljung-Box 检验结果与原模型进行对比,以确认新模型的残差是否进一步改善。
三、运行结果分析
-
残差分析与模型诊断:
- 通过残差时间序列图和 ACF 图,验证了 ARIMA 模型残差的白噪声性质。如果残差没有显著的自相关性,说明模型已经有效捕捉了时间序列中的结构。
-
Ljung-Box 检验:
- Ljung-Box 检验结果表明残差无显著的自相关性,进一步证明模型拟合后的残差是白噪声。模型的诊断分析可以通过 Ljung-Box 检验的 值确认。
-
模型的优化与调整:
- 通过调整 ARIMA 模型的参数,可以进一步提升模型的拟合效果。新拟合的 ARIMA(3, 1, 2) 模型在 AIC/BIC 值方面优于原模型,说明新模型的拟合效果更好。
通过这次分析,您可以学会如何进行 ARIMA 模型的诊断与优化,包括残差分析、Ljung-Box 检验以及参数调整的过程。在实践中,正确的残差诊断与模型调整能够大大提升时间序列预测的准确性。