写在最前:===========
大约两周前,阅读《智能运维》这本书,了解到 ARIMA 模型可以根据过去的数据,做预测分析,当时觉得很有意思,但是一直到最近 才真正着手实践,当然 我这个实践也是很粗糙的,更大的意义是通过动手的过程,带来小小的成就感的同时, 检验自己能力上的不足。
理论基础 ===========
ARIMA,Autoregressive Integrated Moving Average model ,差分整合移动平均自回归模型,又称整合移动平均自回归模型(移动也可称作滑动),时间序列预测分析方法
每个时间序列的数据都有自身的特性,而预测分析的关键点在于,确定 ARIMA(p,d,q) 这个模型中 d, p ,q的 合适的数值
d,对序列进行差分处理,处理n次之后,n阶差分序列 比较平稳,没有上升或者下降的趋势,那么d就是n这个阶数。 有时候 指数级别的序列无法直接通过差分的方式获取合适的d值, 但是可以通过 序列整体取log 对数处理之后的序列 进行较少的差分阶数,获取d,比如 https://www.jianshu.com/p/4130bac8ebec 这篇对 湖北的产值的分析 就是这个思路 。
p和 q的取值 我就直接上个图吧 , 理解很简单 说起来很麻烦
不过, 有时候 p q,经过 acf 和pacf 两个数据集获取之后,最好经过 一下集中模型进行一下 残差检验 ,为什么这么做,这超出我的能力范围了,建议搭建 看我上边给的 jianshu链接文档。
* AIC=-2 ln(L) + 2 k 中文名字:赤池信息量 akaike information criterion
* BIC=-2 ln(L) + ln(n)*k 中文名字:贝叶斯信息量 bayesian information criterion
* HQ=-2 ln(L) + ln(ln(n))*k hannan-quinn criterion
本文当中代码这个案例,我目测用 7,1 比较合适,但是 残差测试 结果 好像8,0会更小 ,
应用场景======================
--普遍适用于 各种以时间作为索引的序列数据,比如销售额,交通流量统计,医院患者人数等等,也有用它做股票分析,结果当然也就那样。 我个人理解,数据场景如果约封闭,也就意味着容易受到单一因素的变化而产生巨变这种,明显不适合, 或者时间段太短, 周期不固定,其实都会影响该模型的可用性,
python环境关键点===================
包括 numpy,pandas,matplotlib等常用数据分析模块, 有一定使用基础,肯定会帮助理解程序的过程。 当然 import statsmodels.api as sm ,这个模型工具包,我也是直接粘贴过来用,里边的什么函数,以后慢慢研究了。 另外就是,过程当中,经常会提示 本地某个模块将会在最新的python3 模块中被废弃, 实际上 ,暂时不会影响当前程序的执行。 强烈推荐使用 anaconda 3的 python安装集合,全家桶的方式省去很多麻烦。不用纠结python3和2的共存问题, 数据分析类的程序,现在98
% 都是python3了。
其他问题===========================
这次,我发现,不管是np pd 的使用,还是mpl得绘图的使用, 都还有提升的必要, 另外,预测分析后边是经过反复实践的,一方面是 日常的运维工作,也包括 日常的生活学习,暂时还是要采取 用到什么就学习什么的大体思路, 毕竟数据分析 和建模这个大坑之大,对于我这个自然选择号 ,也如无法挣脱的黑洞。 python的基本还是要多多提升一下。
相关参考:
1 ,https://blog.csdn.net/wenyusuran/article/details/82143978
# 我直接借用了该博主的程序和结论, 该博主是从 源网站直接阅读文档 (http://statsmodels.sourceforge.net/devel/examples/notebooks/generated/tsa_arma_0.html)自己进行的实验,其实为我们这些后来人,排除了很多困难
2,
3,
上午 看的 2和3 这两篇文章,确定 d, p ,q的思路和方法
正文 请看 代码和 执行结果 ================
我建议 还是去看人家博主的文章吧
# -*- coding:utf-8 -*- from __future__ import print_function import pandas as pd import numpy as np from scipy import stats import matplotlib.pyplot as plt import statsmodels.api as sm from statsmodels.graphics.api import qqplot dta=[10930,10318,10595,10972,7706,6756,9092,10551,9722,10913,11151,8186,6422,6337,11649,11652,10310,12043,7937,6476,9662,9570,9981,9331,9449,6773,6304,9355,10477,10148,10395,11261,8713,7299,10424,10795,11069,11602,11427,9095,7707,10767,12136,12812,12006,12528,10329,7818,11719,11683,12603,11495,13670,11337,10232, 13261,13230,15535,16837,19598,14823,11622,19391,18177,19994,14723,15694,13248,9543,12872,13101,15053,12619,13749,10228,9725,14729,12518,14564,15085,14722,11999,9390,13481,14795,15845,15271,14686,11054,10395] dta=np.array(dta,dtype=np.float) #dta dta=pd.Series(dta) dta.index = pd.Index(sm.tsa.datetools.dates_from_range('2001','2090')) dta.plot(figsize=(12,8)) #plt.show() # 一介差分 ''' fig=plt.figure(figsize=(12,8)) ax1=fig.add_subplot(211) diff1=dta.diff(1) diff1.plot(ax=ax1) fig=plt.figure(figsize=(12,8)) ax2=fig.add_subplot(212) diff2=diff1.diff(1) diff2.plot(ax=ax2) ''' #plt.show() # 二阶效果平稳 后边看 p,q的 情况 """ fig=plt.figure(figsize=(12,8)) ax1=fig.add_subplot(211) fig = sm.graphics.tsa.plot_acf(dta,lags=40,ax=ax1) ax2 = fig.add_subplot(212) fig=sm.graphics.tsa.plot_pacf(dta,lags=40,ax=ax2) plt.show() """ # 从图上看 我会基本选定为q=7 或者8,p=1或者0 arma_mod70 = sm.tsa.ARMA(dta,(7,0)).fit() print(arma_mod70.aic,arma_mod70.bic,arma_mod70.hqic) arma_mod71 = sm.tsa.ARMA(dta,(7,1)).fit() print(arma_mod71.aic,arma_mod71.bic,arma_mod71.hqic) arma_mod80 = sm.tsa.ARMA(dta,(8,0)).fit() print(arma_mod80.aic,arma_mod80.bic,arma_mod80.hqic) # 我的结果也是和转载者的一样 其实是8-0 这种模型的拟合效果最好 # 检验残差序列 """ resid=arma_mod80.resid fig = plt.figure(figsize=(12,8)) ax1 = fig.add_subplot(211) fig = sm.graphics.tsa.plot_acf(resid.values.squeeze(), lags=40, ax=ax1) ax2 = fig.add_subplot(212) fig = sm.graphics.tsa.plot_pacf(resid, lags=40, ax=ax2) plt.show() """ # 预测 predict_dta = arma_mod80.predict('2090', '2100', dynamic=True) print(predict_dta) fig,ax=plt.subplots(figsize=(12,8)) ax=dta.ix['2000':].plot(ax=ax) fig=arma_mod80.plot_predict('2090','2100',dynamic=True,ax=ax,plot_insample=False) plt.show() print('ok')