У меня есть сомнения, связанные с работой по прогнозированию временных рядов, которую я делаю для своего проекта.
Я использую SARIMA (сезонная ARIMA) для прогнозирования модели, поскольку временной ряд оказывает влияние на сезонность. В SARIMA у нас есть параметры - p, d, q, P, D, Q и m, которые необходимо передать. Хотя большинство этих параметров можно выбрать автоматически с помощью автоаримы, термин «m», определяемый как число сезонных циклов, наблюдаемых в году (недельная сезонность - 52, месячная сезонность - 12 и т. Д.), Является термином, который мы должны вручнуюпредоставлять.
Как именно мы можем решить этот термин? Согласно моим временным рядам, у цикла, кажется, есть немного неправильные циклы, то есть иногда он повторяется раз в две недели, а иногда повторяется через два месяца. Наш набор данных собирается еженедельно (363 точки данных за 2 года и данные за 3 месяца).
Поскольку возникла путаница при выборе «m», мы сохранили его равным 52 (поскольку данные доступны еженедельно) и получили приличную MAPE (около 9). Тем не менее, когда я увеличил его до 80, MAPE снизился до 3, и прогнозируемый график намного лучше соответствовал реальному графику. Когда я увеличил его до 80, код выдал ошибку.
Кто-нибудь знает, почему это происходит?
Редактирование этого
Я увеличил набор тестовых данных, а затем увеличил значение m, что сработало. Но более высокое значение mне обязательно дает более низкий MAPE. значение 80 для m дает низкий MAPE, в то время как значения 81 и 85 дают более высокие значения. Это кажется довольно случайным, но я уверен, что это значение m имеет огромное значение при определении модели прогноза. Я прилагаю изображения здесь для лучшего понимания.
SARIMA со значением m 80
SARIMA со значением m 81
SARIMA со значением m 85
Ошибка при высоком значении m
ValueError Traceback (most recent call last)
<ipython-input-90-8517b4596f58> in <module>
----> 1 model_fit = train_auto_arima(train_df1.DAT_RATE)
2 model_fit.fit(train_df1.values)
3 print(f'Params - > \n aic-{model_fit.aic()}, \n get_params-{model_fit.get_params()}')
4 # forecasting
5 test_predictions = forecast_over_test_set(model_fit, test_df1.DAT_RATE, train_df1.DAT_RATE)
<ipython-input-89-218545403b7c> in train_auto_arima(df)
81 stepwise=False, # We are going with Parallel execution rather than step-wise approach
82 information_criterion='bic',
---> 83 trace=True, error_action='ignore')
84
85 return arima
~\AppData\Roaming\Python\Python37\site-packages\pmdarima\arima\auto.py in auto_arima(y, exogenous, start_p, d, start_q, max_p, max_d, max_q, start_P, D, start_Q, max_P, max_D, max_Q, max_order, m, seasonal, stationary, information_criterion, alpha, test, seasonal_test, stepwise, n_jobs, start_params, trend, method, transparams, solver, maxiter, disp, callback, offset_test_args, seasonal_test_args, suppress_warnings, error_action, trace, random, random_state, n_fits, return_valid_fits, out_of_sample_size, scoring, scoring_args, with_intercept, sarimax_kwargs, **fit_args)
320 if seasonal_test_args is not None else dict()
321 D = nsdiffs(xx, m=m, test=seasonal_test, max_D=max_D,
--> 322 **seasonal_test_args)
323
324 if D > 0 and exogenous is not None:
~\AppData\Roaming\Python\Python37\site-packages\pmdarima\arima\utils.py in nsdiffs(x, m, max_D, test, **kwargs)
105
106 D = 0
--> 107 dodiff = testfunc(x)
108 while dodiff == 1 and D < max_D:
109 D += 1
~\AppData\Roaming\Python\Python37\site-packages\pmdarima\arima\seasonality.py in estimate_seasonal_differencing_term(self, x)
456
457 # Get the critical value for m
--> 458 stat = self._compute_test_statistic(x)
459 crit_val = self._calc_ocsb_crit_val(self.m)
460 return int(stat > crit_val)
~\AppData\Roaming\Python\Python37\site-packages\pmdarima\arima\seasonality.py in _compute_test_statistic(self, x)
417 # Compute the actual linear model used for determining the test stat
418 try:
--> 419 regression = self._fit_ocsb(x, m, maxlag, maxlag)
420 except np.linalg.LinAlgError: # Singular matrix
421 if crit_regression is not None:
~\AppData\Roaming\Python\Python37\site-packages\pmdarima\arima\seasonality.py in _fit_ocsb(x, m, lag, max_lag)
341 y_first_order_diff = diff(x, m)
342 y = diff(y_first_order_diff)
--> 343 ylag = OCSBTest._gen_lags(y, lag)
344
345 if max_lag > 0:
~\AppData\Roaming\Python\Python37\site-packages\pmdarima\arima\seasonality.py in _gen_lags(y, max_lag, omit_na)
334
335 # delegate down
--> 336 return OCSBTest._do_lag(y, max_lag, omit_na)
337
338 @staticmethod
~\AppData\Roaming\Python\Python37\site-packages\pmdarima\arima\seasonality.py in _do_lag(y, lag, omit_na)
319 # Create a 2d array of dims (n + (lag - 1), lag). This looks cryptic..
320 # If there are tons of lags, this may not be super efficient...
--> 321 out = np.ones((n + (lag - 1), lag)) * np.nan
322 for i in range(lag):
323 out[i:i + n, i] = y
C:\ProgramData\Anaconda3\lib\site-packages\numpy\core\numeric.py in ones(shape, dtype, order)
221
222 """
--> 223 a = empty(shape, dtype, order)
224 multiarray.copyto(a, 1, casting='unsafe')
225 return a
ValueError: negative dimensions are not allowed