Отрицательные результаты в модели ARIMA - PullRequest
0 голосов
/ 02 апреля 2020

Я пытаюсь предсказать ежедневный доход до конца месяца, изучая предыдущий месяц. Из-за различий в доходах между рабочими и выходными я решил использовать модель временных рядов (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)

Выходные данные выглядят следующим образом: enter image description here

Как можно увидеть, что результаты прогнозирования имеют отрицательное значение как результат отрицательного наклона.

Поскольку я пытаюсь предсказать доход, результат не может быть ниже нуля, и отрицательный наклон также выглядит очень странно.

Что не так на моем пути? Как это улучшить?

Спасибо! Оставайся дома, будь в безопасности!

Ответы [ 2 ]

1 голос
/ 02 апреля 2020

Вы не можете заставить модель ARIMA принимать только положительные значения. Тем не менее, классическая c «хитрость», когда вы хотите предсказать что-то, что всегда положительно, состоит в том, чтобы использовать функцию, которая преобразует положительные значения в любое значение в R. Функция log является хорошим примером этого.

panel['log_revenue'] = np.log(panel['revenue'])

И прогнозировать сейчас log_revenue столбец.

Теперь, если прогнозы принимают отрицательные значения, это нормально, потому что ваш прогноз на самом деле np.exp(predict), что положительно.

0 голосов
/ 02 апреля 2020

Решение состоит в том, чтобы взять больше истории данных.

enter image description here

...