29.7 ARIMA模型预测
ARMA(自回归滑动平均模型)和 ARIMA(自回归积分滑动平均模型)是用于时间序列预测的统计模型。ARMA 通过使用过去值的线性组合来分析时间序列,而 ARIMA 则通过对过去值进行差分处理,以去除趋势或季节性成分,从而进行预测。
29.7.1 ARIMA介绍
ARIMA是一种用于时间序列预测的统计模型,此模型结合了自回归(AR)、积分(I)和滑动平均(MA)三种成分,以适应各种时间序列数据的特性。ARIMA 模型的关键组成部分及其功能如下所示:
- 自回归(AR)成分:自回归成分表示当前值与过去值的线性关系,利用过去值的加权平均来预测未来值。AR 成分的阶数用 𝑝表示,表示使用多少个滞后值来进行预测。
- 积分(I)成分:积分成分用于处理时间序列中的趋势,使其变得平稳。通过对时间序列进行差分处理,以去除趋势或季节性成分,使序列平稳。I 成分的阶数用 𝑑表示,表示需要进行多少次差分操作以使序列平稳。
- 滑动平均(MA)成分:滑动平均成分表示当前值与过去误差的线性关系,它使用过去预测误差的加权平均来改善预测。MA 成分的阶数用 𝑞表示,表示使用多少个滞后误差值来进行预测。
ARIMA 模型通常表示为:
ARIMA(𝑝,𝑑,𝑞)
其中:
29.7.2 平稳性检查
平稳性检查是一种测试时间序列数据是否平稳的方法。通常通过绘制数据图表来检查是否存在明显的趋势或季节性,从而判断平稳性。平稳性可以通过观察数据的均值、方差和自相关性来确定。如果时间序列是平稳的,则均值、方差和自相关性应保持恒定。如果均值、方差或自相关性随时间变化,则时间序列是非平稳的。
(1)导入一些用于时间序列分析和建模的 Python 库及其函数。
import statsmodels.tsa.stattools as ts
import statsmodels.api as sm
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.graphics.tsaplots import plot_acf
from statsmodels.graphics.tsaplots import plot_pacf
from sklearn.metrics import mean_squared_error
(2)下面代码用于检查数据框中前四列时间序列数据的平稳性。通过应用ADF(Augmented Dickey-Fuller)检验,打印输出每列的ADF统计量、p值以及临界值,并根据p值判断每列数据是否平稳。如果p值小于或等于0.05,则认为数据是平稳的,否则认为数据是非平稳的。
for i in df.columns[:4]:
# 检查数据的平稳性
result = ts.adfuller(df[i])
# 打印检验结果
print('ADF 统计量: %f' % result[0])
print('p 值: %f' % result[1])
print('临界值:')
for key, value in result[4].items():
print('\t%s: %.3f' % (key, value))
# 解释检验结果
if result[1] <= 0.05:
print(i, '是平稳的')
else:
print(i, '不是平稳的')
print(' ')
执行后会输出:
ADF Statistic: -0.197822
p-value: 0.938781
Critical Values:
1%: -3.432
5%: -2.862
10%: -2.567
Open is not stationary
ADF Statistic: -0.080000
p-value: 0.951395
Critical Values:
1%: -3.432
5%: -2.862
10%: -2.567
High is not stationary
ADF Statistic: -0.202130
p-value: 0.938267
Critical Values:
1%: -3.432
5%: -2.862
10%: -2.567
Low is not stationary
ADF Statistic: -0.087651
p-value: 0.950655
Critical Values:
1%: -3.432
5%: -2.862
10%: -2.567
Close is not stationary
29.7.3 季节性分解
季节性分解是一种分析时间序列数据的方法,将数据分解为趋势、季节性成分和残差三部分。趋势反映了数据的长期变化,季节性成分表示定期重复的模式,而残差则是数据中无法通过趋势和季节性解释的随机波动。通过季节性分解,可以更好地理解数据的结构,识别隐藏的模式,从而用于预测和决策。
在本项目中,通过下面的代码对 df 数据框的前四列进行季节性分解。季节性分解的结果包括趋势、季节性成分和残差。在代码中循环遍历每个变量,并生成相应的可视化图表来可视化这些分解成分。每个变量的分解结果展示为三个子图,分别表示趋势、季节性成分和残差。在图表美化方面,代码隐藏了图表的右侧和顶部边框,并设置了自定义的颜色、标题、坐标标签和旋转的 x 轴标签。
# 为每个变量生成图表的颜色
colors = plt.rcParams["axes.prop_cycle"]()
# 对 df 数据框的前四列进行循环处理
for j in df.columns[:4]:
# 对变量进行季节性分解,周期设置为365天
results = seasonal_decompose(df[j], period=365)
trend = results.trend # 提取趋势成分
seasonal = results.seasonal # 提取季节性成分
residual = results.resid # 提取残差
properties = [trend, seasonal, residual] # 存储所有成分
a = 1 # 行数
b = 3 # 列数
c = 1 # 初始化子图计数器
# 设置图表尺寸和标题
fig = plt.figure(figsize=(18, 4))
fig.suptitle(f'Seasonal Decomposition of {j} Variable', fontsize=20)
# 循环遍历每个成分(趋势、季节性、残差)并绘制图表
for i in properties:
color = next(colors)["color"] # 为每个成分设置不同的颜色
plt.subplot(a, b, c) # 创建子图
plt.plot(i, color=color) # 绘制成分曲线
plt.gca().spines['right'].set_visible(False) # 隐藏图表右侧边框
plt.gca().spines['top'].set_visible(False) # 隐藏图表顶部边框
plt.xlabel(' Years') # 设置 x 轴标签
plt.ylabel(i.name) # 设置 y 轴标签
plt.xticks(rotation=45) # 旋转 x 轴刻度标签
c = c + 1 # 子图计数器自增
plt.tight_layout() # 自动调整子图之间的间距
plt.show() # 显示图表
上述代码可视化了数据的季节性分解成分,有助于分析变量的长期趋势、季节性波动及其随机残差。执行效果如图29-19所示,
图29-19 季节性分解图