Я пытаюсь предсказать ежедневный доход до конца месяца, изучая предыдущий месяц. Из-за различий в доходах между рабочими и выходными я решил использовать модель временных рядов (ARIMA) в Python.
. Это мой код Python, который я использую:
import itertools
import pandas as pd
import numpy as np
from datetime import datetime, date, timedelta
import statsmodels.api as sm
import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')
import calendar
data_temp = [['01/03/2020',53921.785],['02/03/2020',97357.9595],['03/03/2020',95353.56893],['04/03/2020',93319.6761999999],['05/03/2020',88835.79958],['06/03/2020',98733.0856000001],['07/03/2020',61501.03036],['08/03/2020',74710.00968],['09/03/2020',156613.20712],['10/03/2020',131533.9006],['11/03/2020',108037.3002],['12/03/2020',106729.43067],['13/03/2020',125724.79704],['14/03/2020',79917.6726599999],['15/03/2020',90889.87192],['16/03/2020',160107.93834],['17/03/2020',144987.72243],['18/03/2020',146793.40641],['19/03/2020',145040.69416],['20/03/2020',140467.50472],['21/03/2020',69490.18814],['22/03/2020',82753.85331],['23/03/2020',142765.14863],['24/03/2020',121446.77825],['25/03/2020',107035.29359],['26/03/2020',98118.19468],['27/03/2020',82054.8721099999],['28/03/2020',61249.91097],['29/03/2020',72435.6711699999],['30/03/2020',127725.50818],['31/03/2020',77973.61724]]
panel = pd.DataFrame(data_temp, columns = ['Date', 'revenue'])
pred_result=pd.DataFrame(columns=['revenue'])
panel['Date']=pd.to_datetime(panel['Date'])
panel.set_index('Date', inplace=True)
ts = panel['revenue']
p = d = q = range(0, 2)
pdq = list(itertools.product(p, d, q))
seasonal_pdq = [(x[0], x[1], x[2], 7) for x in list(itertools.product(p, d, q))]
aic = float('inf')
for es in [True,False]:
for param in pdq:
for param_seasonal in seasonal_pdq:
try:
mod = sm.tsa.statespace.SARIMAX(ts,
order=param,
seasonal_order=param_seasonal,
enforce_stationarity=es,
enforce_invertibility=False)
results = mod.fit()
if results.aic<aic:
param1=param
param2=param_seasonal
aic=results.aic
es1=es
#print('ARIMA{}x{} enforce_stationarity={} - AIC:{}'.format(param, param_seasonal,es,results.aic))
except:
continue
print('Best model parameters: ARIMA{}x{} - AIC:{} enforce_stationarity={}'.format(param1, param2, aic,es1))
mod = sm.tsa.statespace.SARIMAX(ts,
order=param1,
seasonal_order=param2,
enforce_stationarity=es1,
enforce_invertibility=False)
results = mod.fit()
pred_uc = results.get_forecast(steps=calendar.monthrange(datetime.now().year,datetime.now().month)[1]-datetime.now().day+1)
pred_ci = pred_uc.conf_int()
ax = ts.plot(label='observed', figsize=(12, 5))
pred_uc.predicted_mean.plot(ax=ax, label='Forecast')
ax.fill_between(pred_ci.index,
pred_ci.iloc[:, 0],
pred_ci.iloc[:, 1], color='k', alpha=.25)
ax.set_xlabel('Date')
plt.legend()
plt.show()
predict=pred_uc.predicted_mean.to_frame()
predict.reset_index(inplace=True)
predict.rename(columns={'index': 'date',0: 'revenue_forcast'}, inplace=True)
display(predict)
Выходные данные выглядят следующим образом:
Как можно увидеть, что результаты прогнозирования имеют отрицательное значение как результат отрицательного наклона.
Поскольку я пытаюсь предсказать доход, результат не может быть ниже нуля, и отрицательный наклон также выглядит очень странно.
Что не так на моем пути? Как это улучшить?
Спасибо! Оставайся дома, будь в безопасности!