赞
踩
一、目标
销售数据是随着时间变化的序列,通过对未来的销售进行预测,方便对人员、物料等各种资源投入的把控,控制好库存,减少浪费,也可以制定未来的营运策略,提高管理效率。
这里使用ARMA(AutoRegressive Moving Average)算法,不仅与前P期的序列值有关,也与前q期的随机扰动有关。
二、数据采集和处理
1.数据采集
采集随着时间变化的销售数据,为了数据保护需要,销售数据做了特殊处理,不代表真实销售。
2.平稳性检验
平稳ARMA(p,q)的均值和方差都是常数,用什么模型主要看自相关系数和偏自相关系数。如果自相关拖尾,偏自相关截尾,即p<>0 &q=0 则用AR,反之MA,如果p阶拖尾,q阶也拖尾,则ARMA。p代表周期、q代表噪音。
这里采用两种方法来检验:
a.画时序图
通过时序图可以发现数据是平稳的。
b.画自相关图
x 轴表示滞后值,y 轴上 -1 和 1 之间则表现了这些滞后值的正负相关性。蓝色区域为置信区间,默认情况下,置信区间这被设置为95%,这表明,这段代码之外的相关值很可能是相关的,而不是统计上的意外。滞后值为 0 相关性为 1 的点表示观察值与其本身 100% 正相关。自相关系数会很快衰减向0,所以可认为是平稳序列
c.单位根ADF检验的方法。如果存在单位根,则说明是非平稳时间序列
可以看出这里的ADF结果为-4.3, p-value小于0.05, 1%的结果-3.45>ADF的结果-4.3,所以说明极其显著拒绝原假设,不存在单位根,所以可以得出结论本数据是平稳的。
3.随机性检验
可以看出延迟1期后,p值为3.87e-19小于0.05,因此95%可以拒绝原假设,认为该序列为非白噪声序列,有信息可以提取。
代码
- import pandas as pd
- import matplotlib.pyplot as plt
- from statsmodels.tsa.stattools import adfuller as ADF
- from statsmodels.stats.diagnostic import acorr_ljungbox
- #画时序图
- data=pd.read_excel(r'C:\Users\Administrator\Desktop\data.xlsx')
- data.day=pd.to_datetime(data.day)
- plt.plot(data.day,data.sales)
- plt.xlabel('day')
- plt.ylabel('sales')
- plt.title('Time Series')
- plt.show()
- #平稳性检测
- print('ADF result is',ADF(data.sales))
- #纯随机检查
- print('纯随机检查结果为',acorr_ljungbox(data.sales,lags=1)) #lags表示延迟期数
三、建模
计算ARMA(p,q)
这里采用BIC(贝叶斯信息量 bayesian information criterion ) = -2 ln(L) + ln(n)*k来定阶段
为了节省运算时间(其实也消耗了很多时间),这里p最大设置为10,q最大设置为6
- from statsmodels.tsa.stattools import arma_order_select_ic
- print('BIC求解的模型阶次为',arma_order_select_ic(data.sales,max_ar=10,max_ma=6,ic='bic')['bic_min_order'])
这个过程相当耗时,可以看到这里输出是1,0,所以选用ARMA(1,0)这个模型。
- model = ARMA(data.sales,(1,0)).fit()
- print(model.summary2()) #给出一份模型报告
- print(model.forecast(10)) #作为期10天的预测,返回预测结果、标准误差、置信区间。
看看误差有多少
forcast=pd.DataFrame(model.forecast(10)[0],index=x,columns=['forcastsales']) #作为期10天的预测,返回预测结果、标准误差、置信区间。 actual=pd.DataFrame(list(file.iloc[90:100].sales),index=x,columns=['actualsales']) delta=((forcast.forcastsales-actual.actualsales)/actual.actualsales).mean()*100 print('误差为%0.2f%%'%delta)
完整代码:
- import pandas as pd
- import matplotlib.pyplot as plt
- from statsmodels.tsa.stattools import adfuller as ADF
- from statsmodels.stats.diagnostic import acorr_ljungbox
- from statsmodels.tsa.arima_model import ARMA
- from statsmodels.tsa.stattools import arma_order_select_ic
- from statsmodels.graphics.tsaplots import plot_acf
- from statsmodels.graphics.tsaplots import plot_pacf
-
- file=pd.read_excel(r'C:\Users\Administrator\Desktop\data.xlsx')
- data=file.iloc[:90]#取到12月21号的数据,留下10天验证
- data.day=pd.to_datetime(data.day)
- #画时序图
- plt.plot(data.day,data.sales)
- plt.xlabel('day')
- plt.ylabel('sales')
- plt.title('Time Series')
- plt.show()
- #画自相关图 和偏自相关图
- plot_acf(data.sales).show()
- plot_pacf(data.sales).show()
- #平稳性检测
- print('ADF result is',ADF(data.sales))
- #纯随机检查
- print('纯随机检查结果为',acorr_ljungbox(data.sales,lags=1)) #lags表示延迟期数
-
- #定阶
- print('BIC求解的模型阶次为',arma_order_select_ic(data.sales,max_ar=10,max_ma=6,ic=['aic', 'bic', 'hqic'])['bic_min_order'])
- model = ARMA(data.sales,(1,0)).fit()
- model.summary2() #给出一份模型报告
- x=file.iloc[90:100].day
- forcast=pd.DataFrame(model.forecast(10)[0],index=x,columns=['forcastsales']) #作为期10天的预测,返回预测结果、标准误差、置信区间。
- actual=pd.DataFrame(list(file.iloc[90:100].sales),index=x,columns=['actualsales'])
- delta=((forcast.forcastsales-actual.actualsales)/actual.actualsales).mean()*100
- print('误差为%0.2f%%'%delta)
- # plt.plot(x,forcast)
- # plt.plot(x,actual,color='red')
- # plt.show()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。