一、项目背景
股票投资已经随着人们生活水平的逐步提高而变得普遍,更多的人开始逐渐关注并参与到股票投资市场中来。股票具有高收益的同时也伴随着较高的风险,我们知道,股票价格的变动受很多因素的影响,因此对于股票价格预测的研究具有非常大的价值,而如果使用对股价影响的因素去建立回归模型并不现实,因为股票价格的变动实则是具有一定的随机性的,且涉及的因素多不胜数,但股票价格的变动具有一定的趋向性,是一个典型的时间序列,时间序列分析是经济研究领域的一个非常重要的方法,它不仅可以描述历史数据随着时间变化所呈现的规律,而且还可以用于经济领域的一些研究和预测。时间序列预测法在股票市场种常用来对股票价格的变化趋势进行预测,从而为投资者提供合理的决策依据。本文基于苹果公司2000年到的股价数据,使用两种时间序列分析模型来对股价进行预测,希望能得到改股票的大约发展趋势。
二、模型介绍
1、指数平滑模型
指数平滑法实际上是一种特殊的加权移动平均法。它拥有以下几个特点: 第一,指数平滑法进一步加强了观察期近期观察值对预测值的作用,对不同时间的观察值所赋予的权数不等,从而加大了近期观察值的权数,使预测值能够迅速反映市场实际的变化。权数之间按等比级数减少,此级数之首项为平滑常数a,公比为(1- a)。第二,指数平滑法对于观察值所赋予的权数有伸缩性,可以取不同的a 值以改变权数的变化速率。如a取小值,则权数变化较迅速,观察值的新近变化趋势较能迅速反映于指数移动平均值中。因此,运用指数平滑法,可以选择不同的a 值来调节时间序列观察值的均匀程度(即趋势变化的平稳程度)。指数平滑法有几种不同形式:一次指数平滑法针对没有趋势和季节性的序列,二次指数平滑法针对有趋势但没有季节性的序列,三次指数平滑法针对有趋势也有季节性的序列。在本次项目中所使用的数据是具有趋势性的股票数据,因此将会在模型中使用二次指数平滑模型,下面将介绍一次指数平滑模型与二次指数平滑模型。
一次指数平滑法
一次指数平滑法的递推公式为:
其中0≤a≤1,其中, s_(i-1) 是时间步长i(理解为第i个时间点)上经过平滑后的值, x_i 是这个时间步长上的实际数据.a可以是0和1之间的任意值,它控制着新旧信息之间的平衡:当 a接近1,就只保留当前数据点;当 a 接近0时,就只保留前面的平滑值(整个曲线都是平的)。递推关系式:
二次指数平滑法
二次指数平滑在此基础上将趋势作为一个额外考量,保留了趋势的详细信息。即我们保留并更新两个量的状态:平滑后的信号和平滑后的趋势。公式如下:
第二个等式描述了平滑后的趋势。当前趋势的未平滑“值”t_i是当前平滑值s_i和上一个平滑值s_(i-1)的差;也就是说,当前趋势告诉我们在上一个时间步长里平滑信号改变了多少。要想使趋势平滑,我们用一次指数平滑法对趋势进行处理,并使用参数β(理解:对t_i的处理类似于一次平滑指数法中的s_i,即对趋势也需要做一个平滑,临近的趋势权重大)。
2、ARIMA模型
ARIMA模型全称为自回归移动平均模型,由AR自回归模型、I差分、MA移动平均模型三部分组合而成。
自回归模型AR
自回归模型描述当前值与历史值之间的关系,用变量自身的历史时间数据对自身进行预测。自回归模型必须满足平稳性。自回归模型需要先确定一个阶数p,表示用几期的历史值来预测当前值。p阶自回归模型可以表示为:
I差分
将不平稳的时间序列转化为平稳的时间序列,或弱平稳时间序列。
移动平均模型MA
移动平均模型能有效地消除预测中的随机波动, 关注的是自回归模型中的误差项的累加,q阶自回归过程的公式定义如下:
三、获取数据
数据的获取主要是从pandas_datareader模块下的雅虎财经接口get_data_yahoo进行便捷数据获取。获取之前需要使用datetime函数来设置要获取的时间区间。
from pandas_datareader.data import get_data_yahoofrom datetime import datetimeimport pandas as pdimport matplotlib.pyplot as plt %matplotlibstart=datetime(2000,1,1)end=datetime(,1,1)stock_data=get_data_yahoo('AAPL',start,end)
观察数据的前五行
stock_data.head()
观察数据可得,获取的股票数据共有六个变量。分别是最高价,最低价,开盘价,收盘价,成交量与调整后的收盘价,在本次项目中,我们需要的是预测股票的收盘价格,因此通过切片获得目标变量,然后再查看数据
stock_data=stock_data['Close']stock_data.head()
四、数据探索
在获取了数据之后,我们需要对数据进行一定的探索,首先来观察数据是否存在缺失值
stock_data.isnull().sum()
然后再来观察数据的分布情况
stock_data.describe()
可以看到获取的数据共有5032条,并且没有缺失值,下面通过可视化的操作更加直观的观察数据。
stock_data.plot()
可以观察到该数据具有很明显的趋势性,进而我们再截取某一年的数据来观察一年内的趋势情况
stock_data[''].plot()
stock_data[''].plot()
我们随机地选取了两年的股票价格走向,发现该股票的价格在一年内是没有周期性的趋势的。
五、数据预处理
数据的预处理操作主要是重采样每一个月的均值来重新获得数据,使数据更加平滑。
stock_mon=stock_data.resample('M').mean()stock_mon.head()
可视化新的数据
stock_mon.plot()
可以看到数据变得平滑了许多,最后划分出建模用的训练数据来完成数据预处理部分,因为时间序列模型只能预测短期的数据,所以选取前来成为训练模型的数据,最后两年来测试预测模型。
train_data=stock_mon['2000':'']train_data.plot()
六、建立模型
1、指数平滑模型
由前文数据探索的图示可知,根据经验判断法,苹果公司股票时间序列波动很大。长期趋势变化幅度较大,呈现明显且迅速的上升趋势,宜选择较大的α值,可在0.5-O.8间选值,以使预测模型灵敏度高些,结合试算法取0.5,0.8分别测试。且选用二次指数平滑法。
导入二次指数平滑的模块from statsmodels.tsa.holtwinters import Holt构建水平平滑参数a=0.5,β=0.2的二次指数平滑模型fit1 = Holt(train_data).fit(smoothing_level=0.5, smoothing_slope=0.2, optimized=False)模型应用预测pred1=fit1.forecast(len(stock_mon['':'']))pred1.head()可视化预测数据与实际数据进行评估pd.DataFrame({'origin': stock_mon,'fitted': fit1.fittedvalues,'pred': pred1}).plot(legend=True)
使用sklearn模块下的mean_squared_error来计算预测值与真实值之间的均方根误差,来获得模型的预测效果mean_squared_error(pred1,stock_mon['':''])
构建水平平滑参数a=0.8,β=0.2的二次指数平滑模型fit2 = Holt(train_data).fit(smoothing_level=0.8, smoothing_slope=0.2, optimized=False)模型应用预测pred1=fit1.forecast(len(stock_mon['':'']))pred1.head()可视化预测数据与实际数据进行评估pd.DataFrame({'origin': stock_mon,'fitted': fit1.fittedvalues,'pred': pred2}).plot(legend=True)
使用sklearn模块下的mean_squared_error来计算预测值与真实值之间的均方根误差,来获得模型的预测效果mean_squared_error(pred2,stock_mon['':''])
通过观察两个不同α值得指数平滑模型,可以了解到两个模型都能根据历史数据对未来两年的股票价格进行一个较好的趋势预测,而根据均方根误差的结果,α为0.5的模型预测效果相对于较好一点。
2、ARIMA模型
使用ARIMA模型对数据进行预测,进入模型的数据需要是平稳的时间序列,虽然由前文的数据的数据可视化可以得到,改股票数据具有很强的趋势性,但还是使用画出自相关系数ACF的方法进行平稳性检验。
from statsmodels.graphics.tsaplots import plot_acfplot_acf(train_data)
观察自回归系数可以知道,acf值长期大于0,故可以判断该时间序列具有很强的不平稳性,下面对数据进行一阶差分并观察差分后的数据
diff1 = train_data.diff(1).dropna()diff1.plot()
可得数据已经没有明显的趋势性并围绕着一个值上下波动,下面再对差分后的自回归系数进行观察
from statsmodels.graphics.tsaplots import plot_pacfplot_acf(diff1)
观察可得系数已不再长时间大于0,可知数据已经较为平稳,接下来需要确定自回归AR的参数p和移动平均MA的参数q,首先画出偏自相关图
plot_pacf(diff1)
要获得合适的参数,我们需要了解什么是acf和pacf,ARIMA的参数代表着什么意义,该怎么去选取。
根据AR自回归和MA移动平均模型,p为相应的自回归项,q是移动平均项数。
自相关函数(ACF)是有序的随机变量序列与其自身相比较公式:
自相关函数反映了同一序列在不同时序的取值之间的相关性。
偏自相关函数(PACF)对于一个平稳AR模型,求出滞后k自相关系数p(k)时 实际上得到并不是x_t与x_(t-1)之间单纯的相关关系,x_t同时还会受到中间k-1个随机变量的影响 而这k-1个随机变量又都和x_(t-1)具有相关关系 所以自相关系数p(k)里实际掺杂了其他变量对x_t与x_(t-1)的影响,偏自相关函数是剔除了中间k-1个随机变量的干扰之后 x_(t-1)对x_t影响的相关程度,是严格这两个变量之间的相关性。
根据以上得出两个acf和pcaf系数图,可以得出均在1阶后趋向于0,所以ARIMA系数选择(1,1,1)
from statsmodels.tsa.arima_model import ARIMAfit3 = ARIMA(train_data,(1,1,1)).fit()
模型应用预测
pred3=fit3.predict('','',dynamic=True,typ='levels')pred3.head()
查看模型报告,主要查看bic值fit3.summary2()
可视化预测数据与实际数据进行评估pd.DataFrame({'origin': stock_mon,'fitted': fit3.fittedvalues,'pred': pred3}).plot(legend=True)
使用sklearn模块下的mean_squared_error来计算预测值与真实值之间的均方根误差,来获得模型的预测效果
mean_squared_error(pred3['':''],stock_mon['':''])
可以看到ARIMA模型的预测效果会比指数平滑模型相对来说好一点,由于模型参数的选择最终是应用在模型上的,而BIC值可以反应出模 型的效果,而根据acf和pcaf图判断选择的p和q可能并不能使得模型最优,因此编写一个循环来获得使bic值最小的pq值,来优化模型。
bic_matrix = [] #bic矩阵for p in range(8):tmp = []for q in range(8):try: #存在部分报错,所以用try来跳过报错。tmp.append(ARIMA(train_data, (p,1,q)).fit().bic)except:tmp.append(None)bic_matrix.append(tmp)bic_matrix = pd.DataFrame(bic_matrix) #从中可以找出最小值print(bic_matrix.stack())
p,q = bic_matrix.stack().astype('float64').idxmin()print(u'BIC最小的p值和q值为:%s、%s' %(p,q))
可以得到要使得模型的BIC值最少的pq值取值为0和1,得到最优参数后再次拟合模型fit4 = ARIMA(train_data,(0,1,1)).fit()pred4=fit4.predict('','',dynamic=True,typ='levels')pred4.head()
可视化预测数据与实际数据进行评估pd.DataFrame({'origin': stock_mon,'fitted': fit4.fittedvalues,'pred': pred4}).plot(legend=True)
fit4.summary2()
七、项目结论
本次项目通过分别建立指数平滑模型与ARIMA模型,对苹果公司的股价数据进行预测,两个模型都取得不错的效果,都能根据过去的历史数据对将来的数据进行拟合预测,而两个模型的应用各有优缺点,指数平滑法、ARIMA 法均适用于短期拟合,ARIMA 模型计算过程比指数平滑法复杂、繁琐。经过比较,精度较差的预测方法为二次指数平滑预测法,原因可能在于平滑法以历史数据为依据,进行预测的前提是,过去存在的各种因素的影响和发展趋势将在今后继续,但是股票价格的变化是复杂的,当经济发展趋势保持较长时间的稳定后, 出现突然上升或下降的趋势时, 指数平滑法就难以适应,所以用 ARIMA 模型预测股票的价格走势较为合理。但ARIMA模型对非线性的,具有周期性变化的时间序列就并不理想,而指数平滑模型能对具有周期性的时间序列进行较好的预测,所以需要具体结合样本数据的特征来做出模型的选择。
对于这次对苹果的股价数据进行预测,苹果公司的股价从开始到都保持一个比较好的增长趋势,中间虽然存在比较小幅度的下降区间但也能很快地调整好增长的趋势,但的9月到年初,股价可以说是一下子回到了一年之前,从这也可以看出股票价格是波动非常大的,没有人能够准确地预测到股价明天是否一定会涨或跌,但纵观历史数据,苹果公司的股票价格是一个随着时间的推移而上升的因此能够用时间序列模型ARIMA或者指数平滑法进行一个短期的趋向性预测。