Экзогенная переменная Python ARIMA из выборки

Я пытаюсь предсказать временной ряд в пакете Python statsmodels ARIMA с включением экзогенной переменной, но не могу понять, как правильно вставить экзогенную переменную в шаг предсказания. См.здесь для документов.

import numpy as np
from scipy import stats
import pandas as pd

import statsmodels.api as sm

vals = np.random.rand(13)
ts = pd.TimeSeries(vals)
df = pd.DataFrame(ts, columns=["test"])
df.index = pd.Index(pd.date_range("2011/01/01", periods = len(vals), freq = 'Q'))

fit1 = sm.tsa.ARIMA(df, (1,0,0)).fit()
#this works fine:
pred1 = fit1.predict(start=12, end = 16)
print(pred1)

Out[32]: 
2014-03-31    0.589121
2014-06-30    0.747575
2014-09-30    0.631322
2014-12-31    0.654858
2015-03-31    0.650093
Freq: Q-DEC, dtype: float64

теперь добавьте в тренд экзогенную переменную

exogx = np.array(range(1,14))
#to make this easy, let's look at the ols of the trend (arima(0,0,0))
fit2 = sm.tsa.ARIMA(df, (0,0,0),exog = exogx).fit()
print(fit2.params)

const    0.555226
x1       0.013132
dtype: float64

print(fit2.fittedvalues)

2011-03-31    0.568358
2011-06-30    0.581490
2011-09-30    0.594622
2011-12-31    0.607754
2012-03-31    0.620886
2012-06-30    0.634018
2012-09-30    0.647150
2012-12-31    0.660282
2013-03-31    0.673414
2013-06-30    0.686546
2013-09-30    0.699678
2013-12-31    0.712810
2014-03-31    0.725942
Freq: Q-DEC, dtype: float64

обратите внимание, как и следовало ожидать, это линия тренда, увеличивающаяся 0.013132 с каждым увеличением тика во времени (конечно, это случайные данные, поэтому, если вы запустить его значения будут разные, но положительная или отрицательная история будет). Итак, следующее значение (для time = 14) должно быть 0.555226 + 0.013132*14 = 0,739074.

#out of sample exog should be (14,15,16)
pred2 = fit2.predict(start = 12, end = 16, exog = np.array(range(13,17)))
print(pred2)
2014-03-31    0.725942
2014-06-30    0.568358
2014-09-30    0.581490
2014-12-31    0.594622
2015-03-31    0.765338
Freq: Q-DEC, dtype: float64

Итак, 2014-03-31 предсказывает (последний пример) правильно, но 2014-06-30 начинается в начале (t = 1), но обратите внимание, 2015-03-31 (на самом деле, всегда последнее наблюдение прогноза, независимо от горизонта) поднимает t = 16 (то есть (значение-перехват) / beta = (0.765338 - 0.555226) / 0.013132).

чтобы сделать это более ясным, обратите внимание, что происходит, когда я раздуваю значения x mat

fit2.predict(start = 12, end = 16, exog = np.array(range(13,17))*10000)
Out[41]: 
2014-03-31       0.725942
2014-06-30       0.568358
2014-09-30       0.581490
2014-12-31       0.594622
2015-03-31    2101.680532
Freq: Q-DEC, dtype: float64

см., что 2015-03-31 взорвался, но ни одно из других значений xmat не рассматривалось? Что я здесь делаю не так???

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

я использую 2.7 из Anaconda2.1 и NumPy 1.8.1 scipy 0.14.0 панды 0.14.0 statsmodels 0.5.0

и проверили проблему на Windows 7 64 бит и centos 64 бит.

кроме того, несколько вещей. Я использую ARIMA для функциональности ARIMA, и выше только для иллюстрации (то есть я не могу "просто использовать OLS...", как я полагаю, будет предложено). Я тоже не могу "просто использовать R" из-за ограничений проекта (и в более общем плане, отсутствие поддержки R в базовой Spark).

вот интересные части кода все вместе, если вы хотите попробовать его самостоятельно

import numpy as np
from scipy import stats
import pandas as pd
import statsmodels.api as sm

vals = np.random.rand(13)
ts = pd.TimeSeries(vals)
df = pd.DataFrame(ts, columns=["test"])
df.index = pd.Index(pd.date_range("2011/01/01", periods = len(vals), freq = 'Q'))

exogx = np.array(range(1,14))
fit2 = sm.tsa.ARIMA(df, (0,0,0),exog = exogx).fit()
print(fit2.fittedvalues)
pred2 = fit2.predict(start = 12, end = 16, exog = np.array(range(13,17))*10000)
print(pred2)

3 ответов


Это, вероятно, лучше размещены на GitHub проблема tracker. Я подал авиабилет хотя.

лучше всего подать билет туда, если я не могу забыть об этом. Очень занят в эти дни.

была ошибка в логике для частного случая k_ar == 0. Должно быть исправлено. Дайте мне знать, если вы можете/не можете дать этому патчу вращение. Если нет, я могу провести более тщательное тестирование и объединить его.

Statsmodels поверх spark? Я заинтригован.


при fiting fit2 вы уже упомянули переменные exog, поэтому нет необходимости повторять его:

exogx = np.array(range(1,5)) # I think you will need 4 exegeneous variables to perform an ARIMAX(0,0,0) since you want out of sample forecast with 4 steps ahead
fit2 = sm.tsa.ARIMA(df, (0,0,0),exog = exogx).fit()
# if you want to do an out-of-sample-forecast use fit2.forecast(steps) instead
#I would do this
pred = fit2.forecast(steps = 4)
fcst_index = pd.date_range(start = df.shift(1,'10T').index[-1]  , periods = 4, freq = '10T')
fcst_serie = pd.Series(data = pred1[0], index = fcst_index)
print fcst_serie

надеюсь, что это поможет! Это отличный пост.Я никогда не пробовал экзогенные переменные на ARIMA раньше, но документы говорят, что это не очень важно, независимо от поля, которое вы используете (будет искать документы, если это необходимо, или вы можете его google)


Если кто-то использует функцию прогноза, это сработало для меня для прогнозирования одного шага.

история обучение массиве

exog является массивом внешних переменных

Y_exog_test отсутствует образец соответствующей внешней переменной. Измените его на ARIMAX, и он должен работать

model = sm.tsa.statespace.SARIMAX(history, trend='c', order=(1,1,1),seasonal_order=(0,1,0,24),exog=yexog)

model_fit = model.fit()

predicted = model_fit.forecast(step=1,exog=[[Y_exog_test]], dynamic=True)