作业:
数据背景:
03年到19年第一季度分季度的数据,13年之前只有传统汽车的销量,13年之后是传统汽车+新能源汽车的销量,
问题1:需要预测未来三期传统汽车的销量。ps:传统汽车的销量会受到新能源汽车的影响噢~
思路:根据学习,我们按照如下流程进行处理。
1.判断是否存在趋势?
根据EXCEL数据生成数据透视表,然后生成如下折现图,透过下图可以看到,是存在明显上升趋势的,且非平稳上升(因2019年只存在一季度数据,此处忽略2019年)
2.是否存在季节性
如图,是存在一定季节性波动的,需将其平稳化
此处借鉴 数据咆哮大师 文章中的二阶差分进行平稳化
补充学习参考 时间序列实战(一)_Python_困而学之,学思并重-CSDN博客
import pandasas pd
import datetime
from dateutil.relativedeltaimport relativedelta
import numpyas np
from statsmodels.tsa.seasonalimport seasonal_decompose
import matplotlib.pyplotas plt
df = pd.read_excel(r'D:\Users\Downloads\时序数据1.xlsx',index_col=0)
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 xin 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')
plt.show()
#输出如下图:
#有明显的递增趋势,可以判断是非平稳的,再来看看是否有季节性:
decomposition = seasonal_decompose(df['传统汽车销量'], freq=12)
fig = plt.figure()
fig = decomposition.plot()
fig.set_size_inches(15, 8)
plt.show()
#可以看到有明显季节性波动,需要将数据平稳化,这里我用简单的二阶差分进行(这里可以配合季节性差分进行测试(shift(12) ),最终选择差分方式)
fig = plt.figure(figsize=(12, 8))
ax2 = fig.add_subplot(111)
diff2 = dta.diff(2)
diff2.plot(ax=ax2)
plt.show()
#可以看到效果还可以#基础上还可以进行根检验:
补充:
如何确定差分阶数和常数项:
假如时间序列在很高的lag(10以上)上有正的ACF,则需要很高阶的差分
假如lag-1的ACF是0或负数或者非常小,则不需要很高的差分,假如lag-1的ACF是-0.5或更小,序列可能overdifferenced。BEWARE OF OVERDIFFERENCING
最优的差分阶数一般在最优阶数下标准差最小(但并不是总数如此)
模型不差分意味着原先序列是平稳的;1阶差分意味着原先序列有个固定的平均趋势;二阶差分意味着原先序列有个随时间变化的趋势
模型没有差分一般都有常数项;有两阶差分一般没常数项;假如1阶差分模型非零的平均趋势,则有常数项
如何确定AR和MA的阶数:
假如PACF显示截尾或者lag-1的ACF是正的(此时序列仍然有点underdifferenced),则需要考虑AR项;PACF的截尾项表明AR的阶数
假如ACF显示截尾或者lag-1的ACF是负的(此时序列有点overdifferenced),则需要加MA项,ACF的截尾项表明AR的阶数
AR和MA可以相互抵消对方的影响,所以假如用AR-MA模型去拟合数据,仍然需要考虑加些AR或MA项。尤其在原先模型需要超过10次的迭代去converge。BEWARE OF USING MULTIPLE AR TERMS AND MULTIPLE MA TERMS IN THE SAME MODEL.
假如在AR部分有个单位根(AR系数和大约为1),此时应该减少一项AR增加一次差分
假如在MA部分有个单位根(MA系数和大约为1),此时应该减少一项AR减少一次差分
假如长期预测出现不稳定,则可能AR、MA系数有单位根
如何确定季节性部分:
假如序列有显著是季节性模式,则需要用季节性差分,但是不要使用两次季节性差分或总过超过两次差分(季节性和非季节性)
假如差分序列在滞后s处有正的ACF,s是季节的长度,则需要加入SAR项;假如差分序列在滞后s处有负的ACF,则需要加入SMA项,如果使用了季节性差异,则后一种情况很可能发生,如果数据具有稳定和合乎逻辑的季节性模式。如果没有使用季节性差异,前者很可能会发生,只有当季节性模式不稳定时才适用。应该尽量避免在同一模型中使用多于一个或两个季节性参数(SAR + SMA),因为这可能导致过度拟合数据和/或估算中的问题。
接下来寻找最优p,q值组合:
from statsmodels.tsa.stattoolsimport adfuller
adfuller(diff2[2:])
import statsmodels.apias sm
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)
#可以看出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)
plt.show()
#对拟合效果进行评估
tempModel = sm.tsa.ARMA(dta, (8, 0)).fit()
delta = tempModel.fittedvalues - dta
score =1 - delta.var()/dta.var()
print("评估分数为:",score)
网友评论