前言
前两篇主要介绍了一些线性模型AR/MA/ARMA/ARIMA。这篇主要介绍时间序列的季节模型。
1.《金融时间序列分析》 第2版 Ruey S.Tsay著 王辉、潘家柱 译2.TimeSeriesAnalysisTsa (附带Python代码)
六、季节模型
6.1 季节性时间序列
有些时间序列呈现出一定的循环或周期性,这样的时间序列叫季节性时间序列。 下面我们以月入境旅游人数数据为例,看看序列是不是具有季节性
如何计算账期天数,统计相关的库import numpy as npimport pandas as pdimport matplotlib.pyplot as plt
temp = DataAPI.EcoDataProGet(&39;,&39;,&39;)temp = temp.set_index(&39;)temp = temp.sort()temp[&39;].plot(figsize=(15,6),grid=True)
可以看出,序列看上去有着季节性,我们在看看每年的情况
compare={}for index in temp[&39;].index:year = index[:4]month = index[5:7]if year not in compare.keys():compare.update({year:{month:temp[&39;][index]}})else:compare[year].update({month:temp[&39;][index]})compare = pd.DataFrame(compare) compare.plot(figsize=(20,6))plt.legend(loc=0)
除了部分月份有一定偏差,序列整体的走势非常相似,那么可以说明有季节性么?我们先了解下季节指数
6.1.1 季节指数
所谓季节指数就是用简单平均法计算的周期内各时期季节性影响的相对数。
首先计算周期内各期平均数
然后计算总平均数
再计算季节指数
季节指数反映了该季度与总平均值之间的一种比较稳定的关系:
如果比值大于1,说明该季度的值常常会高于总平均值;
如果比值小于1,说明该季度的值常常低于总平均值;
如果序列的季节指数都近似为1,就说明该序列没有明显的季节性。
我们来计算一下上面数据的季节指数:
账期是指从生产商、批发商向零售商供货后,直至零售商付款的这段时间周期。 比如企业销售货物给客户,从货物出库,转移对应的风险和单据之后,到客户实际给完全款的时间,比如销售货物是5月1日,实际支付款项是7月31日,则。
ave_k = compare.mean(axis=1)ave = ave_k.mean()compare[&39;] = ave_k/avecompare
可以看出,虽然看上去具有季节性,但根据季节指数来看,季节指数除了2月份以外几乎全都接近1,序列的季节性很弱,不利于后面的建模。
好吧,看来只好我自己造一组数据了。
T = np.array([4,7,8,4,1,1,3])data = Tfor i in range(1,20):x = T + idata = np.append(data,x)plt.figure(figsize=(10,6))plt.plot(data)
再来看看它的季节指数:
ave = data.mean()term = len(T)numOfTerm = len(data)/len(T)S = []for i in range(term):s = 0for j in range(numOfTerm):s += data[i+j*term]S.append(s/numOfTerm)S = S/aveS
array([ 0.96296296,1.18518519,1.25925926,0.96296296,0.74074074,0.74074074,0.88888889])
可以看出,这次的季节指数比刚刚明显多了。
6.2 季节性差分
在之前我们介绍过差分(正规差分化),其形式为:
我们将它推广,如果一个序列具有周期性,且周期为s,则季节性差分化为:
我们以第一个上序列为例(旅游的),周期为12,我们进行季节性差分试试:
dataDiff = temp[&39;].diff(12)[12:]dataDiff.plot(figsize=(15,6))
应该是6月15日,因为拿货日期是从4月1日到30日是一个周期,一个周期结束后,计算约定账期(45天),如果5月15日收款的话,账期就成了15天了。账期是指从生产商、批发商向零售商供货后,直至零售商付款的这段时间周期。 在。
可以看出,季节性基本上被消除,但是序列不够平稳,我们不妨再做1阶差分看看
diffdiff = dataDiff.diff()[1:]diffdiff.plot(figsize=(15,6)
t = sm.tsa.stattools.adfuller(diffdiff)34;p-value: ",t[1]
p-value: 2.e-12
经过ADF检验,我们发现p-value小于显著性水平0.05,序列是平稳的。
6.3 多重季节性模型
上一节中,经过了季节性差分和正规差分后,序列成为了平稳时间序列,则我们可以用MA模型对多重差分后的模型建模。则我们有模型:
其中,B为向后推移算子,代表前一时刻的值。B的s次方则为前s时刻的值。{at}为白噪声序列,s为序列的周期。上述模型为航空模型。
另外,序列经过了季节性差分和正规差分消除序列相关性(序列平稳),则可以认为是间隔s和间隔1的周期共同影响,因此该模型称为多重季节性MA模型
6.3.1 建模
由于statsmodels中没有找到直接对序列建立季节模性的函数。我们使用参数估计的方式来建模。我们以一开始的旅游数据为例
如何进行参数估计?首先记:
根据白噪声性质,我们计算序列的方差与协方差如下:
接着,我们计算{ωt}的这三个参数:
花呗的账单日期在消费次月的第一天,在那一天账单会计入前一月所产生的所有消费金额。另外,花呗的还款日期也是在次月,具体时间是次月
ACF1 -0.55
ACF12 -0.331684718252
我们知道,我们的s为12,根据公式:
两个自相关系数为:
然后我们根据之前推出的3个等式,代入Var,Cov1,Cov12,解3个方程的方程组。最终可归结为求两个二元一次方程:
# 求二元一次方程,返回绝对值大于1的解def calc(a,b,c):if b**2-4*a*c<0:return np.nanelif b**2-4*a*c==0:return -b/(2*a)else:if abs((-b+(b**2-4*a*c)**(1/2))/(2*a))<1 :return (-b+(b**2-4*a*c)**(1/2))/(2*a)elif abs((-b-(b**2-4*a*c)**(1/2))/(2*a))<1:return (-b-(b**2-4*a*c)**(1/2))/(2*a)else:return np.nanprint var/cov_1,var/cov_12theta = calc(1,var/cov_1,1)Theta = calc(1,var/cov_12,1)print theta,Theta
-1.81686882383 -3.
nan nan
未能求出满足要求的θ和Θ的值。。。也就是序列难以用以上模型表达,即使用其他方法求出最优估计,应该满足的3条性质也无法满足
另一方面,在求季节指数时我们发现该序列季节性不强,这也是原因之一。
下面我们介绍其他模型。
6.4 综合分析模型(加法模型、乘法模型、混合模型)
通常时间序列包括3个因素:
趋势因素T
季节性因素S
不规则因素I
有时候也会加入周期要素C,我们这里将它归为季节性因素
常用的综合分析模型有:
加分模型
乘法模型
混合模型
6.4.1 建模
我们之前分析过,旅游数据的季节指数显示没有明显的季节性。因此我们这里以自己构造的数据为例。
T = np.array([4,7,8,4,1,1,3])data = Tfor i in range(1,20):temp = T + idata = np.append(data,temp)plt.figure(figsize=(10,6))plt.plot(data)
我们选用加法模型来试试:
收款三个月账期算时间的方法:账期是指从生产商、批发商向零售商供货后,直至零售商付款的这段时间周期。生产商或批发商在规定时间内给予零售商一定金额的信用额度,零售商在信用额度内不用付款就可以进货,但是在规定时间内。
先分离季节性,我们可以看出周期为7,用移动平均来滤波
seasonRemove = pd.rolling_mean(data,7)st = data - seasonRemoveplt.figure(figsize=(10,5))plt.plot(seasonRemove,label = &39;)plt.plot(st,label = &39;)plt.legend(loc=0)
对于去除季节性后的序列,我们用最小二乘来拟合:
from sklearn import linear_modeltrain = np.mat(range(7,len(seasonRemove))).Tclf = linear_model.LinearRegression()clf.fit(train,seasonRemove[7:])k = clf.coef_print &39;,kx = range(7,len(seasonRemove))y = k*x b = (seasonRemove[7:] - y).mean()print &39;,b y = y +bplt.figure(figsize=(10,6))plt.plot(x,y,label=&39;)plt.plot(seasonRemove,label=&39;)plt.legend(loc=0)
k = [ 0.14285714]
应收账款账期是指给对方的付款期限,比如20天,一般和现金折扣结合起来,成为企业的应收账款信用政策。应收账款是指企业在正常的经营过程中因销售商品、产品、提供劳务等业务,应向购买单位收取的款项,包括应由购买单位或接受。
b = 3.
有
拟合效果很好, 接着根据残差计算
It=[]for i in range(len(seasonRemove[7:])):It.append(y[i]-seasonRemove[7+i])plt.figure(figsize=(10,6))plt.plot(It,label=&39;)plt.legend()
看残差我们发现,虽然很小,量级为e-15,但不是平稳的,随着序列继续推进,误差渐渐变大。不过也可能是计算性能上的误差。
建设银行信用卡账单日一般可在每月的2、5、7、10、12、15、17、19、22、23、24、25、26及27日,不过账单日每年只可以修改一次。信用卡的账单日,是银行每个月结算持卡人账单日之前(包括账单日)消费还款情况的日子,。
可以看出,加法模型很适合这个序列,可以有效分为趋势和季节两种特征。
6.4.2 分解
利用sm.tsa.seasonal_decompose,可以直接将时间序列分解为趋势、季节和残差,并有加法模型和乘法模型两种模式可选。以上面的数据为例
result = sm.tsa.seasonal_decompose(np.array(data),model=&39;,freq=1) 39;Original&39;Trend&39;Seasonality&39;Residuals')plt.legend(loc=0)
小结
本篇简单介绍了季节模型,由于书上太偏理论而且讲的内容太少,所以这篇写起来相当费劲儿,python可用的现成模型也少。都是网上查阅资料写的。
个人感觉季节模型最重要的是如何分离出季节特征,其中加法模型最常用,本篇也只举了简单的例子。想要深入还得继续研究。