Прогнозирование со статистическими моделями
У меня есть файл .csv, содержащий 5-летний временной ряд, с часовым разрешением (товарная цена). Исходя из исторических данных, я хочу создать прогноз цен на 6-й год.
Я прочитал несколько статей на www об этих типах процедур, и я в основном основывал свой код на размещенном там коде, так как мои знания как в Python (особенно statsmodels), так и в статистике, по большей части, ограничены.
Это ссылки для тех, кому интересно:
http://www.seanabu.com/2016/03/22/time-series-seasonal-ARIMA-model-in-python/
http://www.johnwittenauer.net/a-simple-time-series-analysis-of-the-sp-500-index/
Прежде всего, вот пример файла .csv. В этом случае данные отображаются с ежемесячным разрешением, это не реальные данные, просто случайные числа, чтобы привести пример (в этом случае я надеюсь, что одного года достаточно, чтобы иметь возможность разработать прогноз на 2-й год; если нет, полный CSV-файл доступен):
Price
2011-01-31 32.21
2011-02-28 28.32
2011-03-31 27.12
2011-04-30 29.56
2011-05-31 31.98
2011-06-30 26.25
2011-07-31 24.75
2011-08-31 25.56
2011-09-30 26.68
2011-10-31 29.12
2011-11-30 33.87
2011-12-31 35.45
Мой текущий прогресс заключается в следующем:
После прочтения входного файла и установки столбца даты в качестве индекса даты и времени, следующий сценарий использовался для разработки прогноза для доступных данных.
model = sm.tsa.ARIMA(df['Price'].iloc[1:], order=(1, 0, 0))
results = model.fit(disp=-1)
df['Forecast'] = results.fittedvalues
df[['Price', 'Forecast']].plot(figsize=(16, 12))
, который дает следующий вывод:
Теперь, как я уже сказал, у меня нет навыков в области статистики, и я почти не представляю, как я получил этот вывод (в основном, изменение атрибута заказа в первой строке изменяет вывод), но «фактический» прогноз выглядит довольно хорошо, и я хотел бы продлить его еще на один год (2016).
Для этого в фрейме данных создаются дополнительные строки следующим образом:
start = datetime.datetime.strptime("2016-01-01", "%Y-%m-%d")
date_list = pd.date_range('2016-01-01', freq='1D', periods=366)
future = pd.DataFrame(index=date_list, columns= df.columns)
data = pd.concat([df, future])
Наконец, когда я использую функцию .predict statsmodels:
data['Forecast'] = results.predict(start = 1825, end = 2192, dynamic= True)
data[['Price', 'Forecast']].plot(figsize=(12, 8))
в качестве прогноза я получаю прямую линию (см. ниже), которая совсем не похожа на прогноз. Более того, если я увеличу диапазон, который в настоящее время составляет 1825–2192-й день (2016 год), на весь шестилетний период времени, линия прогноза будет прямой линией для всего периода (2011–2016 годы).
Я также пытался использовать метод statsmodels.tsa.statespace.sarimax.SARIMAX.predict, который учитывает сезонные колебания (что имеет смысл в этом случае), но я получаю некоторую ошибку о том, что «модуль» не имеет атрибута » SARIMAX. Но это второстепенная проблема, расскажу подробнее, если нужно.
Где-то я теряю контроль и не знаю где. Спасибо за прочтение. Ура!