第四十三周:文献阅读+ARIMA时间序列模型

目录

摘要

Abstract

文献阅读:基于ARIMA-LSTM混合模型的股价相关系数预测

现有问题

提出方法

方法论

ARIMA模型部分

LSTM模型部分

ARIMA-LSTM混合模型

研究实验

研究目的

数据集

评价指标

结果与评价

模型代码

ARIMA时间序列模型

前言

1、时间序列的表达

2、时间序列的特征

基本流程

1、平稳性检验

2、白噪声检验

3、模型定阶

4、模型检验

总结


摘要

本周阅读的文献《Stock Price Correlation Coefficient Prediction with ARIMA-LSTM Hybrid Model》中,提出了一个ARIMA和神经网络LSTM的混合模型,用以预测两支股的股价相关系数。其中ARIMA模型能够过滤数据中的线性趋势,LSTM能够进一步增强了其长期预测特性,因此该混合模型可以同时捕获线性和非线性特性,具有多功能预测潜力。ARIMA时序模型建模过程中,首先要对数据进行平稳性检验,通过差分将数据转变为平稳数据,判断使用AR、MA、ARMA中哪种模型并进行定阶,检验得到模型后进行预测。

Abstract

The literature "Stock Price Correlation Coefficient Prediction with ARIMA-LSTM Hybrid Model" read this week, proposes a hybrid model of ARIMA and neural network LSTM to predict the stock price correlation coefficients of two stocks. The ARIMA model can filter linear trends in the data, while LSTM can further enhance its long-term prediction characteristics. Therefore, this hybrid model can capture both linear and nonlinear characteristics simultaneously, and has the potential for multifunctional prediction. In the process of modeling the ARIMA time series model, the first step is to perform a stationarity test on the data. The data is transformed into stationary data through differentiation, and the order of which model to use from AR, MA, and ARMA is determined. After testing the model, the prediction is made.

文献阅读:基于ARIMA-LSTM混合模型的股价相关系数预测

Stock Price Correlation Coefficient Prediction with ARIMA-LSTM Hybrid Modelicon-default.png?t=N7T8https://arxiv.org/pdf/1808.01560v5.pdf

现有问题

  1. 虽然已经有许多金融和统计方法来估计未来的相关性,但很少有人使用神经网络来执行这项任务。
  2. 常用模型,例如Full history模型、Constant Correlation模型和Single-Index模型,以及MultiGroup模型,用于相关预测的不精确性已经在很大程度上得到了承认。
  3. 神经网络经常被用来预测未来的股票收益,并产生了显著的结果。

提出方法

鉴于股票相关数据也可以表示为时间序列数据,提出了一个ARIMA和神经网络LSTM的混合模型来预测两支股的股价相关系数,该方法不是通过预测单个资产的收益来计算相关系数,而是直接对相关系数本身的值进行预测。

应用LSTM来预测两只个股的股价相关系数,LSTM细胞的使用进一步增强了其长期预测特性。为了在模型中同时包含线性和非线性,同时采用了ARIMA模型,ARIMA模型过滤数据中的线性趋势,并将残差值传递给LSTM模型。该方法只关注混合模型的多功能预测潜力,以捕获线性和非线性。

方法论

ARIMA模型部分

ARIMA模型本质上是一种线性回归模型,用于跟踪平稳时间序列数据的线性趋势。模型表示为ARIMA(p,d,q)。参数p、d、q为整数值,决定了时间序列模型的结构。其中参数p、q分别为AR模型和MA模型的阶数,参数d为应用于数据的差分水平。阶(p,q)的ARMA模型的数学表示如下

\hat{x}_{t}=c+\sum_{k=1}^{p}\phi _{k}x_{t-k}-\sum_{l=1}^{q}\theta _{k}\varepsilon_{t-l}

使用标准化的方法来构建ARIMA模型,该方法包括三个迭代步骤:

  1. 模型识别与模型选择确定模型的类型,是AR(p)还是MA(q),还是ARMA(p,q)。
  2. 参数估计对模型参数进行调整以优化模型。
  3. 对模型进行检验残差分析,使模型更加完善。

LSTM模型部分

RNN是一种有效处理时间序列数据的序列模型。它取时间序列数据的向量序列作为输入X=[x_{1},x_{2},...,x_{t}]  ,并输出由模型单元中的神经网络结构计算得到的向量值,在图中表示为A。向量X是一个跨越t个时间段的时间序列数据,向量X中的值依次通过单元格A。每个时间步骤,单元格输出一个值,该值与下一个时间步骤数据和单元格状态C相连接。输出值和C作为下一个时间步骤的输入。该过程一直重复到最后一个时间步长数据。然后,启动时间反向传播(BPTT)过程,其中权重矩阵被更新。

本模型采用的LSTM单元由四个交互神经网络组成,每个网络分别代表遗忘门、输入门、输入候选门和输出门。

  • 遗忘门输出一个元素值在0到1之间的向量。它作为一个遗忘器,从前一个时间步长乘到单元状态Ct - 1,以删除不需要的值,并保留预测所需的值。
  • 在下一个阶段中,输入门和候选输入门一起工作以呈现新的细胞状态Ct,这将作为更新的细胞状态传递到下一个时间步骤。输入门使用s形作为激活函数,候选输入使用双曲正切,每个输出它和C~ t。它选择C~中的哪个特征应该反映到新的细胞状态Ct中。
  • 最后,输出门决定选择什么值,将其与tanh施加的状态Ct结合作为输出ht。新的细胞状态是应用遗忘门的前细胞状态Ct−1和新的tanh应用状态Ct的组合。
  • 细胞状态Ct和输出ht将传递到下一个时间步,并将经历相同的过程。根据任务的不同,可以将Softmax或双曲正切等进一步的激活函数应用于这些函数。

在本论文中,这是一个输出值在-1和1之间的回归任务,我们将双曲正切函数应用于数据向量x的最后一个元素的输出。

ARIMA-LSTM混合模型中的LSTM模型架构是一个使用25个LSTM单元的RNN神经网络。将25个LSTM单元的最后输出合并为一个具有全连通层的单个值。然后,该值将通过双双曲正切激活函数传递,以输出单个最终预测。双曲正切就是双曲正切函数乘以2的倍数。下图显示了模型的简化架构。 

ARIMA-LSTM混合模型

假设时间序列数据由线性部分和非线性部分组成,因此可以表示如下:

x_{t}=L_{t}+N_{t}+\varepsilon _{t}

自回归综合移动平均(ARIMA)模型是一种用于时间序列预测的传统统计模型,该模型在线性问题上表现良好。另一方面,长短期记忆(LSTM)模型可以捕捉数据集中的非线性趋势。因此,将两个模型连续组合在一起,以同时包含模型中的线性和非线性趋势。采用ARIMA-LSTM混合模型,在第一阶段,ARIMA模型捕捉时间序列数据中的线性趋势,先在ARIMA建模步骤中滤除线性。然后,LSTM模型试图捕捉残差值中的非线性,残差值是前一阶段的输出。,

研究实验

研究目的

将ARIMA-LSTM混合模型与全历史模型、恒相关模型、单指标模型和多组模型等传统预测金融模型进行了对比检验。证明ARIMA-LSTM模型的预测能力显著优于其他所有金融模型。

数据集

ARIMA模型的数据集利用标准普尔500公司调整后的收盘价中完全输入的150组价格数据,以100天的时间窗口计算每对资产的相关系数。为了增加多样性,设置了五个不同的起始值,第1、21、41、61和81天,每个应用滚动的100天窗口,间隔100天,直到数据集结束。该过程呈现55875组时间序列数据,每组24个时间步长。最后,我们用55875 × 24的数据生成训练、开发和测试数据集。

LSTM模型的数据集使用从ARIMA模型中得到的150只随机选择的标准普尔500指数股票的残值作为LSTM模型的输入。数据集包括训练X/Y、开发X/Y、测试1 X/Y和测试2 X/Y。每个X数据集有55875行,20个时间步,每个时间序列对应一个Y数据集(如上图所示)。数据点一般在0左右,因为输入是残差数据集。

评价指标

均方误差(MSE)、平均绝对误差(MAE)和均方根误差(RMSE)

结果与评价

将ARIMA-LSTM混合模型与全历史模型、恒相关模型、单指标模型和多组模型等传统预测金融模型进行了对比检验,计算预测的MSE、RMSE和MAE值。在development、test1和test2数据集上的MSE值分别为0.1786、0.1889和0.2154。数值变化较小,说明模型得到了充分的推广。

在我们的实证研究中,型。本文的研究表明,ARIMA-LSTM模型可以用于投资组合优化的相关系数预测,并且ARIMA-LSTM模型的预测能力显著优于其他所有金融模。模型的性能在不同的时间段和不同的资产组合上进行了验证,这些资产组合具有不同的指标,如MSE、RMSE和MAE。这些值几乎是常数相关模型的一半,在我们的实验中,常数相关模型在四种金融模型中表现最好。从这种优异的表现来看,我们可以认为ARIMA-LSTM混合模型具有足够的预测潜力。因此,ARIMA-LSTM模型作为投资组合优化的相关系数预测器将是相当重要的。

模型代码

ARIMA模型

  1. 通过差分变换,先将非平稳数据变得平稳,之后再用ARMA模型处理平稳数据;
  2. 根据ACF图和PACF图判断使用AR、MA、ARMA中哪种模型;
  3. 判断p,q阶数是多少
  4. 可能ARMA有多个p,q决定的模型,通过信息标准AIC和BIC来协助选择模型选择AIC、BIC值最小的,因为AIC、BIC越小,模型越好
  5. 参数估计对模型参数进行调整以优化模型
train = pd.read_csv('C:/Users/Froilan/Desktop/myFiles/JupyterFiles/stock_correlation_prediction/train_dev_test/before_arima/train.csv')
train = np.transpose(train.loc[:, ~train.columns.str.contains('^Unnamed')])
for _ in range(100):
    randint = random.randrange(0,55875,1)
    train[randint].plot()
    plt.show()
    plt.close()
#对于非平稳序列,如果先进行差分后的结果不满足要求,则需要在原有基础上继续进行差分,直到差分后的结果属于平稳性序列
#方法:差分变换diff(),做一阶差分
    plot_acf(train[randint].diff()[1:])
    plt.show()
    plt.close()
    plot_pacf(train[randint].diff()[1:])
    plt.show()
    plt.close()
    

平稳的序列的ACF图和PACF图不是拖尾就是截尾。如下图,大多数数据集显示出一种振荡趋势,似乎接近于白噪声。其他值得注意的趋势包括增加/减少趋势,稳定相关系数时偶尔出现大的下降,以及混合振荡-稳定周期。蓝色区域是置信区间,p的值就是ACF第一次穿过上置信区间时的横轴值。q的值就是PACF第一次穿过上置信区间的横轴值。虽然ACF/PACF图表明大部分数据集接近白噪声,但几个阶(p, d, q) =(1,1,0),(0,1,1),(1,1,1),(2,1,1),(2,1,0)适用。

#用得到的五组参数(p, d, q) =(1,1,0),(0,1,1),(1,1,1),(2,1,1),(2,1,0)分别创建五个模型
#method='mle':使用极大似然估计
#suppress_warnings:是否过滤掉警告
model_110 = ARIMA(order=(1,1,0), method='mle', suppress_warnings=True)
model_011 = ARIMA(order=(0,1,1), method='mle', suppress_warnings=True)
model_111 = ARIMA(order=(1,1,1), method='mle', suppress_warnings=True)
model_211 = ARIMA(order=(2,1,1), method='mle', suppress_warnings=True)
model_210 = ARIMA(order=(2,1,0), method='mle', suppress_warnings=True)

train_X = []; train_Y = []
dev_X = []; dev_Y = []
test1_X = []; test1_Y = []
test2_X = []; test2_Y = []

flag = 0
#可能ARMA有多个p,q决定的模型
#通过信息标准AIC和BIC来协助选择模型选择AIC、BIC值最小的,因为AIC、BIC越小,模型越好
for i in range(55875):
    tmp = []
    c=0
    for s in datasets :
        c+=1
        try:
            model1 = model_110.fit(s[i])
            model = model1
            
            try:
                model2 = model_011.fit(s[i])
                
                if model.aic() <= model2.aic() :
                    pass
                else :
                    model = model2
                    
                try :
                    model3 = model_111.fit(s[i])
                    if model.aic() <= model3.aic() :
                        pass
                    else :
                        model = model3
                except :
                    try:
                        model4 = model_211.fit(s[i])
                        
                        if model.aic() <= model4.aic() :
                            pass
                        else:
                            model = model4
                    except:
                        try:
                            model5 = model_210.fit(s[i])
                            
                            if model.aic() <= model5.aic():
                                pass
                            else :
                                model = model5
                        except :
                            pass
                    
            except:
                try:
                    model3 = model_111.fit(s[i])

                    if model.aic() <= model3.aic() :
                        pass
                    else :
                        model = model3
                except :
                    try:
                        model4 = model_211.fit(s[i])
                        
                        if model.aic() <= model4.aic() :
                            pass
                        else:
                            model = model4
                    except:
                        try:
                            model5 = model_210.fit(s[i])
                            
                            if model.aic() <= model5.aic():
                                pass
                            else :
                                model = model5
                        except :
                            pass
                
        except:
            try:
                model2 = model_011.fit(s[i])
                model = model2
            
                try :
                    model3 = model_111.fit(s[i])
                    
                    if model.aic() <= model3.aic():
                        pass
                    else:
                        model = model3
                except :
                    try:
                        model4 = model_211.fit(s[i])
                        
                        if model.aic() <= model4.aic() :
                            pass
                        else:
                            model = model4
                    except:
                        try:
                            model5 = model_210.fit(s[i])
                            
                            if model.aic() <= model5.aic():
                                pass
                            else :
                                model = model5
                        except :
                            pass
            
            except :
                try:
                    model3 = model_111.fit(s[i])
                    model = model3
                except :
                    try:
                        model4 = model_211.fit(s[i])
                        
                        if model.aic() <= model4.aic() :
                            pass
                        else:
                            model = model4
                    except:
                        try:
                            model5 = model_210.fit(s[i])
                            
                            if model.aic() <= model5.aic():
                                pass
                            else :
                                model = model5
                        except :
                            flag = 1
                            print(str(c) + " FATAL ERROR")
                            break
        
        predictions = list(model.predict_in_sample())
        #用预测值的平均值填充预测的第一个时间步长
        #以便匹配s[i]数据的长度
        predictions = [np.mean(predictions)] + predictions
        
        residual = pd.Series(np.array(s[i]) - np.array(predictions))
        tmp.append(np.array(residual))
        
  

LSTM模型

#定义激活函数
class Double_Tanh(Activation):  
def __init__(self, activation, **kwargs):
super(Double_Tanh, self).__init__(activation, **kwargs)
self.__name__ = ’double_tanh’
def double_tanh(x):
return (K.tanh(x) * 2)
get_custom_objects().update({’double_tanh’:Double_Tanh(double_tanh)})
#RIMA-LSTM混合模型中的LSTM模型架构是一个使用25个LSTM单元的RNN神经网络。
#将25个LSTM单元的最后输出合并为一个具有全连通层的单个值。
#然后,该值将通过双双曲正切激活函数传递,以输出单个最终预测。双曲正切就是双曲正切函数乘以2的倍数。
model = Sequential()  #定义序列模型
model.add(LSTM(25, input_shape=(20,1))) #将25个LSTM单元添加到模型中
#传递一个 input_shape 参数给第一层。它是一个表示尺寸的元组 (一个整数或 None 的元组)
model.add(Dense(1))   #2D层,通过Dense设置参数input_dim 指定输入尺寸
model.add(Activation(double_tanh))  #设置激活函数为tanh
#模型编译,通过compile方法,接收三个参数:
#优化器optimizer
#损失函数loss
#评估标准metrics
model.compile(loss=’mean_squared_error’, optimizer=’adam’,   
metrics=[’mse’, ’mae’])
#拟合模型
model_scores = {}
epoch_num=1
for _ in range(50):
    #训练模型
    dir = ’~/models/hybrid_LSTM’
    file_list = os.listdir(dir)    #获取路径下的目录
    if len(file_list) != 0 :
        epoch_num = len(file_list) + 1 
        recent_model_name = ’epoch’+str(epoch_num-1)+’.h5’
        filepath = ’~/models/hybrid_LSTM/’+recent_model_name
        model = load_model(filepath)    #保存和加载模型
    filepath = ’~/models/hybrid_LSTM/epoch’+str(epoch_num)+’.h5’
    checkpoint = ModelCheckpoint(filepath, monitor=’loss’,
        verbose=1, save_best_only=False, mode=’min’)
    callbacks_list = [checkpoint]
    if len(callbacks_list) == 0:
        #train_X: 训练数据的输入特征
        #train_y: 训练数据的标签
        #epochs: 模型迭代的次数, 一般越大训练的效果越好,但过大会导致过拟合
        #batch_size: 每次迭代的样本数

        model.fit(_train_X, _train_Y, epochs=1, batch_size=500,
            shuffle=True)
    else:
        model.fit(_train_X, _train_Y, epochs=1, batch_size=500,
            shuffle=True, callbacks=callbacks_list)

ARIMA时间序列模型

前言

1、时间序列的表达

2、时间序列的特征

序列相关性:当期的序列值和前期某个或某些序列值线性相关。

  • 自相关系数(ACF):用来度量同一事件在不同时期之间的相关程度,\rho_{h}=\frac{r(h)}{r(0)},其中r(h)为h期协方差函数,r(0)为方差。
  • 偏自相关系数(PACF):度量去除中间变量影响后的相关程度。例如 X_{t} 和 X_{t-2} 通过 X_{t-1} 产生关联,PACF即为去除 X_{t-1} 的关联后两者的相关程度。

趋势性:序列整体上呈现单调性,如平稳,上涨或下跌。(ARMA模型是平稳的时间序列模型,在建模前必须去除趋势性)

随机性:序列在一定程度上呈现不确定性,模型并不能够捕提到现实世界中的所有特征,总有一些嗓声的存在,这些噪声叫做白嗓声。


根据序列是否平稳,时间序列可以分为:

  1. 平稳序列:白噪声序列、AR(p)序列,MA(q)序列,ARMA(p.q)序列
  2. 非平稳序列: ARIMA(p.d.q)序列

p: 自回归阶数
q: 滑动平均阶数
d: 时间序列成为平稳时所做的差分次数

基本流程

1、平稳性检验

序列平稳性是进行时间序列分析的前提条件。建模过程中有很多都是建立在大数定理和中心极限定理的前提条件下的,在大数定理和中心定理中要求样本同分布(这里同分布等价于时间序列中的平稳性),如果它不满足,得到的许多结论都是不可靠的。

什么是平稳序列?

  • E(X_{t})=\mu,,对于所有t而言,序列的期望为一常数
  • Var(X_{t})=\sigma ,对于所有t,序列方差为一常数
  • r(h)=Cov(X_{t}-X_{t-h}),对于所有t以及h >0,序列的协方差为是由h唯一决定的函数,即h阶的相关性只与h有关,与时刻t无关。

1)检验平稳性

时间序列平稳性检验主要是观察法和单位根检验法

方法一:观察序列图。观察序列的趋势图与相关图是否随着时间的变化呈现出某种规律。所谓的规律就是时间序列经常提到的周期性因素,现实中遇到得比较多的是线性周期成分,这类周期成分可以采用差分或者移动平均来解决,而对于非线性周期成分的处理相对比较复杂,需要采用某些分解的方法。若个体值要围绕序列均值上下波动,没有明显的上升或下降趋势,则是平稳序列。

方法二:观察自相关图

方法三:单位根检验:当一个时间序列的滞后算子多项式方程存在单位根时,我们认为该时间序列是非平稳的;反之,当该方程不存在单位根时,我们认为该时间序列是平稳的。

2)不平稳序列转为平稳序列

  • 对数变换主要是为了减小数据的振动幅度,使其线性规律更加明显。

对数变换相当于增加了一个惩罚机制,数据越大其惩罚越大,数据越小惩罚越小。变换的序列需要满足大于0,小于0的数据不存在对数变换。 

ads_log = np.log(ads)
adfuller(ads_log, autolag='AIC')
  • 差分变换可以消除数据增长趋势性和季节性时间序列最常用来剔除周期性因素。

对于非平稳序列,如果先进行差分后的结果不满足要求,则需要在原有基础上继续进行差分,直到差分后的结果属于平稳性序列。

2、白噪声检验

白噪声是时序中的纯随机序列,其具备平稳无序,无自相关的特性,因此白噪声序列本身不存在有用的信息价值。一般地,在时序建模前,需要确认变量非白噪声;建模后,需要检验残差序列是白噪声,确保残差有用信息全部提取完。

  1. 做出模型的残差序列
  2. 对残差序列进行平稳性检验,确保其满足平稳性要求。可以使用ADF检验或KPSS检验。
  3. 对平稳化后的残差序列进行自相关性检验,使用自相关函数ACF和偏自相关函数PACF来判断是否存在自相关性。
  4. 进行Ljung-Box检验或Q检验,检査序列是否满足白噪声性质。该检验的原假设是序列是白噪声,如果p值小于显著性水平,则拒绝原假设,认为序列不是白噪声

3、模型定阶

1.根据ACF图和PACF图判断序列平稳化后,使用AR、MA、ARMA中哪种模型

ACF图:描述了该序列的当前值与其过去的值之间的相关程度,以滞后值(上图就是滞后值为 1阶)为x轴,自相关系数(Xt与Xt-1的相关系数值)为y轴画出的图,也叫做相关图。

PACF图:PACF 是部分自相关函数或者偏自相关函数,找到残差(在去除了之前的滞后已经解释的影响之后仍然存在)与下一个滞后值的相关性。

X1与X2的自相关性是蓝色的部分;X2与X3的自相关性是绿色的部分;那么,X1与X2的偏自相关PACF就是图中阴影的部分。

截尾是指时间序列的自相关函数(ACF)或偏自相关函数(PACF)在某阶后均为0的性质;拖尾是ACF或PACF并不在某阶后均为0的性质。

  • 截尾:在大于某个常数k后快速趋于0为k阶截尾
  • 拖尾:始终有非零取值,不会在k大于某个常数后就恒等于零(或在0附近随机波动)

2.判断p,q阶数是多少 

  • 首先需要通过PACF和ACF这两个图来判断是哪种模型,方法如下:
模型ACFPACF
AR拖尾截尾
MA截尾拖尾
ARMA拖尾拖尾
  • 然后再看上面的阶数和2倍标准差范围,就能找到对应p、q值。

以AR模型为例:可以看到ACF是一个逐渐趋于0的拖尾,而PACF在7阶过后系数为0,所以模型是AR(7)或AR(8),即ARMA(7,0)或ARMA(8,0)。备选模型ARMA(7,1)。

3.可能有多个p,q决定的模型(因为可能ACF和PACF图可以看出多个p和q),这时要通过信息标准AIC和BIC来协助选择模型(选择AIC、BIC值最小的,因为AIC、BIC越小,模型越好)

  • 赤池信息准则 (akaike information criterion) : AIC=-2ln(L)+2kAIC鼓励数据拟合的优良性但是尽量避免出现过度拟合(Overfitting)的情况。所以优先考虑的模型应是AIC值最小的那一个)
  • 贝叶斯信息准则 (bayesian information criterion)  :  BIC=-2ln(L)+ln(n)*k

其中 L 是该模型下的最大似然, n 是数据数量, k 是模型的变量个数。AIC和BIC是通过加入模型复杂度的惩罚项来避免过拟合问题,通常两者都倾向于选择参数更少的模型。但很多情况下,AIC最小的模型,不代表BIC也会最小。

4、模型检验

模型的显著性检验:整个模型对信息的提取是否充分

参数的显著性检验:模型结构是否最简

总结

ARIMA模型既可以捕捉到数据的趋势变化,又可以处理那些有临时、突发的变化或者噪声较大的数据。由于ARIMA模型的输入只能是平稳数据,因此需要对数据进行平稳性检验,并通过差分变换等方式将不平稳数据转换为平稳数据,然后通过ACF和PACF图形来确定使用哪一种模型以及确定p、d、q三个超参数,并使用AIC和BIC进行模型选择的方法,以选取最优的ARIMA模型。

  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值