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()