时间序列实践

Q:

03年到19年第一季度分季度的数据,13年之前只有传统汽车的销量,13年之后是传统汽车+新能源汽车的销量,需要预测未来三期传统汽车的销量~ps:传统汽车的销量会受到新能源汽车的影响.

 

import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_excel("C:\orange_credit\crdt\时序数据.xlsx", sheet_name='Sheet2', index_col=u'日期')

#先画出日期和传统车型销量的图形,可以判断是非平稳的
data.plot()
plt.show()


df.index.name = None  # 将index的name取消
df.reset_index(inplace=True)
df.drop(df.index[64], inplace=True)
start = datetime.datetime.strptime("2003-01", "%Y-%m")  # 把一个时间字符串解析为时间元组
date_list = [start + relativedelta(months=x*3) for x in range(0, 64)]  # 从2003-01-01开始逐月增加组成list
df['index'] = date_list
df.set_index(['index'], inplace=True)

先看传统汽车整体趋势:

dta = np.array(df['传统汽车销量'], dtype=np.float)
# 生成时间序列并画图
dta = pd.Series(dta)
dta.index = df.index
# 趋势
dta.plot(figsize=(12, 8), title='Monthly Total Traditional Car')






有明显的递增趋势,可以判断是非平稳的,再来看看是否有季节性:

decomposition = seasonal_decompose(df['传统汽车销量'], freq=12)
fig = plt.figure()
fig = decomposition.plot()
fig.set_size_inches(15, 8)





可以看到有明显季节性波动,需要将数据平稳化,这里我用简单的二阶差分进行(这里可以配合季节性差分进行测试(shift(12) ),最终选择差分方式)

fig = plt.figure(figsize=(12, 8))
ax2 = fig.add_subplot(111)
diff2 = dta.diff(2)
diff2.plot(ax=ax2)





可以看到效果还可以。基础上还可以进行根检验:

sm.tsa.stattools.adfuller(diff2[2:]

 
如何确定差分阶数和常数项:
  1. 假如时间序列在很高的lag(10以上)上有正的ACF,则需要很高阶的差分

  2. 假如lag-1的ACF是0或负数或者非常小,则不需要很高的差分,假如lag-1的ACF是-0.5或更小,序列可能overdifferenced。BEWARE OF OVERDIFFERENCING

  3. 最优的差分阶数一般在最优阶数下标准差最小(但并不是总数如此)

  4. 模型不差分意味着原先序列是平稳的;1阶差分意味着原先序列有个固定的平均趋势;二阶差分意味着原先序列有个随时间变化的趋势

  5. 模型没有差分一般都有常数项;有两阶差分一般没常数项;假如1阶差分模型非零的平均趋势,则有常数项

如何确定AR和MA的阶数:
  1. 假如PACF显示截尾或者lag-1的ACF是正的(此时序列仍然有点underdifferenced),则需要考虑AR项;PACF的截尾项表明AR的阶数

  2. 假如ACF显示截尾或者lag-1的ACF是负的(此时序列有点overdifferenced),则需要加MA项,ACF的截尾项表明AR的阶数

  3. AR和MA可以相互抵消对方的影响,所以假如用AR-MA模型去拟合数据,仍然需要考虑加些AR或MA项。尤其在原先模型需要超过10次的迭代去converge。BEWARE OF USING MULTIPLE AR TERMS AND MULTIPLE MA TERMS IN THE SAME MODEL.

  4. 假如在AR部分有个单位根(AR系数和大约为1),此时应该减少一项AR增加一次差分

  5. 假如在MA部分有个单位根(MA系数和大约为1),此时应该减少一项AR减少一次差分

  6. 假如长期预测出现不稳定,则可能AR、MA系数有单位根

如何确定季节性部分:
  1. 假如序列有显著是季节性模式,则需要用季节性差分,但是不要使用两次季节性差分或总过超过两次差分(季节性和非季节性)

  2. 假如差分序列在滞后s处有正的ACF,s是季节的长度,则需要加入SAR项;假如差分序列在滞后s处有负的ACF,则需要加入SMA项,如果使用了季节性差异,则后一种情况很可能发生,如果数据具有稳定和合乎逻辑的季节性模式。如果没有使用季节性差异,前者很可能会发生,只有当季节性模式不稳定时才适用。应该尽量避免在同一模型中使用多于一个或两个季节性参数(SAR + SMA),因为这可能导致过度拟合数据和/或估算中的问题。

接下来寻找最优p,q值组合:

arma_mod70 = sm.tsa.ARMA(dta, (7, 0)).fit()
print(arma_mod70.aic, arma_mod70.bic, arma_mod70.hqic)
arma_mod30 = sm.tsa.ARMA(dta, (0, 1)).fit()
print(arma_mod30.aic, arma_mod30.bic, arma_mod30.hqic)
arma_mod80 = sm.tsa.ARMA(dta, (8, 0)).fit()
print(arma_mod80.aic, arma_mod80.bic, arma_mod80.hqic)
结果如下

754.1050637800771 773.6745492091378 761.8264803250283

835.8762241876609 842.3993859973478 838.4500297026447

754.4743430156554 776.2182157146118 763.0536947322679

可以看出ARMA(8,0) 和ARMA(7,0) 是差不多的 ,这里选择两个对结果没有太大影响。

最后可以进行预测了


# 预测
predict_dta = arma_mod80.predict('2019', '2021', dynamic=True)

print(predict_dta)

fig, ax = plt.subplots(figsize=(12, 8))

ax = dta.ix['2000':].plot(ax=ax)

fig = arma_mod80.plot_predict('2019', '2021', dynamic=True, ax=ax, plot_insample=False)

预测结果


2019-01-01    713.995946


2019-04-01    621.508451


2019-07-01    595.797886


2019-10-01    637.026010


2020-01-01    647.507366


2020-04-01    620.106670


2020-07-01    594.113071


2020-10-01    597.800788


2021-01-01    613.222166

 

 

转自:https://mp.weixin.qq.com/s/Whq2djsu6jhMmlgoLLNSEw

 

posted @ 2020-03-08 10:55  yancheng111  阅读(430)  评论(0编辑  收藏  举报