1
$\begingroup$

I'm trying to make forecasts using sktime for my entire training data and an arbitrary length of out-of-sample data but can't figure it out.

# Generate 2 years of daily data
data = np.random.random(365 * 2,)
df = pd.DataFrame({'y': data})
# Arbirtrary X variable (8% per year growth as a daily increase)
df['daily_growth'] = 8 / 365 

# Forecast for entire dataset and 1 year into the future
fh = np.arange(-len(df)+1, 365+1)
# Fit model
arima = AutoARIMA()
arima.fit(df.y, X=df.daily_growth)
# Create forecast df for in-sample and out-of-sample data... 
# ...this is probably where the problem lies
forecast_df = pd.DataFrame(index=range(len(fh))) # `index=fh` also fails
forecast_df['daily_growth'] = 8 / 365
# ValueError...
preds_with_X = arima.predict(fh=fh, X=forecast_df)

Output

ValueError                                Traceback (most recent call last)
Input In [3], in <cell line: 15>()
     13 preds_no_X = arima_no_X.predict(fh=fh)
     14 len(fh) == len(forecast_df)
---> 15 preds_with_X = arima_with_X.predict(fh=fh, X=forecast_df)
     17 plt.plot(df.y, label='Actual')
     18 plt.plot(preds_no_X, label='preds_no_X')

File ~/opt/anaconda3/envs/humbl_keywords/lib/python3.9/site-packages/sktime/forecasting/base/_base.py:318, in BaseForecaster.predict(self, fh, X)
    316 # we call the ordinary _predict if no looping/vectorization needed
    317 if not self._is_vectorized:
--> 318     y_pred = self._predict(fh=fh, X=X_inner)
    319 else:
    320     # otherwise we call the vectorized version of predict
    321     y_pred = self._vectorize("predict", X=X_inner, fh=fh)

File ~/opt/anaconda3/envs/humbl_keywords/lib/python3.9/site-packages/sktime/forecasting/base/adapters/_pmdarima.py:84, in _PmdArimaAdapter._predict(self, fh, X)
     81 # both in-sample and out-of-sample values
     82 else:
     83     y_ins = self._predict_in_sample(fh_ins, X=X)
---> 84     y_oos = self._predict_fixed_cutoff(fh_oos, X=X)
     85     return pd.concat([y_ins, y_oos])

File ~/opt/anaconda3/envs/humbl_keywords/lib/python3.9/site-packages/sktime/forecasting/base/adapters/_pmdarima.py:177, in _PmdArimaAdapter._predict_fixed_cutoff(self, fh, X, return_pred_int, alpha)
    162 """Make predictions out of sample.
    163 
    164 Parameters
   (...)
    174 Returns series of predicted values.
    175 """
    176 n_periods = int(fh.to_relative(self.cutoff)[-1])
--> 177 result = self._forecaster.predict(
    178     n_periods=n_periods,
    179     X=X,
    180     return_conf_int=False,
    181     alpha=DEFAULT_ALPHA,
    182 )
    184 fh_abs = fh.to_absolute(self.cutoff)
    185 fh_idx = fh.to_indexer(self.cutoff)

File ~/opt/anaconda3/envs/humbl_keywords/lib/python3.9/site-packages/pmdarima/utils/metaestimators.py:53, in _IffHasDelegate.__get__.<locals>.<lambda>(*args, **kwargs)
     50         attrgetter(self.delegate_names[-1])(obj)
     52 # lambda, but not partial, allows help() to work with update_wrapper
---> 53 out = (lambda *args, **kwargs: self.fn(obj, *args, **kwargs))
     54 # update the docstring of the returned function
     55 update_wrapper(out, self.fn)

File ~/opt/anaconda3/envs/humbl_keywords/lib/python3.9/site-packages/pmdarima/arima/auto.py:257, in AutoARIMA.predict(self, n_periods, X, return_conf_int, alpha, **kwargs)
    247 @if_has_delegate("model_")
    248 def predict(self,
    249             n_periods=10,
   (...)
    254 
    255     # Temporary shim until we remove `exogenous` support completely
    256     X, _ = pm_compat.get_X(X, **kwargs)
--> 257     return self.model_.predict(
    258         n_periods=n_periods,
    259         X=X,
    260         return_conf_int=return_conf_int,
    261         alpha=alpha,
    262     )

File ~/opt/anaconda3/envs/humbl_keywords/lib/python3.9/site-packages/pmdarima/arima/arima.py:785, in ARIMA.predict(self, n_periods, X, return_conf_int, alpha, **kwargs)
    783 X = self._check_exog(X)  # type: np.ndarray
    784 if X is not None and X.shape[0] != n_periods:
--> 785     raise ValueError('X array dims (n_rows) != n_periods')
    787 # f = self.arima_res_.forecast(steps=n_periods, exog=X)
    788 arima = self.arima_res_

ValueError: X array dims (n_rows) != n_periods

Alas, pmdarima doesn't print what input it receives for n_rows and n_periods. But I think I am passing the correct shapes.

len(fh) == len(forecast_df)  # True
fh.shape, forecast_df.shape  # ((1095,), (1095, 1))

P.S. I'm not sure my daily_growth var would actually have any impact on the results. Advice on this point and how to get the model to have 8% growth would be helpful too!

$\endgroup$

1 Answer 1

0
$\begingroup$

You are making 2 mistakes:

  1. you train a model with a constant exogenuous variable.
  2. your forecast horizon object fh does not make sense as it has values <= 0.

This code works:

from sktime.forecasting.arima import AutoARIMA
import pandas as pd
import numpy as np

data = np.random.random(365 * 2,)
df = pd.DataFrame({'y': data})
df['daily_growth'] = np.random.random(365 * 2,)
fh = [1,2,3,4]
arima = AutoARIMA()
arima.fit(df.y, X=df.daily_growth)
forecast_df = pd.DataFrame(index=range(len(fh)))
forecast_df['daily_growth'] = 8 / 365
preds_with_X = arima.predict(fh=fh, X=forecast_df.daily_growth)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.