【发布时间】:2019-12-02 10:32:35
【问题描述】:
我正在尝试建立一个模型来预测一家外卖咖啡馆的每日订单数量。这是数据,
在这里您可以看到两个主要高峰:它们是假期——分别是 2 月 14 日和 3 月 8 日。此外,您可以看到周期为 7 的明显季节性:人们在周末订购更多,而在工作日订购较少。
Dickey-Fuller 检验表明序列不是平稳的,p 值 = 0.152
然后我决定应用 Box-Cox 变换,因为偏差看起来不均匀。之后,Dickey-Fuller 检验的 p 值为 0.222,但转换后的系列现在看起来像一个正弦曲线,
然后我应用了这样的季节性差异:
data["counts_diff"] = data.counts_box - data.counts_box.shift(7)
plt.figure(figsize=(15,10))
sm.tsa.seasonal_decompose(data.counts_diff[7:]).plot()
p_value = sm.tsa.stattools.adfuller(data.counts_diff[7:])[1]
现在 p 值约为 10e-5 并且序列是平稳的
然后我绘制了 ACF 和 PACF 来选择网格搜索的初始参数,
常识和我知道的规则告诉我要选择,
Q = 1
q = 4
P = 3
p = 6
d = 0
D = 1
模型查找代码:
ps = range(0, p+1)
d=0
qs = range(0, q+1)
Ps = range(0, P+1)
D=1
Qs = range(0, Q+1)
parameters_list = []
for p in ps:
for q in qs:
for P in Ps:
for Q in Qs:
parameters_list.append((p,q,P,Q))
len(parameters_list)
%%time
from IPython.display import clear_output
results = []
best_aic = float("inf")
i = 1
for param in parameters_list:
print("counting {}/{}...".format(i, len(parameters_list)))
i += 1
try:
model=sm.tsa.statespace.SARIMAX(data.counts_diff[7:], order=(param[0], d, param[1]),
seasonal_order=(param[2], D, param[3], 7)).fit(disp=-1)
except ValueError:
print('wrong parameters:', param)
continue
except LinAlgError:
print('LU decomposition error:', param)
continue
finally:
clear_output()
aic = model.aic
if aic < best_aic:
best_model = model
best_aic = aic
best_param = param
results.append([param, model.aic])
网格搜索后,我得到了这个,
但是当我绘制它时,它会在零处显示一条恒定线,
残差是无偏的,没有趋势并且不是自相关的,
绘图代码在这里:
# inverse Box-Cox transformation
def invboxcox(y, lmbda):
if lmbda == 0:
return np.exp(y)
else:
return np.exp(np.log(lmbda*y+1) / lmbda)
data["model"] = invboxcox(best_model.fittedvalues, lmbda)
plt.figure(figsize(15,5))
plt.ylabel('Orders count')
data.counts.plot()
#pylab.show()
data.model.plot(color='r')
plt.ylabel('Model explanation')
pylab.show()
如果我取消注释该行,情节如下所示,
我错过了什么?我应该考虑转换系列的正弦形状吗?为什么规模如此不同?
还有代码,
data["model"] = invboxcox(best_model.fittedvalues, lmbda)
plt.figure(figsize(15,5))
(data.counts_diff + 1).plot()
#pylab.show()
data.model.plot(color='r')
pylab.show()
绘制两个相当相似的图,
所以,AFAIK,问题出在逆向转换中。
【问题讨论】:
-
你能提供一些数据本身吗?顺便说一句:BoxCox 变换(包括逆变换)在
statsmodels.base.transform中可用。 -
是的,你可以在这里找到它:dropmefiles.com/Ac2rw
标签: python statistics time-series statsmodels