R语言实现金融数据的时间序列分析及建模
一、实验介绍
1.1 实验内容
本实验主要探讨了几种时间序列的预测模型,首先带领大家对时间序列有一个初步的认识再在这个基础之上,向读者介绍当下最常用的 ARIMA 模型来预测时间序列,接着为读者展示几种指数平滑的方法来预测,最后通过几种模型的对比,让大家可以从中选择出一个最佳的模型来实现预测。
为了保证可以在实验楼环境中完成本次实验,我们在实验基础上补充了一系列的实验指导,比如实验截图,代码注释,帮助您更好得实战。
如果您对于实验有疑惑或者建议可以随时在讨论区中提问,与同学们一起探讨。
1.2 实验知识点
- 时间序列预测
- ARIMA 模型
- 指数平滑
1.3 实验环境
- R version 3.4.1
- Xfce终端
1.4 适合人群
本课程难度为简单,属于初级级别课程,需要有一定金融统计知识,本实验主要涉及时间序列的相关基础知识。
二、实验内容
2.1 时间序列预测
时间序列预测法就是通过编制和分析时间序列,根据时间序列所反映出来的发展过程、方向和趋势,进行类推或延伸,借以预测下一段时间或以后若干年内可能达到的水平。
2.2 时间序列预测法的步骤
第一步 收集历史资料,加以整理,编成时间序列,并根据时间序列绘成统计图
第二步 分析时间序列。时间序列中的每一时期的数值都是由许许多多不同的因素同时发生作用后的综合结果。
第三步 求时间序列的长期趋势(T)季节变动(s)和不规则变动(I)的值,并选定近似的数学模式来代表它们
第四步 利用时间序列资料求出长期趋势、季节变动和不规则变动的数学模型后,就可以利用它来预测未来的长期趋势值 T 和季节变动值 s,在可能的情况下预测不规则变动值 I。
2.3 时间序列预测法的分类
时间序列预测法可用于短期预测、中期预测和长期预测。根据对资料分析方法的不同,又可分为:简单序时平均数法、加权序时平均数法、移动平均法、加权移动平均法、趋势预测法、指数平滑法、季节性趋势预测法、市场寿命周期预测法等。
知识点来源:时间序列预测法
三、实验步骤
本次实验主要使用的是自回归移动平均和指数平滑法。
3.1 ARIMA 模型
自回归移动平均模型(ARIMA)包含一个确定(explicit)的统计模型用于处理时间序列的不规则部分,它允许不规则部分可以自相关。
3.1.1 数据准备
加载相应数据包
> library(zoo)
> library(xts)
> library(TTR)
本实验选用的是 42 位英国国王的去世年龄数据,然后将其转化成时间序列数据,并用图形的形式展示出来
> kings<-scan("http://robjhyndman.com/tsdldata/misc/kings.dat",skip=3)
> kingstimeseries<-ts(kings)
> plot.ts(kingstimeseries)
3.1.2 数据差分
ARIMA 模型定义的是一个平稳时间序列。因此, 如果从一个非平稳的时间序列开始, 那么首先就需要做时间序列差分直到得到一个平稳时间序列。如果必须对时间序列做 d 阶差分才能得到一个平稳序列,那么就使用 ARIMA(p,d,q) 模型,其中 d 是差分的阶数。
可以通过下面的代码来得到时间序列数据的一阶差分, 并画出差分序列的图:
> kingstimeseriesdiff1<-diff(kingstimeseries,differences=1)
> plot.ts(kingstimeseriesdiff1)
从一阶差分的图中可以看出,数据已经是平稳的。如果不平稳就需要继续差分。所以对于英国国王去世年龄时间序列选择 ARIMA(p,1,q) 的模型。
3.1.3 寻找 ARIMA 模型
当我们的获得的时间序列是平稳的,或者经过 d 次差分后的到了一个平稳序列,接下来就是选择一个合适的 ARIMA 模型,通常我们需要检查平稳时间序列的自相关图和偏相关图,也就是寻找 ARIMA(p,d,q) 中合适的 p 值和 q 值。
> acf(kingstimeseriesdiff1,lag.max=20)
> acf(kingstimeseriesdiff1,lag.max=20,plot=FALSE)
从上面图中可以看出在滞后 1 阶的自相关值超出了置信边界,但是其他所有在滞后1-20 阶的自相关值都没有超出置信边界。
> pacf(kingstimeseriesdiff1,lag.max=20)
> pacf(kingstimeseriesdiff1,lag.max=20,plot=FALSE)
偏相关图显示在滞后 1,2 和 3 阶时的偏自相关系数超出了置信边界,为负值,且在等级上随着滞后阶数的增加而缓慢减少。
安装 forecast 包并载入:
> install.packages("forecast")
> library(forecast)
根据 acf 和 pacf 我们可以先拟合 ARIMA(1,1,3) 模型:
> kings.arima <- arima(kingstimeseries, order = c(1,1,3))
> summary(kings.arima)
3.1.4 模型预测
未来 5 位国王的预测值
> kingsarimaforecast <- forecast(kings.arima, h = 5)
> kingsarimaforecast
> plot(kingsarimaforecast)
3.1.5 模型误差检验
在指数平滑模型下, 观察 ARIMA 模型的预测误差是否服从零均值、方差不变的正态分布,同时也可以观察连续预测误差是否(自)相关。
同时对国王去世年龄使用 ARIMA(1,1,3) 模型后所产生的预测误差做(自)相关图,和 Ljung-Box 检验:
> acf(kingsarimaforecast$residuals,lag.max=20)
> Box.test(kingsarimaforecast$residuals, lag=20, type="Ljung-Box")
相关图显示出在滞后 1-20 阶中样本自相关值都没有超出显著(置信)边界,而且 Ljung-Box 检验的 p 值为 0.9515,所以我们推断在滞后 1-20 阶中没有明显证据说明预测误差是非零自相关的。
3.1.6 ARIMA 模型自动预测
我们也可以通过 forecast 包里的 auto.arima 这个函数进行 ARIMA 模型自动的预测。
> kings.arima1 <- auto.arima(kingstimeseries)
> summary(kings.arima1)
重新生成模型,通过以下的代码完成:
> kings.arima_new <- arima(kingstimeseries, order=c(0,1,1))
> summary(kings.arima_new)
使用自动生成的模型进行预测:
> kingsarimaforecast <- forecast(kings.arima_new, h = 5 )
> kingsarimaforecast
> plot(kingsarimaforecast)
进行模型误差检验
> acf(kingsarimaforecast$residuals,lag.max=20)
> Box.test(kingsarimaforecast$residuals, lag=20, type="Ljung-Box")
在时间序列下通过对比自动拟合的模型,这也不失为一种参照的标准。
3.2 指数平滑模型
指数平滑法对于预测来说是非常有帮助的,而且它对时间序列上面连续的值之间相关性没有要求。指数平滑法可以用于时间序列数据的短期预测。
3.2.1 简单指数平滑法
简单指数平滑法主要适用于没有季节性变化且处于恒定水平以及没有明显趋势的时间序列的预测。
获取数据(数据来源为伦敦每年降雨量),通过 ts 函数转换为时间序列,并画出时序图:
> rain<-scan("http://robjhyndman.com/tsdldata/hurst/precip1.dat",skip=1)
> rainseries<-ts(rain,start=c(1813))
> plot.ts(rainseries)
调用 HoltWinters() 函数,并设定参数 beta=FALSE,gamma=FALSE
> rainseriesHW <-HoltWinters(rainseries,beta=FALSE,gamma=FALSE)
> plot(rainseriesHW)
通过 forecast 包来预测未来 5 年的降水量,载入 forecast 包
> library("forecast")
调用 forecast() 函数预测,并画出预测结果
> rainseriesforecasts<-forecast(rainseriesHW,h=5)
> plot(rainseriesforecasts)
其中蓝线是预测 1913-1920 间的降雨量,深灰色阴影区域为 80% 的预测区间,浅灰色阴影区域为 95% 的预测区间。
forecast 提供了预测误差的统计指标(residuals),来评估预测是否有改进的可能性:如果预测误差是相关的,则很可能是简单指数平滑预测可以被另外一种预测技术优化。
> acf(rainseriesforecasts$residuals[!is.na(rainseriesforecasts$residuals)],lag.max=20,plot=T)
观看上图可以发现自相关系数在第 3 期的时候达到了置信界限。为了验证在滞后 1-20 阶时非 0 自相关属性是否显著,可以借助 Box.test() 的 Ljung-Box检验。
> Box.test(rainseriesforecasts$residuals,lag=20,type="Ljung-Box")
统计量为 17.4,并且 P 值是 0.626 这样的值不足以拒绝预测误差在 1-20 阶是非零自相关。
3.2.2 霍尔特指数平滑法
简单指数平滑法只能预测那些处于恒定水平和没有季节变动的时间序列,霍尔特指数平滑法可以用于非恒定水平,没有季节性可相加模型的时间序列预测。
霍尔特指数平滑法是估计当前时间的水平和斜率。其平滑水平是由两个参数控制,alpha:估计当前点水平,beta:估计当前点趋势部分斜率。两个参数都介于 0-1 之间,当参数越接近 0,大部分近期的观测值的权值将较小。
数据来源是 1866 年到 1911 年每年女士裙子直径,将数据通过 ts 函数转换为时间序列,并画出时序图:
> skirts<-scan("http://robjhyndman.com/tsdldata/roberts/skirts.dat",skip=5)
> skirtsseries<-ts(skirts,start=c(1866))
> plot.ts(skirtsseries)
调用 HoltWinters() 函数,并设定参数 gamma=FALSE
> skirtsseriesHW<-HoltWinters(skirtsseries,gamma=FALSE)
> skirtsseriesHW
> plot(skirtsseriesHW)
相关预测值中 alpha 值为 0.8383,beta预测值为 1.0,这些都是非常高的值,充分显示了无论是水平上还是趋势的斜率上,当前值对时间序列上的最近的观测值的依赖关系比较重,这样的结果也符合我们的预期,因为时间序列的水平和斜率在整个时间段内发生了巨大的变化。
总体来看,预测的效果也还不错(红色为预测值)。
通过 forecast 包来预测未来 5 年的数据值,并画出预测结果:
> skirtsseriesforecasts<-forecast(skirtsseriesHW,h=5)
> plot(skirtsseriesforecasts)
为了检验预测效果,我们同样检验延迟 1-20 阶中的预测误差是否非零自相关,继续采用 Ljung-Box 检验:
> acf(skirtsseriesforecasts$residuals[!is.na(skirtsseriesforecasts$residuals)],lag.max=20,plot=T)
相关图呈现样本内预测误差在滞后 5 阶时超过置信边界,其他都没有超过,我们认为存在一定的偶尔因素。
> Box.test(skirtsseriesforecasts$residuals,lag=20,type="Ljung-Box")
Ljung-Box 检验时,p =0.4749,意味着置信度只有 53% 这样的值不足以拒绝预测误差在 1-20 阶是非零自相关,则我们接受预测误差在 1-20 阶是非零自相关的。
3.2.3 Holt-Winters 指数平滑法
这是一种有增长或者降低趋势并且存在季节性波动的时间序列的预测方法。
Holt-Winters 算法中提供了 alpha、beta 和 gamma 来分别对应当前点的水平、趋势部分和季节部分,参数的去执法范围都是 0-1 之间,并且参数接近 0 时,近期的观测值的影响权重就越小。
数据来源是澳大利亚昆士兰州海滨纪念商品的月度销售日子做为分析对象,将数据通过 ts 函数转换为时间序列,并画出时序图:
> souvenir<-scan("http://robjhyndman.com/tsdldata/data/fancy.dat")
> souvenirtimeseries<-ts(souvenir,frequency=12,start=c(1987,1))
> plot.ts(souvenirtimeseries)
可以通过取对数来减少极值带来的影响,消除方差不齐。
> logsouvenirtimeseries<-log(souvenirtimeseries)
> plot.ts(logsouvenirtimeseries)
调用 HoltWinters() 函数
> souvenirtimeseriesHW<-HoltWinters(logsouvenirtimeseries)
> plot(souvenirtimeseriesHW)
通过 forecast 包来预测未来 12 个月的销售数据,并画出预测结果
> souvenirtimeseriesforecasts<-forecast(souvenirtimeseriesHW,h=12)
> plot(souvenirtimeseriesforecasts)
从图中可以以看出来模型非常成功得预测了季节峰值,峰值大约发生在每年的 12 月份。
还可以通过画相关图和进行 Ljung-Box 检验来检查样本内预测误差在延迟 1-20 阶时否是非零自相关的,并以此确定预测模型是否可以再被优化。
> acf(souvenirtimeseriesforecasts$residuals[!is.na(souvenirtimeseriesforecasts$residuals)],lag.max=20,plot=T)
相关图显示出在滞后 1-20 阶中样本自相关值都没有超出显著(置信)边界。
> Box.test(souvenirtimeseriesforecasts$residuals,lag=20,type="Ljung-Box")
Ljung-Box 检验的 p 值为 0.6183,所以我们推断在滞后 1-20 阶中没有明显证据说明预测误差是非零自相关的。
四.总结
通过本次实验,读者可以对比各种时间序列预测模型的优劣,从中选择合适的模型进行相应的预测,同时读者可以对课程以外的其他预测模型进行实验探究,结果报告可发布在实验平台上和大家一起讨论交流。