python3时间序列分析预测
数据来源网上(http://blog.csdn.net/u010414589/article/details/49622625)函数来自数据分析与挖掘和一些自己封装的函数,代码如下:
时间序列分析 步骤:1、检验平稳,2、是否白噪声,3、得到要对平稳时间序列分别求得其自相关系数ACF 和偏自相关系数PACF,得到较佳的阶层 p 和阶数 q,4、建模分析
import pandas as pd import matplotlib.pyplot as plt import statsmodels.api as sm import sys from statsmodels.stats.diagnostic import acorr_ljungbox from statsmodels.tsa.stattools import adfuller as ADF from statsmodels.tsa.arima_model import ARIMA class Arm(): def do(self): 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 = pd.Series(dta).astype(float) dta.index = pd.Index(sm.tsa.datetools.dates_from_range('2001','2090')) self.pw(dta) self.whiteNoise(dta) self.getPq(dta) dd = self.arimaModel(dta) print(dd) # self.error(dta,dd) #检验平稳 def pw(self,data): adf = ADF(data) d = 0 while adf[1] > 0.05: d = d + 1 adf = ADF(data.diff(d).dropna()) print(u'原始序列经过%s阶差分后归于平稳,p值为%s' %(d, adf[1])) #白噪声检验(白噪声数据没有分析的必要) def whiteNoise(self,data): [[lb], [p]] = acorr_ljungbox(data, lags = 1) if p < 0.05: print(u'原始序列为非白噪声序列,对应的p值为:%s' %p) else: print(u'原始该序列为白噪声序列,对应的p值为:%s' %p) [[lb], [p]] = acorr_ljungbox(data.diff().dropna(), lags = 1) if p < 0.05: print(u'一阶差分序列为非白噪声序列,对应的p值为:%s' %p) else: print(u'一阶差分该序列为白噪声序列,对应的p值为:%s' %p) #获取pq参数 def getPq(self,xdata): #定阶 pmax = int(len(xdata)/10) #一般阶数不超过length/10 qmax = int(len(xdata)/10) #一般阶数不超过length/10 bic_matrix = [] #bic矩阵 for p in range(pmax+1): tmp = [] for q in range(qmax+1): try: #存在部分报错,所以用try来跳过报错。 tmp.append(ARIMA(xdata, (p,1,q)).fit().bic) except: tmp.append(None) bic_matrix.append(tmp) bic_matrix = pd.DataFrame(bic_matrix) #从中可以找出最小值 p,q = pd.DataFrame(bic_matrix).astype(float).stack().idxmin() #先用stack展平,然后用idxmin找出最小值位置。 print(u'BIC最小的p值和q值为:%s、%s' %(p,q)) #简历模型预测 def arimaModel(self,xdata): #第一个6和第三个6是getPq()函数得来的,中间的1是多少阶差分稳定pw()函数得来 arima = ARIMA(xdata, (6, 1, 6)).fit() #建立并训练模型 xdata_pred = arima.predict('2091', '2100', dynamic=True) #预测 return self.returnData(xdata.diff(1).dropna(),xdata_pred,xdata[0],10) #计算误差 def error(self,rdata,pdata): #计算误差 abs_ = (rdata - pdata).abs() mae_ = abs_.mean() # mae rmse_ = ((abs_**2).mean())**0.5 # rmse mape_ = (abs_/rdata).mean() # mape print(u'平均绝对误差为:%0.4f,\n均方根误差为:%0.4f,\n平均绝对百分误差为:%0.6f。' %(mae_, rmse_, mape_)) #差分还原(这里是一阶差分还原) def returnData(self,data,pdata,firstData,num): allData = [] result = pd.concat([data,pdata]) indexs = result.index dds = list(result) temp = firstData for dd in dds: temp += dd allData.append(temp) return (pd.DataFrame(allData,index=indexs).iloc[len(allData) - num:,:]) #折线图 def zeixian(self,x,y): plt.figure() plt.plot(y,x,label='y1') #设置x和y轴的名字 plt.xlabel('X') plt.ylabel('Y') #图列 plt.legend(loc='best') #展示 plt.show() if __name__=='__main__': Arm = Arm() Arm.do()