统计学-时间序列分析实践

目标是预测未来三期传统汽车的销量。
数据背景:
03年到19年第一季度分季度的数据,13年之前只有传统汽车的销量,13年之后是传统汽车+新能源汽车的销量,需要预测未来三期传统汽车的销量~
ps:传统汽车的销量会受到新能源汽车的影响噢~
(我们先针对传统销量进行时间序列预测,不考虑新能源汽车)

import numpy as np
import pandas as pd
import datetime 
import matplotlib.pyplot as plt
import statsmodels.api as sm
from dateutil.relativedelta import relativedelta
from statsmodels.tsa.seasonal import seasonal_decompose
#首先处理下数据
data=pd.read_excel("/Downloads/data.xlsx",index_col=0)
print(data.head(10))
data.index.name = None  # 将index的name取消
data.reset_index(inplace=True)
data.drop(data.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
data['index'] = date_list
data.set_index(['index'], inplace=True)
print(data.head(10))
 传统汽车销量  国内生产总值当季值(亿元)x1    ...      汽车整车股票指数    消费者信心指数
index                                  ...                         
2003-01-01   102.1          29825.5    ...       1696.81  97.700000
2003-04-01   110.0          32537.3    ...       1912.54  87.666667
2003-07-01   112.1          35291.9    ...       1803.71  92.333333
2003-10-01   122.8          39767.4    ...       1922.48  94.666667
2004-01-01   131.1          34544.6    ...       1930.71  95.333333
2004-04-01   133.3          38700.8    ...       1245.70  92.566667
2004-07-01   121.0          41855.0    ...       1163.16  91.066667
2004-10-01   123.7          46739.8    ...        870.61  92.566667
2005-01-01   139.7          40453.3    ...        749.62  93.933333
2005-04-01   162.2          44793.1    ...        764.84  94.533333
data1 = np.array(data['传统汽车销量'], dtype=np.float)
# 生成时间序列并画图
data1 = pd.Series(data1)
data1.index = data.index
# 趋势
data1.plot(figsize=(12, 8), title='传统汽车销量')
传统汽车销量趋势.png

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

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

具有明显的季节性波动,ARIMA 模型对时间序列的要求是平稳型。因此,当得到一个非平稳的时间序列时,首先要做的即是做时间序列的差分,直到得到一个平稳时间序列。
将数据平稳化,用简单的二阶差分:

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

模型选择

arma_mod70 = sm.tsa.ARMA(data1,(7,0)).fit()
print(arma_mod70.aic,arma_mod70.bic,arma_mod70.hqic)
arma_mod30 = sm.tsa.ARMA(data1,(0,1)).fit()
print(arma_mod30.aic,arma_mod30.bic,arma_mod30.hqic)
arma_mod71 = sm.tsa.ARMA(data1,(7,1)).fit()
print(arma_mod71.aic,arma_mod71.bic,arma_mod71.hqic)
arma_mod80 = sm.tsa.ARMA(data1,(8,0)).fit()
print(arma_mod80.aic,arma_mod80.bic,arma_mod80.hqic)
741.7064371640738 761.1363849143108 749.3608750397088
824.035997236598 830.512646486677 826.5874765284763
744.7216708631242 766.310501696721 753.226601836052
742.0032319184199 763.5920627520167 750.5081628913478

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

predict_dta = arma_mod70.predict('2019', '2022', dynamic=True)
print(predict_dta)
fig, ax = plt.subplots(figsize=(12, 8))
ax = data1.ix['2000':].plot(ax=ax)
fig = arma_mod70.plot_predict('2019', '2022', dynamic=True, ax=ax, plot_insample=False)
传统汽车销量预测.png
2019-01-01    713.995452
2019-04-01    621.508277
2019-07-01    595.797997
2019-10-01    637.025889
2020-01-01    647.507010
2020-04-01    620.106297
2020-07-01    594.112870
2020-10-01    597.800678
2021-01-01    613.221781
2021-04-01    605.209659
2021-07-01    585.717920
2021-10-01    581.768503
2022-01-01    587.753080

参考:《统计学(第七版)》贾俊平
(https://mp.weixin.qq.com/s/Whq2djsu6jhMmlgoLLNSEw)

你可能感兴趣的:(统计学-时间序列分析实践)