Task:
1.时序建模的流程
2.时序任务经典单变量数据集
3.ARIMA(p,d,q)模型实战
4.SARIMA摘要图的理解
5.处理不平稳的2种差分
a.n阶差分—处理趋势
b.季节性差分—处理季节性
建立一个ARIMA模型,通常遵循以下步骤:
- 数据可视化:观察原始时间序列图,判断是否存在趋势或季节性。
- 平稳性检验:
- 对原始序列进行ADF检验。
- 如果p值 > 0.05,说明序列非平稳,需要进行差分。
- 确定差分次数 d:
- 进行一阶差分,然后再次进行ADF检验。
- 如果平稳了,则 d=1。否则,继续差分,直到平稳。
- 确定 p 和 q:
- 对差分后的平稳序列绘制ACF和PACF图。
- 根据昨天学习的规则(PACF定p,ACF定q)来选择p和q的值。
- 建立并训练ARIMA(p, d, q)模型。
6.模型评估与诊断:查看模型的摘要信息,检查残差是否为白噪声。
a.AIC用来对比不同模型选择,越小越好
b.关注系数是否显著,通过p值或者置信区间均可
c.残差的白噪声检验+正态分布检验 - 进行预测(需要还原回差分前的结构)
太棒了!这是一个非常系统和全面的知识点回顾。下面我将结合您的总结,并加入更详细的解释和实际代码示例,来帮助您深入理解并实战ARIMA模型。
1. 时序建模的流程
时间序列建模不仅仅是运行一个算法,它是一个端到端的问题解决过程。
- 问题定义与数据收集: 明确业务目标(比如:预测未来3个月的销售额)。收集与时间相关的数据,确保数据的粒度(天、周、月等)和覆盖范围符合需求。
- 数据探索与可视化 (EDA):
- 时间序列图: 最重要的第一步,直观判断趋势(上升/下降)、季节性(周期性模式)、周期性(不规则的重复模式)、波动性(方差是否恒定)、异常值。
- 分解图: 使用
statsmodels.tsa.seasonal.seasonal_decompose
可以将时间序列分解为趋势、季节性和残差,帮助我们更清晰地理解数据的组成部分。 - ACF/PACF 图: 初步判断数据的自相关性,为选择ARIMA模型的p, q参数提供线索。
- 数据预处理:
- 缺失值处理: 插值(线性插值、多项式插值、样条插值)、前向/后向填充、删除。
- 异常值处理: 识别并处理(平滑、替换、删除)。
- 平稳化: 这是ARIMA模型的核心要求。非平稳序列的统计特性(均值、方差、自协方差)随时间变化,导致模型参数不稳定。主要通过差分来达到平稳。
- 模型选择: 基于数据特性(是否平稳、是否存在季节性、线性/非线性)选择合适的模型。ARIMA处理线性、单变量、平稳或可差分至平稳的序列。
- 模型训练: 将数据集分为训练集和测试集。使用训练集数据拟合模型,估计模型参数。
- 模型评估与诊断:
- 性能指标: 使用RMSE (均方根误差)、MAE (平均绝对误差)、MAPE (平均绝对百分比误差) 等评估模型在测试集上的预测准确性。
- 残差分析: 关键一步。理想的残差应该是:
- 白噪声 (White Noise): 均值为零,方差为常数,且相互之间没有相关性。这意味着模型已经捕捉了数据中所有的信息。
- 正态分布: 误差通常假定服从正态分布。
- 通过绘制残差图、残差ACF/PACF图、Q-Q图、进行Ljung-Box检验(白噪声检验)和Jarque-Bera检验(正态性检验)来诊断。
- 模型预测: 使用训练好的模型对未来进行预测。
- 模型部署与监控: 将模型投入实际使用,并持续监控其性能,及时更新。
2. 时序任务经典单变量数据集
这些数据集是时间序列分析的“Hello World”,它们通常具有明显的特征,适合作为教学和实验的素材:
- 航空旅客数据 (Air Passengers): 著名的月度数据集,特点是明显的上升趋势和年度季节性,方差也随时间增大。是SARIMA模型的典型应用案例。
- 太阳黑子数据 (Sunspots): 年度数据,呈现约11年的周期性。
- 强生公司季度收益 (Johnson & Johnson Quarterly Earnings): 季度数据,通常包含趋势和季节性。
- 股票收盘价/日交易量: 金融时间序列,波动性强,通常是非平稳的。
- 零售销售数据: 通常有季节性(节假日)、趋势(经济增长)和周期性(商业周期)。
3. ARIMA (p,d,q) 模型实战
ARIMA模型是AR(自回归)、I(差分)、MA(滑动平均)的结合。
- AR§:
p
是自回归阶数。表示当前值与前p
个历史值相关。例如,AR(1)
意味着 Y t = c + ϕ 1 Y t − 1 + ϵ t Y_t = c + \phi_1 Y_{t-1} + \epsilon_t Yt=c+ϕ1Yt−1+ϵt。 - I(d):
d
是差分阶数。表示需要对原始序列进行d
次差分才能使其平稳。例如,d=1
意味着我们分析的是 Y t − Y t − 1 Y_t - Y_{t-1} Yt−Yt−1 这个差分序列。 - MA(q):
q
是滑动平均阶数。表示当前值与前q
个历史预测误差相关。例如,MA(1)
意味着 Y t = c + θ 1 ϵ t − 1 + ϵ t Y_t = c + \theta_1 \epsilon_{t-1} + \epsilon_t Yt=c+θ1ϵt−1+ϵt。
模型表达式 (一阶差分,AR§, MA(q)):
( 1 − ∑ i = 1 p ϕ i L i ) ( 1 − L ) d y t = ( 1 + ∑ j = 1 q θ j L j ) ϵ t (1 - \sum_{i=1}^p \phi_i L^i) (1-L)^d y_t = (1 + \sum_{j=1}^q \theta_j L^j) \epsilon_t (1−i=1∑pϕiLi)(1−L)dyt=(1+j=1∑qθjLj)ϵt
其中, L L L 是滞后运算符( L y t = y t − 1 Ly_t = y_{t-1} Lyt=yt−1), ϕ \phi ϕ 是AR系数, θ \theta θ 是MA系数, ϵ t \epsilon_t ϵt 是白噪声误差。
4. SARIMA 摘要图的理解
当您使用statsmodels
库中的SARIMA(或现在更新的ARIMA
类,它同时支持ARIMA和SARIMA)模型进行训练后,model.fit().summary()
会输出一个摘要表,其中包含了大量诊断信息。理解这个摘要至关重要。
SARIMA(p,d,q)(P,D,Q)s:在ARIMA的基础上,增加了季节性参数。
(p,d,q)
: 非季节性部分。(P,D,Q)s
: 季节性部分。P
是季节性AR阶数,D
是季节性差分阶数,Q
是季节性MA阶数,s
是季节周期(例如,月度数据s=12,季度数据s=4)。
摘要表中的关键信息:
模型参数:
Model:
显示你建立的模型类型,例如SARIMAX(p, d, q)(P, D, Q)[s]
。Log Likelihood:
对数似然值,用于模型比较,越大越好。AIC, BIC, HQIC:
信息准则 (Akaike Information Criterion, Bayesian Information Criterion, Hannan-Quinn Information Criterion)。它们衡量模型拟合优度和模型复杂度的平衡。值越小越好。通常用于比较不同(p,d,q)
或(P,D,Q)
组合的模型优劣。No. Observations
,Covariance Type
,Date
,Time
等基本信息。
系数表 (Coefficients):
coef
: 对应参数的估计值(如ar.L1
、ma.L1
、ar.S.L12
、ma.S.L12
等)。std err
: 系数估计值的标准误差。z
: Wald检验的z统计量(coef / std err
)。P>|z|
: p值。这是最重要的部分之一。如果p值 < 0.05
(或您选择的显著性水平),则认为该系数是统计显著的,即它对模型有贡献。如果 p值很大,可能说明该参数是不必要的,可以尝试将其对应的阶数设为0。[0.025, 0.975]
: 系数的95%置信区间。如果这个区间不包含0,也说明该系数是显著的。
残差诊断 (Ljung-Box, Jarque-Bera, Hetereoscedasticity):
Ljung-Box (Q):
白噪声检验。- 原假设 (H0): 残差是白噪声(即残差之间没有相关性)。
- P-value (JB): 如果p值 > 0.05,我们接受原假设,认为残差是白噪声,模型拟合良好。如果p值 < 0.05,说明残差中仍存在模式,模型可能需要改进。
Jarque-Bera (JB):
正态性检验。- 原假设 (H0): 残差服从正态分布。
- P-value (JB): 如果p值 > 0.05,我们接受原假设,认为残差近似正态分布。
Skew
: 残差的偏度,衡量对称性。Kurtosis
: 残差的峰度,衡量尾部厚度。Heteroscedasticity (H):
异方差性检验。- 原假设 (H0): 残差方差是齐性的(常数)。
- P-value (H): 如果p值 > 0.05,接受原假设,残差方差恒定。
5. 处理不平稳的2种差分
平稳性是时间序列分析的基石。非平稳序列通过差分可以转化为平稳序列。
a. n阶差分 (Non-seasonal differencing):
- 定义: Y t ′ = Y t − Y t − d Y_t' = Y_t - Y_{t-d} Yt′=Yt−Yt−d。例如,一阶差分是 Y t − Y t − 1 Y_t - Y_{t-1} Yt−Yt−1。
- 目的: 主要用于去除趋势 (Trend)。如果序列有线性趋势,一阶差分通常可以去除;如果趋势更复杂(如二次趋势),可能需要二阶差分。
- 对应ARIMA中的
d
参数。
b. 季节性差分 (Seasonal differencing):
- 定义: Y t ′ ′ = Y t − Y t − s Y_t'' = Y_t - Y_{t-s} Yt′′=Yt−Yt−s,其中
s
是季节周期(例如,月度数据 s=12,季度数据 s=4)。 - 目的: 主要用于去除季节性 (Seasonality)。它通过减去去年同期的值来消除季节性模式。
- 通常在非季节性差分之后进行(即对差分后的序列再次进行季节性差分),或者直接对原始序列进行季节性差分(如果只有季节性而无明显趋势)。
- 对应SARIMA中的
D
参数。
- 定义: Y t ′ ′ = Y t − Y t − s Y_t'' = Y_t - Y_{t-s} Yt′′=Yt−Yt−s,其中
建立一个ARIMA模型实战 (Python 代码解释)
我们将使用经典的 “Air Passengers” 数据集来演示ARIMA模型的建立过程。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.seasonal import seasonal_decompose # 用于分解
from statsmodels.tsa.stattools import adfuller # ADF 平稳性检验
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf # 绘制ACF和PACF
from statsmodels.tsa.arima.model import ARIMA # ARIMA 模型
from sklearn.metrics import mean_squared_error, mean_absolute_error # 评估指标
from math import sqrt
import warnings
warnings.filterwarnings("ignore") # 忽略一些不必要的警告
# --- 1. 数据可视化 ---
print("--- 1. 数据可视化 ---")
# 加载数据
# 由于AirPassengers通常是作为内置数据集或csv文件提供,这里假设为csv文件
# 您可以从 statsmodels.datasets.airpassengers.load_pandas().data 获得
try:
df = pd.read_csv('AirPassengers.csv', index_col='Month', parse_dates=True)
except FileNotFoundError:
print("AirPassengers.csv 未找到,尝试使用内置数据集...")
from statsmodels.datasets import airpassengers
data = airpassengers.load_pandas().data
df = pd.DataFrame(data['value'])
df.index = pd.to_datetime(data['year_month'])
df.index.name = 'Month'
df.columns = ['Passengers'] # 重命名列
print("原始数据前5行:\n", df.head())
print("\n数据信息:\n", df.info())
plt.figure(figsize=(12, 6))
plt.plot(df)
plt.title('Air Passengers Original Series')
plt.xlabel('Date')
plt.ylabel('Passengers')
plt.grid(True)
plt.show()
# 观察:明显的上升趋势和年度季节性,且季节性波动幅度随时间增大(方差非恒定)。
# 这提示我们可能需要对数变换来稳定方差,然后进行差分。
# 为了简化,我们先不进行对数变换,直接差分。
# 如果方差变化显著,建议先进行对数变换:df['log_Passengers'] = np.log(df['Passengers'])
# 进一步分解观察趋势和季节性
decomposition = seasonal_decompose(df['Passengers'], model='additive', period=12) # 月度数据,周期为12
fig = decomposition.plot()
fig.set_size_inches(10, 8)
plt.tight_layout()
plt.show()
# --- 2. 平稳性检验 (ADF 检验) ---
print("\n--- 2. 平稳性检验 (ADF 检验) ---")
def adf_test(series, name='Original Series'):
"""进行ADF检验并打印结果"""
print(f"\n对 {name} 进行ADF检验:")
result = adfuller(series.dropna(), autolag='AIC')
print(f'ADF Statistic: {result[0]:.2f}')
print(f'p-value: {result[1]:.3f}')
print('Critical Values:')
for key, value in result[4].items():
print(f' {key}: {value:.2f}')
if result[1] <= 0.05:
print(f"结论: p-value ({result[1]:.3f}) <= 0.05,序列 {name} 是平稳的。")
else:
print(f"结论: p-value ({result[1]:.3f}) > 0.05,序列 {name} 是非平稳的,需要差分。")
adf_test(df['Passengers'], 'Original Passengers')
# --- 3. 确定差分次数 d ---
print("\n--- 3. 确定差分次数 d ---")
# 第一次差分 (去除趋势)
df_diff1 = df['Passengers'].diff(1).dropna()
plt.figure(figsize=(12, 4))
plt.plot(df_diff1)
plt.title('Air Passengers - 1st Order Differencing')
plt.xlabel('Date')
plt.ylabel('Differenced Passengers')
plt.grid(True)
plt.show()
adf_test(df_diff1, '1st Order Differencing')
# 观察:第一次差分后,趋势基本消除,但仍然有明显的季节性。
# 此时ADF检验可能仍然显示非平稳,因为季节性也是非平稳的一种形式。
# 对于Air Passengers,除了非季节性差分 (d),还需要季节性差分 (D)。
# 但这里我们主要演示ARIMA,所以先假设我们只需要非季节性差分来处理趋势。
# 如果ADF仍然不平稳,继续差分。
# 实际中,对于Air Passengers,通常需要进行 1 阶非季节性差分 (d=1) 和 1 阶季节性差分 (D=1, s=12)
# 为了演示ARIMA,我们假设经过1次差分后,我们主要关注非季节性部分的平稳性。
# 更好的方法是进行季节性差分后再进行非季节性差分,以获得更平稳的序列来确定p,q。
# 但为了严格遵循ARIMA的d,我们先只做非季节性差分。
# 通常,d=1或d=2就足够了。
# 确定d:这里我们可以看到1阶差分后,p值接近0.05,但仍受季节性影响。
# 如果我们只考虑非季节性ARIMA,通常d=1是处理线性趋势的常用选择。
# 实际应用中,d的确定也可以借助auto_arima库,它会自动寻找最佳d(和D)。
# --- 4. 确定 p 和 q ---
print("\n--- 4. 确定 p 和 q ---")
# 对差分后的序列(这里用1阶差分后的序列)绘制ACF和PACF图
# 因为Air Passengers有强季节性,即使1阶差分后,ACF/PACF在季节滞后(如12, 24)也会有显著峰值。
# 在确定非季节性p,q时,我们主要关注非季节性滞后。
# 为了更准确地确定p,q,我们通常会使用一个经过季节性差分后的序列(如果存在季节性)
# 比如 `df_diff12_1 = df['Passengers'].diff(12).diff(1).dropna()`
# 这里我们用 `df_diff1` 来演示,并解释其局限性。
plt.figure(figsize=(12, 6))
plt.subplot(211) # 2行1列第1个
plot_acf(df_diff1, lags=30, ax=plt.gca(), title='ACF of 1st Order Differenced Series')
plt.subplot(212) # 2行1列第2个
plot_pacf(df_diff1, lags=30, ax=plt.gca(), title='PACF of 1st Order Differenced Series')
plt.tight_layout()
plt.show()
# 规则 (昨天学习的规则):
# PACF 定 p: 偏自相关函数图在某个滞后阶数后突然截断或迅速衰减,那么该滞后阶数就是 p。
# ACF 定 q: 自相关函数图在某个滞后阶数后突然截断或迅速衰减,那么该滞后阶数就是 q。
# 对 `df_diff1` (1阶差分后的序列) 的观察:
# * PACF: 在滞后1处有显著的峰值,之后迅速衰减。这可能提示 p=1。
# * ACF: 在滞后1处有显著的峰值,之后衰减但并非截断。在滞后12处有显著峰值(季节性)。
# * 由于季节性的存在,确定非季节性p,q变得复杂。
# * **经验法则:**
# * PACF在`p`处截尾,ACF拖尾 -> AR(p)
# * ACF在`q`处截尾,PACF拖尾 -> MA(q)
# * ACF和PACF都拖尾 -> ARMA(p,q)
# * 根据Air Passengers的特性,通常`d=1`且`D=1, s=12`是比较合适的。
# * 我们暂时选择一个经典的ARIMA(p,d,q)组合来演示,比如 (1,1,1) 或 (2,1,2)。
# * **这里我们选择 `d=1` (根据ADF测试,虽然有季节性但已削弱趋势)**
# * **根据ACF/PACF图,我们初步猜测 `p=1` 或 `p=2`,`q=1` 或 `q=2`。**
# * **为了避免季节性混淆,实际通常用 `auto_arima` 来自动选择参数。**
# * 使用 `pmdarima` 库的 `auto_arima` 可以自动确定最优的 (p,d,q)(P,D,Q)s 参数。
# * 这里我们手动选择一组参数来演示 ARIMA。
# * 让我们尝试一个相对简单的 ARIMA(1,1,1) 作为初始模型。
# --- 5. 建立并训练ARIMA(p, d, q)模型 ---
print("\n--- 5. 建立并训练ARIMA(p, d, q)模型 ---")
# 定义训练集和测试集
train_size = int(len(df) * 0.8)
train_data, test_data = df[0:train_size], df[train_size:]
print(f"训练集大小: {len(train_data)}")
print(f"测试集大小: {len(test_data)}")
# 建立ARIMA模型 (选择 (1,1,1) 作为示例,d=1已在上面确定)
# statsmodels的ARIMA模型会自动处理差分
order = (1, 1, 1) # (p, d, q)
print(f"建立ARIMA模型,阶数: {order}")
model = ARIMA(train_data['Passengers'], order=order)
model_fit = model.fit()
# --- 6. 模型评估与诊断 ---
print("\n--- 6. 模型评估与诊断 ---")
print(model_fit.summary())
# a. AIC 用来对比不同模型选择,越小越好
# 在summary中查找AIC值。如果要比较不同 (p,d,q) 组合,可以训练多个模型,比较它们的AIC。
# b. 关注系数是否显著,通过p值或者置信区间均可
# 在summary的 "coef" 表格中,查看 `P>|z|` 列。
# 如果 `P>|z|` 小于 0.05(或0.1,取决于显著性水平),则该系数是统计显著的。
# 例如,如果 `ar.L1` 的p值很小,说明AR(1)项很重要。
# c. 残差的白噪声检验 + 正态分布检验
# 在summary的底部:
# * **Ljung-Box (Q):** 关注 `P-value (Q)`。如果它大于 0.05,则残差是白噪声。
# * **Jarque-Bera (JB):** 关注 `P-value (JB)`。如果它大于 0.05,则残差服从正态分布。
# 绘制残差图
print("\n--- 残差诊断图 ---")
model_fit.plot_diagnostics(figsize=(15, 10))
plt.tight_layout()
plt.show()
# 诊断图解读:
# * **Standardized Residuals:** 标准化残差图。理想情况是残差围绕0波动,无明显趋势、无明显模式、无异常大波动。如果出现趋势或模式,说明模型捕捉信息不足。
# * **Histogram plus kde estimate:** 残差的直方图和核密度估计。理想情况是近似正态分布,均值在0附近。
# * **Normal Q-Q:** Q-Q图。理想情况是点沿着45度直线分布。如果点偏离直线,表示残差不服从正态分布。
# * **Correlogram (ACF):** 残差的ACF图。理想情况是所有滞后的自相关系数都在置信区间内(即不显著),这表示残差是白噪声,模型已充分提取信息。如果仍有显著的峰值,说明残差中仍有自相关性,模型需要改进(如增加p,q阶数或考虑季节性参数)。
# 对于Air Passengers,ARIMA(1,1,1)可能不足以完全处理季节性,残差的ACF图很可能在滞后12处仍有显著峰值。
# 这再次提示我们需要SARIMA模型。
# --- 7. 进行预测 (需要还原回差分前的结构) ---
print("\n--- 7. 进行预测 ---")
# 预测测试集数据
# statsmodels的predict/forecast方法会自动处理差分还原
start_index = len(train_data)
end_index = len(df) - 1
# forecast = model_fit.predict(start=start_index, end=end_index, dynamic=False) # dynamic=False 表示使用所有历史数据进行一步预测
forecast = model_fit.forecast(steps=len(test_data)) # forecast更适合多步预测
# 将预测结果转换为Series,并匹配测试集的索引
forecast_series = pd.Series(forecast, index=test_data.index)
# 绘制结果
plt.figure(figsize=(12, 6))
plt.plot(train_data['Passengers'], label='Training Data')
plt.plot(test_data['Passengers'], label='Actual Test Data')
plt.plot(forecast_series, label='ARIMA Forecast')
plt.title(f'Air Passengers ARIMA({order}) Forecast vs Actual')
plt.xlabel('Date')
plt.ylabel('Passengers')
plt.legend()
plt.grid(True)
plt.show()
# 计算评估指标
rmse = sqrt(mean_squared_error(test_data['Passengers'], forecast_series))
mae = mean_absolute_error(test_data['Passengers'], forecast_series)
print(f'RMSE: {rmse:.2f}')
print(f'MAE: {mae:.2f}')
# 进一步预测未来 N 个月
future_steps = 12 # 预测未来12个月
future_forecast = model_fit.forecast(steps=future_steps)
# 创建未来时间的索引
last_date = df.index[-1]
future_dates = pd.date_range(start=last_date, periods=future_steps + 1, freq='MS')[1:] # MS = Month Start
future_forecast_series = pd.Series(future_forecast, index=future_dates)
plt.figure(figsize=(12, 6))
plt.plot(df['Passengers'], label='Historical Data')
plt.plot(future_forecast_series, label='Future Forecast')
plt.title(f'Air Passengers ARIMA({order}) Future Forecast')
plt.xlabel('Date')
plt.ylabel('Passengers')
plt.legend()
plt.grid(True)
plt.show()
print("\n--- 预测结果 ---")
print(future_forecast_series)
代码解释和关键点总结:
数据加载与可视化 (步骤1):
- 使用
pandas.read_csv
加载数据,index_col
指定时间列,parse_dates=True
将其解析为日期时间对象,这对于时间序列非常重要。 df.plot()
快速查看数据走势。seasonal_decompose
用于将序列分解为趋势、季节性和残差,帮助我们直观理解数据结构。period=12
因为是月度数据,季节周期为12个月。
- 使用
平稳性检验 (步骤2):
statsmodels.tsa.stattools.adfuller
执行ADF检验。p-value <= 0.05
是判断序列平稳性的常用阈值。如果p值大于此,说明序列非平稳。
确定差分次数 d (步骤3):
df['Passengers'].diff(1)
进行一阶差分,dropna()
去除差分后产生的NaN
值。- 每次差分后,重新绘制图并进行ADF检验,直到序列平稳。
- 重要提示: Air Passengers数据具有强季节性。即使一阶非季节性差分,ADF检验可能仍然显示不平稳,因为季节性部分未被消除。严格来说,对于这类数据,应使用SARIMA,它会包含季节性差分
D
。但本例为演示ARIMA,我们假设d=1
足以处理趋势。
确定 p 和 q (步骤4):
statsmodels.graphics.tsaplots.plot_acf
和plot_pacf
绘制自相关和偏自相关图。- 判断方法:
- PACF (定 p): 如果PACF图在某个滞后处突然截断(迅速下降到零线以下),则这个滞后值就是AR的阶数
p
。 - ACF (定 q): 如果ACF图在某个滞后处突然截断,则这个滞后值就是MA的阶数
q
。 - 拖尾: 如果ACF/PACF逐渐衰减而不是突然截断,则称为拖尾。
- PACF (定 p): 如果PACF图在某个滞后处突然截断(迅速下降到零线以下),则这个滞后值就是AR的阶数
- 对于Air Passengers,其差分序列的ACF/PACF会显示季节性滞后(如12, 24)上的显著峰值,这进一步强调了SARIMA的必要性。在没有
auto_arima
的帮助下,手动选择p,q
需要经验和多次尝试。
建立并训练ARIMA模型 (步骤5):
statsmodels.tsa.arima.model.ARIMA
是最新推荐的模型类,它统一了ARIMA和SARIMA。order=(p,d,q)
指定模型的非季节性参数。model.fit()
训练模型。
模型评估与诊断 (步骤6):
model_fit.summary()
输出模型的详细报告,这是模型诊断的核心。- AIC/BIC: 越小越好,用于比较不同模型的拟合优度。
- P>|z|: 参数的p值。小于0.05通常认为参数显著。
- Ljung-Box (Q): 残差白噪声检验。
P-value (Q)
大于0.05表示残差是白噪声,模型拟合较好。 - Jarque-Bera (JB): 残差正态性检验。
P-value (JB)
大于0.05表示残差近似正态分布。
model_fit.plot_diagnostics()
提供四个有用的诊断图,直观检查残差的特性。
进行预测 (步骤7):
model_fit.forecast(steps=N)
用于进行未来N
步的预测。这个方法会自动将差分还原,输出原始尺度的预测值。model_fit.predict(start=..., end=..., dynamic=False)
可以用于in-sample(训练集内)或out-of-sample(测试集内)的预测。dynamic=False
意味着在预测每一步时都使用所有可用的历史数据(包括实际值),而dynamic=True
则表示从某个点开始,只使用模型自身的预测值作为输入。- 将预测结果与真实值进行可视化对比,并计算RMSE和MAE等评估指标,以量化预测准确性。
ARIMA模型的局限性与SARIMA的引入:
通过Air Passengers的例子,我们可以明显看到,即使建立了ARIMA模型,由于数据强烈的季节性,模型可能仍然不能完美捕捉所有模式(如残差ACF图中季节性滞后处的显著性)。这时,就需要引入SARIMA模型,它在ARIMA的基础上加入了季节性差分和季节性AR/MA项,能够更好地处理具有季节性特征的时间序列。