(29-5-03)通过回测、ARIMA 和 GRU 预测股票价格:ARIMA模型预测(3)

29.7.7  自回归模型

自回归(AR)模型是一种用于时间序列分析的统计模型,通过利用过去的观测值来预测未来的值。自回归(AR)模型是一种回归分析,其中输出变量(Y)被建模为其自身过去值的线性函数加上一个噪声项(epsilon)。AR模型用于描述和分析时间相关的现象,如股票价格、经济周期和生态现象。

在本项目中,通过下面的代码绘制自相关函数(ACF)和偏自相关函数(PACF)的可视化图表,以帮助确定时间序列数据中的自回归(AR)和移动平均(MA)模型的阶数。

fig, (ax1, ax2, ax3) = plt.subplots(3, figsize=(15, 10))

# 绘制原始序列的偏自相关函数图
plot_pacf(df.High, auto_ylims=True, lags=5, ax=ax1, title='Original Series')
ax1.spines['top'].set_visible(False)

# 绘制一次差分序列的偏自相关函数图
plot_pacf(df.High.diff().dropna(), auto_ylims=True, lags=5, ax=ax2, title='1st Order Differencing')
ax2.spines['top'].set_visible(False)

# 绘制二次差分序列的偏自相关函数图
plot_pacf(df.High.diff().diff().dropna(), auto_ylims=True, lags=5, ax=ax3, title='2nd Order Differencing')
ax3.spines['top'].set_visible(False)

plt.tight_layout()
plt.show()

执行效果如图29-21所示,绘制了原始序列、一次差分序列和二次差分序列的PACF图,并设置了图表的样式以增强可读性。

图29-21  自相关函数(ACF)和偏自相关函数(PACF)的可视化图

此时可以在ACF和PACF图中观察到明显的截止点,或当滞后的相关值降到某个阈值以下时,停止寻找p和q值。这通常表示数据的模式已经被捕捉,添加更多的滞后值不会提供额外的信息。

注意:为什么ARIMA比ARMA更好?

在技术上,我们可以使用ARMA模型,但ARIMA(自回归积分滑动平均)模型比ARMA模型更好,具体原因如下:

  1. 更灵活:ARIMA模型能够处理非平稳数据,而ARMA模型无法做到这一点。
  2. 差分处理:ARIMA模型可以使用差分来去除趋势和季节性,而ARMA模型无法做到这一点。
  3. 季节性成分:ARIMA模型还允许在模型中包含季节性成分,而ARMA模型无法做到这一点。

29.7.8  数据分割

在拟合模型之前需要对数据进行分割,时间序列数据的分割方法与典型的机器学习算法数据集分割有所不同。由于时间序列具有顺序性,我们不希望模型学习到由于随机分割而产生的空隙,因此我们将基于年份进行数据分割。

(1)在本项目中,选择了2020年之前的数据作为训练数据,剩余的数据用于测试工作。

train = df[df.index.year<2020]
test = df[df.index.year>=2020]

(2)下面代码绘制了训练集和测试集的“High”列数据,并通过一个垂直虚线来标识训练集和测试集的分界点。

# 创建一个图形和一个轴
fig, ax = plt.subplots()

# 在轴上绘制训练集的High列数据
train['High'].plot(ax=ax, label='Training Set', title='Data Train/Test Split', linewidth=3)

# 在轴上绘制测试集的High列数据
test['High'].plot(ax=ax, label='Test Set',  linewidth=3)

# 移除图表的顶部和右边的边框
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False);

# 在图表上添加一个垂直线,表示分界点
ax.axvline('2020-01-01', color='black', ls='--', lw=2)

# 添加图例
ax.legend(['Training Set', 'Test Set'])

# 标记x轴
ax.set_xlabel('Years')

# 显示图表
plt.show()

执行后绘制了一个时间序列图,显示了训练集和测试集的“High”列数据,执行效果如图29-22所示。展示了训练集和测试集的线条,移除了图表的上边框和右边框,并在图表上添加了图例和x轴标签,最后展示了图表。

图29-22  时间序列图

(3)通过下面的代码打印输出了训练集和测试集的行数,这可以帮助确认数据集的分割情况以及确保数据被正确地划分为训练集和测试集。

print(f'There are {train.shape[0]} rows in the training set and {test.shape[0]} rows in the test set')

执行后会输出:

There are 3867 rows in the training set and 770 rows in the test set

(4)下面这段代码的功能是选择数据集中用于训练和测试的特征列,并查看训练集的前几行数据。具体步骤如下:

  1. 定义外生特征(exogenous_features),即用于模型的额外特征列,包括 'Open'、'High' 和 'Low'。
  2. 从训练集 (train) 和测试集 (test) 中选择前四列作为分析数据列。
  3. 显示训练集的前几行数据,以检查数据的格式和内容。
# 选择用于模型的外生特征
exogenous_features = ['Open', 'High', 'Low']

# 从训练集和测试集中选择前四列
train = train[train.columns[:4]]
test = test[test.columns[:4]]

# 显示训练集的前几行数据
train.head()

执行后会输出:

Date	              Open	High	Low	      Close			
2004-08-23 00:00:00-04:00	2.527778	2.729730	2.515015	2.710460
2004-08-24 00:00:00-04:00	2.771522	2.839840	2.728979	2.737738
2004-08-25 00:00:00-04:00	2.783784	2.792793	2.591842	2.624374
2004-08-26 00:00:00-04:00	2.626627	2.702703	2.599600	2.652653
2004-08-27 00:00:00-04:00	2.626376	2.701451	2.619119	2.700450

(5)下面代码的功能是使用 ARIMA 模型拟合训练数据,具体实现步骤如下:

  1. 忽略警告信息:使用 warnings.filterwarnings('ignore') 来忽略警告信息,避免干扰输出。
  2. 定义并拟合 ARIMA 模型:创建一个 ARIMA 模型实例,指定自变量(endog)为训练集的 'Close' 列,外生变量(exog)为定义的外生特征列('Open'、'High' 和 'Low'),并设置 ARIMA 模型的参数为 (1, 1, 1),即 p=1,d=1,q=1。
  3. 查看模型摘要:使用 model_fit.summary() 输出模型的详细拟合结果。
import warnings 
warnings.filterwarnings('ignore')

# 创建并拟合 ARIMA 模型
model = sm.tsa.arima.ARIMA(endog=train['Close'], exog=train[exogenous_features], order=(1, 1, 1))  #(p,d,q)
model_fit = model.fit()

# 输出模型摘要
model_fit.summary()

执行后会输出:

SARIMAX Results
Dep. Variable:	Close	No. Observations:	3867
Model:	ARIMA(1, 1, 1)	Log Likelihood	1770.361
Date:	Mon, 23 Jan 2023	AIC	-3528.722
Time:	21:35:07	BIC	-3491.163
Sample:	0	HQIC	-3515.385
- 3867		
Covariance Type:	opg		
coef	std err	z	P>|z|	[0.025	0.975]
Open	-0.5615	0.006	-96.368	0.000	-0.573	-0.550
High	0.7750	0.005	150.396	0.000	0.765	0.785
Low	0.7870	0.005	166.993	0.000	0.778	0.796
ar.L1	-0.0658	0.008	-7.778	0.000	-0.082	-0.049
ma.L1	-0.9998	0.003	-307.385	0.000	-1.006	-0.993
sigma2	0.0234	0.000	89.339	0.000	0.023	0.024
Ljung-Box (L1) (Q):	0.19	Jarque-Bera (JB):	9485.55
Prob(Q):	0.67	Prob(JB):	0.00
Heteroskedasticity (H):	8.22	Skew:	0.10
Prob(H) (two-sided):	0.00	Kurtosis:	10.67

现在模型已经训练完成,我们可以开始在训练数据上进行预测,随后在测试数据上进行预测。

(6)下面代码的功能是对训练集数据进行预测,并将实际的“Close”值与预测值绘制在同一图上,以便可视化模型在训练集上的表现。

# 在训练集中添加预测结果
train['Predictions'] = model_fit.predict()

# 绘制实际值与预测值的最后50行数据
train[['Close', 'Predictions']][-50:].plot()
plt.title('Predictions on Training Set')  # 标题:训练集上的预测
plt.gca().spines['right'].set_visible(False)  # 隐藏右侧边框
plt.gca().spines['top'].set_visible(False)  # 隐藏顶部边框
plt.show()

上述代码的实现步骤包括:将预测结果添加到训练集中,绘制实际值和预测值的最后50行数据,并显示可视化图表,执行效果如图29-23所示。在图中显示了训练集数据中“Close”列的实际值与模型预测的“Predictions”值的对比。图表展示了这两个系列的最后50个数据点,以便比较实际值与预测值的差异。

图29-23  训练集上的预测图

(7)下面代码用于在测试集上进行预测,利用已经训练好的 ARIMA 模型对测试集进行逐步预测,并将预测结果存储在“Forecast”列中。然后,通过可视化图表展示了测试集中“Close”列的实际值与预测的“Forecast”值的对比,展示了最后50个数据点,以便进行可视化比较。

# 在测试集上进行预测
forecast = [model_fit.forecast(exog=test[exogenous_features].iloc[i]).values[0] for i in range(len(test))]
test['Forecast'] = forecast
test[['Close','Forecast']][-50:].plot()
plt.title('预测在测试集上')
plt.gca().spines['right'].set_visible(False)
plt.gca().spines['top'].set_visible(False)
plt.show()

执行效果如图29-24所示。

图29-24  测试集上的预测图

(8)计算多变量 ARIMAX 模型的均方根误差(RMSE),用于评估模型在测试集上的预测性能。通过计算预测值与实际值之间的均方根误差,提供了模型预测准确度的量化指标,并将结果打印出来。

rmse = np.sqrt(mean_squared_error(test['Close'],test['Forecast']))
print(f'The RMSE for Multivariate ARIMAX is {round(rmse,4)}')

执行后会输出:

The RMSE for Multivariate ARIMAX is 0.7477

(9)下面的test 是一个数据框(DataFrame),通过test存储模型在测试集上的预测结果和实际值。

test

执行后会输出:

                        Open	High	 Low	      Close	      Forecast
Date					
2020-01-02 00:00:00-05:00	66.789497	67.032997	66.606499	66.969498	66.876931
2020-01-03 00:00:00-05:00	67.420502	68.433998	67.324501	68.433998	68.173472
2020-01-06 00:00:00-05:00	67.400002	68.687500	67.365997	68.075996	68.414108
2020-01-07 00:00:00-05:00	67.581497	69.916000	67.550003	69.890503	69.409122
2020-01-08 00:00:00-05:00	70.023003	70.175003	69.578003	69.755501	69.834908
...	...	...	...	...	...
2023-01-17 00:00:00-05:00	90.849998	92.190002	90.129997	92.120003	91.376339
2023-01-18 00:00:00-05:00	92.059998	92.250000	90.050003	91.290001	90.680473
2023-01-19 00:00:00-05:00	92.139999	92.800003	90.639999	91.120003	91.526122
2023-01-20 00:00:00-05:00	90.720001	93.610001	90.629997	93.050003	92.943345
2023-01-23 00:00:00-05:00	95.099998	98.300003	95.019997	98.019997	97.573603

这样,我们就完成了使用 ARIMA 模型的预测工作。接下来,将使用深度学习来预测股票价格。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

感谢鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值