利用python实现平稳时间序列的建模方式


Posted in Python onJune 03, 2020

一、平稳序列建模步骤

假如某个观察值序列通过序列预处理可以判定为平稳非白噪声序列,就可以利用ARMA模型对该序列进行建模。建模的基本步骤如下:

(1)求出该观察值序列的样本自相关系数(ACF)和样本偏自相关系数(PACF)的值。

(2)根据样本自相关系数和偏自相关系数的性质,选择适当的ARMA(p,q)模型进行拟合。

(3)估计模型中位置参数的值。

(4)检验模型的有效性。如果模型不通过检验,转向步骤(2),重新选择模型再拟合。

(5)模型优化。如果拟合模型通过检验,仍然转向不走(2),充分考虑各种情况,建立多个拟合模型,从所有通过检验的拟合模型中选择最优模型。

(6)利用拟合模型,预测序列的将来走势。

二、代码实现

1、绘制时序图,查看数据的大概分布

trainSeting.head()
Out[36]: 
date
2017-10-01 126.4
2017-10-02  82.4
2017-10-03  78.1
2017-10-04  51.1
2017-10-05  90.9
Name: sales, dtype: float64

plt.plot(trainSeting)

利用python实现平稳时间序列的建模方式

2、平稳性检验

'''进行ADF检验
adf_test的返回值
Test statistic:代表检验统计量
p-value:代表p值检验的概率
Lags used:使用的滞后k,autolag=AIC时会自动选择滞后
Number of Observations Used:样本数量
Critical Value(5%) : 显著性水平为5%的临界值。
(1)假设是存在单位根,即不平稳;
(2)显著性水平,1%:严格拒绝原假设;5%:拒绝原假设,10%类推。
(3)看P值和显著性水平a的大小,p值越小,小于显著性水平的话,就拒绝原假设,认为序列是平稳的;大于的话,不能拒绝,认为是不平稳的
(4)看检验统计量和临界值,检验统计量小于临界值的话,就拒绝原假设,认为序列是平稳的;大于的话,不能拒绝,认为是不平稳的
'''
#滚动统计
def rolling_statistics(timeseries):
 #Determing rolling statistics
 rolmean = pd.rolling_mean(timeseries, window=12)
 rolstd = pd.rolling_std(timeseries, window=12)
 
 #Plot rolling statistics:
 orig = plt.plot(timeseries, color='blue',label='Original')
 mean = plt.plot(rolmean, color='red', label='Rolling Mean')
 std = plt.plot(rolstd, color='black', label = 'Rolling Std')
 plt.legend(loc='best')
 plt.title('Rolling Mean & Standard Deviation')
 plt.show(block=False)
 
##ADF检验
from statsmodels.tsa.stattools import adfuller
def adf_test(timeseries):
 rolling_statistics(timeseries)#绘图
 print ('Results of Augment Dickey-Fuller Test:')
 dftest = adfuller(timeseries, autolag='AIC')
 dfoutput = pd.Series(dftest[0:4], index=['Test Statistic','p-value','#Lags Used','Number of Observations Used'])
 for key,value in dftest[4].items():
  dfoutput['Critical Value (%s)'%key] = value #增加后面的显著性水平的临界值
 print (dfoutput)
 
adf_test(trainSeting) #从结果中可以看到p值为0.1097>0.1,不能拒绝H0,认为该序列不是平稳序列

返回结果如下

利用python实现平稳时间序列的建模方式

Results of Augment Dickey-Fuller Test:
Test Statistic    -5.718539e+00
p-value      7.028398e-07
#Lags Used      0.000000e+00
Number of Observations Used 6.200000e+01
Critical Value (1%)   -3.540523e+00
Critical Value (5%)   -2.909427e+00
Critical Value (10%)   -2.592314e+00
dtype: float64

通过上面可以看到,p值小于0.05,可以认为该序列为平稳时间序列。

3、白噪声检验

'''acorr_ljungbox(x, lags=None, boxpierce=False)函数检验无自相关
lags为延迟期数,如果为整数,则是包含在内的延迟期数,如果是一个列表或数组,那么所有时滞都包含在列表中最大的时滞中
boxpierce为True时表示除开返回LB统计量还会返回Box和Pierce的Q统计量
返回值:
lbvalue:测试的统计量
pvalue:基于卡方分布的p统计量
bpvalue:((optionsal), float or array) ? test statistic for Box-Pierce test
bppvalue:((optional), float or array) ? p-value based for Box-Pierce test on chi-square distribution
'''
from statsmodels.stats.diagnostic import acorr_ljungbox
def test_stochastic(ts,lag):
 p_value = acorr_ljungbox(ts, lags=lag) #lags可自定义
 return p_value

test_stochastic(trainSeting,[6,12])
Out[62]: (array([13.28395274, 14.89281684]), array([0.03874194, 0.24735042]))

从上面的分析结果中可以看到,延迟6阶的p值为0.03<0.05,因此可以拒绝原假设,认为该序列不是白噪声序列。

4、确定ARMA的阶数

(1)利用自相关图和偏自相关图

####自相关图ACF和偏相关图PACF
import statsmodels.api as sm
def acf_pacf_plot(ts_log_diff):
 sm.graphics.tsa.plot_acf(ts_log_diff,lags=40) #ARIMA,q
 sm.graphics.tsa.plot_pacf(ts_log_diff,lags=40) #ARIMA,p
 
acf_pacf_plot(trainSeting) #查看数据的自相关图和偏自相关图

利用python实现平稳时间序列的建模方式

(2)借助AIC、BIC统计量自动确定

##借助AIC、BIC统计量自动确定
from statsmodels.tsa.arima_model import ARMA
def proper_model(data_ts, maxLag): 
 init_bic = float("inf")
 init_p = 0
 init_q = 0
 init_properModel = None
 for p in np.arange(maxLag):
  for q in np.arange(maxLag):
   model = ARMA(data_ts, order=(p, q))
   try:
    results_ARMA = model.fit(disp=-1, method='css')
   except:
    continue
   bic = results_ARMA.bic
   if bic < init_bic:
    init_p = p
    init_q = q
    init_properModel = results_ARMA
    init_bic = bic
 return init_bic, init_p, init_q, init_properModel
 
proper_model(trainSeting,40)
#在statsmodels包里还有更直接的函数:
import statsmodels.tsa.stattools as st
order = st.arma_order_select_ic(ts_log_diff2,max_ar=5,max_ma=5,ic=['aic', 'bic', 'hqic'])
order.bic_min_order
'''
我们常用的是AIC准则,AIC鼓励数据拟合的优良性但是尽量避免出现过度拟合(Overfitting)的情况。所以优先考虑的模型应是AIC值最小的那一个模型。
为了控制计算量,我们限制AR最大阶不超过5,MA最大阶不超过5。 但是这样带来的坏处是可能为局部最优。
timeseries是待输入的时间序列,是pandas.Series类型,max_ar、max_ma是p、q值的最大备选值。
order.bic_min_order返回以BIC准则确定的阶数,是一个tuple类型

返回值如下:

order.bic_min_order
Out[13]: (1, 0)

5、建模

从上述结果中可以看到,可以选择AR(1)模型

################################模型######################################
# AR模型,q=0
#RSS是残差平方和
# disp为-1代表不输出收敛过程的信息,True代表输出
from statsmodels.tsa.arima_model import ARIMA
model = ARIMA(trainSeting,order=(1,0,0)) #第二个参数代表使用了二阶差分
results_AR = model.fit(disp=-1)
plt.plot(trainSeting)
plt.plot(results_AR.fittedvalues, color='red') #红色线代表预测值
plt.title('RSS:%.4f' % sum((results_AR.fittedvalues-trainSeting)**2))#残差平方和

利用python实现平稳时间序列的建模方式

6、预测未来走势

############################预测未来走势##########################################
# forecast方法会自动进行差分还原,当然仅限于支持的1阶和2阶差分
forecast_n = 12 #预测未来12个天走势
forecast_AR = results_AR.forecast(forecast_n)
forecast_AR = forecast_AR[0]
print (forecast_AR)

print (forecast_ARIMA_log)
[90.49452199 84.05407353 81.92752342 81.22536496 80.99352161 80.91697003

80.89169372 80.88334782 80.88059211 80.87968222 80.87938178 80.87928258]

##将预测的数据和原来的数据绘制在一起,为了实现这一目的,我们需要增加数据索引,使用开源库arrow:
import arrow
def get_date_range(start, limit, level='day',format='YYYY-MM-DD'):
 start = arrow.get(start, format) 
 result=(list(map(lambda dt: dt.format(format) , arrow.Arrow.range(level, start,limit=limit))))
 dateparse2 = lambda dates:pd.datetime.strptime(dates,'%Y-%m-%d')
 return map(dateparse2, result)
 
# 预测从2017-12-03开始,也就是我们训练数据最后一个数据的后一个日期
new_index = get_date_range('2017-12-03', forecast_n)
forecast_ARIMA_log = pd.Series(forecast_AR, copy=True, index=new_index)
print (forecast_ARIMA_log.head())
##绘图如下
plt.plot(trainSeting,label='Original',color='blue')
plt.plot(forecast_ARIMA_log, label='Forcast',color='red')
plt.legend(loc='best')
plt.title('forecast')

利用python实现平稳时间序列的建模方式

以上这篇利用python实现平稳时间序列的建模方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
在Django中创建动态视图的教程
Jul 15 Python
Django使用Mysql数据库已经存在的数据表方法
May 27 Python
Python中创建二维数组
Oct 17 Python
python实现桌面壁纸切换功能
Jan 21 Python
python pandas获取csv指定行 列的操作方法
Jul 12 Python
Pandas之groupby( )用法笔记小结
Jul 23 Python
详解解决Python memory error的问题(四种解决方案)
Aug 08 Python
Python使用matplotlib绘制三维参数曲线操作示例
Sep 10 Python
Python如何实现强制数据类型转换
Nov 22 Python
Python3 socket即时通讯脚本实现代码实例(threading多线程)
Jun 01 Python
Python获取字典中某个key的value
Apr 13 Python
Django中celery的使用项目实例
Jul 07 Python
Python ADF 单位根检验 如何查看结果的实现
Jun 03 #Python
基于Python快速处理PDF表格数据
Jun 03 #Python
PIL.Image.open和cv2.imread的比较与相互转换的方法
Jun 03 #Python
Python3创建Django项目的几种方法(3种)
Jun 03 #Python
Django 实现 Websocket 广播、点对点发送消息的代码
Jun 03 #Python
使用python实现时间序列白噪声检验方式
Jun 03 #Python
部署Django到阿里云服务器教程示例
Jun 03 #Python
You might like
php echo 输出字符串函数详解
2010/05/13 PHP
PHP实现阳历到农历转换的类实例
2015/03/07 PHP
thinkphp5.1框架实现格式化mysql时间戳为日期的方式小结
2019/10/10 PHP
jquery插件 autoComboBox 下拉框
2010/12/22 Javascript
Firefox和IE兼容性问题及解决方法总结
2013/10/08 Javascript
JQuery实现表格动态增加行并对新行添加事件
2014/07/30 Javascript
jquery ui dialog替代confirm实例分析
2016/01/25 Javascript
JavaScript中将数组进行合并的基本方法讲解
2016/03/07 Javascript
js添加千分位的实现代码(超简单)
2016/08/01 Javascript
php 修改密码实现代码
2017/05/24 Javascript
js模拟百度模糊搜索的实例
2017/08/04 Javascript
jquery实现限制textarea输入字数的方法
2017/09/06 jQuery
jQuery图片加载失败替换默认图片方法汇总
2017/11/29 jQuery
小程序识别身份证,银行卡,营业执照,驾照的实现
2019/11/05 Javascript
Vue.js中Line第三方登录api的实现代码
2020/06/29 Javascript
Python数据分析之双色球统计单个红和蓝球哪个比例高的方法
2018/02/03 Python
PyQt5实现拖放功能
2018/04/25 Python
pandas.DataFrame选取/排除特定行的方法
2018/07/03 Python
对Python闭包与延迟绑定的方法详解
2019/01/07 Python
pandas把所有大于0的数设置为1的方法
2019/01/26 Python
python打包exe开机自动启动的实例(windows)
2019/06/28 Python
选择Python写网络爬虫的优势和理由
2019/07/07 Python
Python如何用filter函数筛选数据
2020/03/05 Python
Python开发企业微信机器人每天定时发消息实例
2020/03/17 Python
HTML5头部标签的一些常用信息小结
2016/10/23 HTML / CSS
英国珠宝钟表和家居礼品精品店:David Shuttle
2018/02/24 全球购物
Wedgwood英国官方网站:英式精致骨瓷餐具、礼品与生活精品,源于1759年
2019/09/02 全球购物
个人租房协议书
2014/11/28 职场文书
督导岗位职责
2015/02/04 职场文书
餐厅服务员岗位职责
2015/02/09 职场文书
2015年事业单位工作总结
2015/04/27 职场文书
检察院起诉意见书
2015/05/20 职场文书
春晚观后感
2015/06/11 职场文书
元宵节晚会主持词
2015/07/01 职场文书
elasticSearch-api的具体操作步骤讲解
2021/06/28 Java/Android
css3手动实现pc端横向滚动
2022/06/21 HTML / CSS