1.时间序列分解的作用和意义
时间序列通常包括如下几种成分:
一个时间序列包含三种影响因素:
长期趋势:在一个相当长的时间内表现为一种近似直线的持续向上、向下或平稳的趋势。
季节变动:受季节变化影响所形成的一种长度和幅度固定的短期周期波动
周期变动:与季节变动类似,但是波动的时间频率不是固定的,通常在时间序列分解中与长期趋势结合成为趋势周期项
不规则变动:受偶然因素的影响所形成的不规则波动,如股票市场受利好或者利空信息的影响,使得股票价格产生的波动
在进行时间序列预测时,时间序列分解可以更直观地查看时间序列的成分,将时间序列数据分解为趋势项、季节项和残差项,后续则可以单独对各项进行时间序列预测并合并。
2.时间序列分解的方法
目前时间序列分解的方法主要包括经典分解法、X11分解法、SEATS分解法、STL分解法、fbprophet分解法等,本文选择STL分解法进行分解。
STL分解法:STL是一种多功能、鲁棒的方法。全称“Seasonal and Trend decomposition using Loess”,其中Loess是一种鲁棒的回归算法。
特点:
- 与SEATS与X11不同,STL可以处理任意季节性数据,而非局限于月度或季度数据
- 季节部分可以随时间变化,变化率可以由用户控制。STL的一大特点便是提供对季节性的单独乘法趋势,可以在采用加法型模型时,使加上去的趋势的幅度不断扩大。且该变化率是自动检测的。
- 趋势周期的平滑度可以由用户控制
- 可以对异常值鲁棒(使异常值不影响季节部分与趋势部分,但是影响残差),代码中一般有robust=True/False控制。
缺点:
- 不能自动处理节假日
- 只能进行加性分解
3.STL分解
在进行分解前,你需要知道的部分参数包括:
period:表示季节性的周期,也就是时间索引的周期,如果原始数据是pandas的series 或dataframe形式代码能够自行判断此参数,但建议自行设置。
season: 表示季节性平滑器的长度,它必须是一个奇数,通常要>=7(默认)。
trend:表示趋势平滑器的长度,通常要>period(或season)的1-1.5倍,并且它必须是一个奇数。默认值是最小的1-1.5倍的period,比如period=7则trend默认值是9,如果period=12则trend默认值是13
使用的库:statsmodels、pandas、seaborn、matplotlib、pylab
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt from statsmodels.tsa.seasonal import STL import statsmodels.api as sm import pylab from pylab import mpl
#导入包的时候比较乱,请见谅.... mpl.rcParams['font.sans-serif'] = ['SimHei']#此步骤是为了解决字体问题 plt.rcParams['axes.unicode_minus']=False#此步骤是为了解决字体问题 plt.rc("figure", figsize=(10, 6))#设置绘图区尺寸 for x in []:#在中括号中输入的是季节平滑器的长度,输入多个则分别导出不同参数下的结果,也可相应修改,添加其他参数 df=pd.read_csv('C:/Users/Administrator/Desktop/STL.csv',encoding='ANSI',usecols=['time', 'value'],index_col='time') #读取原始数据,这里的time,value是原始数据中的列标签名,此外encoding参数需要根据csv的编码确认,usecols选择使用的列,index_col参数选择索引列 print(df)#查看读取好的文件 stl=STL(df,period=12,seasonal=x,robust=False)#因为原始数据是月度数据,这里手动设置了period=12,robust为True时会用一种更严格的方法来约束trend和season,同时也会导致更大的resid res=stl.fit() res.plot() plt.savefig("D:/figures2/{}.png".format(x))#保存STL分解结果图 plt.clf()#清空绘图区防止重复绘图 df['trend']=res.trend#保存分解后数据 df['seasonal']=res.seasonal df['resid']=res.resid dataframe = pd.DataFrame({'trend':df['trend'],'season':df['seasonal'],'resid':df['resid']})#将分解结果按照列导入csv文件 dataframe.to_csv("D:/figures2/{}table.csv".format(x),sep=',') print('residual mean:',df.resid.mean())#查看残差正态性检验的均值 mean=df.resid.mean() sns.distplot(df.resid)#绘制带正态曲线的概率密度直方图 plt.savefig("D:/figures2/{}mean={}.png".format(x,mean)) plt.clf() sm.qqplot(df.resid, line='s')#绘制正态检验QQ图 plt.savefig("D:/figures2/{}QQ.png".format(x))
代码中除了对原始数据进行读取和STL分解外,还包括了如下几个步骤:
(1)将分解后的数据导入至csv文件中以便后续分析和绘图
(2)绘制残差项的直方图和QQ图,判断残差正态性(只有残差项通过正态性检验才说明分解有效)
标签:以验潮,为例,STL,df,分解,序列,resid,trend From: https://www.cnblogs.com/Vicrooor/p/17382822.html