php是最好的语言

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


作者:xTao 分类:LNMP 浏览:2456 评论:0