Время является наиболее важным фактором в определении взлета и падения бизнеса. Вот почему мы наблюдаем распродажи в магазинах и на платформах электронной коммерции в связи с праздниками. Эти компании анализируют данные о потреблении за годы, чтобы определить лучшее время, чтобы открыть свои двери и увидеть рост потребительских расходов.
Но как специалист по данным, как вы можете провести такой анализ? Не волнуйтесь, вам не нужно строить машину времени! Моделирование временных рядов — это мощная техника и средство для понимания и прогнозирования тенденций и закономерностей.
Но даже модели временных рядов имеют разные аспекты. Большинство примеров, которые мы видим в Интернете, работают с одномерными временными рядами. К сожалению, реальные варианты использования не работают таким образом. В игре задействовано несколько переменных, и работа со всеми ими одновременно — это то, в чем специалисты по данным находят свою ценность.
В этом посте мы поймем, что такое многомерный временной ряд и как с ним работать. Мы также возьмем тематическое исследование и реализуем его на Python, чтобы дать вам практическое понимание предмета.
Оглавление
- Одномерный и многомерный временные ряды
- одномерный временной ряд
- многомерный временной ряд
- Многомерный временной ряд — обработка векторной авторегрессии (VAR)
- Зачем нам ВАР?
- Стационарность многомерных временных рядов
- сплит проверки обучения
- Реализация Python
1. Одномерные и многомерные временные ряды
В этой статье предполагается, что читатель знаком со свойствами одномерных временных рядов и различными методами прогнозирования. Поскольку эта статья будет посвящена многомерным временным рядам, я рекомендую вам прочитать следующие статьи, которые послужат хорошим введением в одномерные временные ряды:
- Полное руководство по прогнозированию временных рядов
- Построение высокопроизводительных моделей синхронизации с помощью Auto ARIMA
Однако, прежде чем углубляться в детали многомерных временных рядов, я кратко расскажу, что такое одномерные временные ряды. Давайте рассмотрим их различия один за другим.
1.1 Одномерный временной ряд
Одномерный временной ряд, как следует из названия, представляет собой ряд с одной переменной, зависящей от времени.
Например, за последние 2 года посмотрите на примерный набор данных ниже, который включает значения температуры (почасовые). Здесь температура является зависимой переменной (зависящей от времени).
Если бы нас попросили предсказать температуру на следующие несколько дней, мы бы посмотрели на прошлые значения и попытались измерить и извлечь закономерность. Мы заметим более низкие температуры по утрам и вечерам, с пиками во второй половине дня. Кроме того, если у вас есть данные за последние несколько лет, вы увидите, что с ноября по январь холоднее, а с апреля по июнь жарче.
Такие наблюдения помогут нам предсказать будущие значения. Вы заметили, что мы использовали только одну переменную (температура за последние 2 года)? Следовательно, это называется одномерным анализом/прогнозированием временных рядов.
1.2 Многомерные временные ряды (MTS)
Многомерный временной ряд имеет более одной переменной, зависящей от времени. Каждая переменная зависит не только от своих прошлых значений, но также имеет определенные зависимости от других переменных. Эта зависимость используется для прогнозирования будущих значений. Звучит сложно? Позволь мне объяснить.
Рассмотрим пример выше. Теперь предположим, что наш набор данных включает процент пота, точку росы, скорость ветра, облачность и т. д., а также значения температуры за последние два года. В этом случае есть несколько переменных, которые считаются наилучшими прогнозируемыми температурами. Такой ряд подпадает под категорию многомерных временных рядов. Вот пример:
Теперь, когда мы понимаем, как выглядит многомерный временной ряд, давайте разберемся, как его использовать для построения прогнозов.
2. Обработка многомерных временных рядов - VAR
В этом разделе я расскажу об одном из наиболее часто используемых методов прогнозирования многомерных временных рядов — векторной авторегрессии (VAR).
В модели VAR каждая переменная является линейной функцией своего прошлого значения и прошлых значений всех других переменных. Чтобы лучше объяснить это, я буду использовать простой визуальный пример:
У нас есть две переменные y1 и y2. Нам нужно предсказать значения этих двух переменных в момент времени t по заданным данным N значений в прошлом. Для простоты я рассмотрел значение задержки, равное 1.
Для вычисления y1(t) мы будем использовать прошлые значения y1 и y2. Аналогично, для вычисления y2(t) будут использоваться прошлые значения y1 и y2. Вот простой математический способ выражения этой связи:
Здесь a1 и a2 — постоянные члены, w11, w12, w21 и w22 — коэффициенты, а e1 и e2 — члены ошибок.
Эти уравнения аналогичны процессу уравнений AR. Поскольку процедуры AR используются для одномерных данных временных рядов, будущие значения представляют собой просто линейные комбинации их собственных прошлых значений. Рассмотрим процесс AR(1):
y(t) = a + w*y(t-1) +e
В этом случае у нас есть только одна переменная — у, постоянный член — а, ошибочный член — е и коэффициент — w. Чтобы учесть многомерные члены в каждом уравнении VAR, мы будем использовать векторы. Уравнения (1) и (2) можно записать в следующем виде:
Двумя переменными являются Y1 и Y2, за которыми следуют константы, меры коэффициентов, значения запаздывания и меры ошибок. Это векторное уравнение для процесса VAR(1). Для процесса VAR(2) к уравнению добавляется еще один член вектора времени (T-2), чтобы обобщить задержку P:
Приведенные выше уравнения представляют процесс var(p) с переменными y1, y2...yk. То же самое можно записать как:
В уравнении εt представляет многомерный векторный белый шум. Для многомерного временного ряда εt должен быть непрерывным случайным вектором, удовлетворяющим следующим условиям:
1. E(εt) = 0
Ожидаемое значение вектора ошибки равно 0.
2.E(εt1,εt2′)=12
Ожидаемые значения εt и εt' являются стандартным отклонением ряда.
3. Зачем нам VAR?
Вспомните пример предсказания температуры, который мы видели ранее, который можно рассматривать как многомерный одномерный ряд. Мы можем решить эту проблему, используя простые методы одномерного прогнозирования, такие как AR, поскольку цель состоит в том, чтобы предсказать температуру, мы можем просто удалить другие переменные (помимо температуры) и подогнать модель к оставшемуся одномерному ряду.
Еще одна простая идея — использовать уже известные нам методы для прогнозирования значений каждого ряда по одному. Это сделает работу очень простой! Так зачем вам изучать еще один метод прогнозирования? Достаточно ли сложна эта тема?
Из приведенных выше уравнений (1) и (2) ясно, что каждая переменная использует прошлое значение каждой переменной для прогнозирования. В отличие от AR, VAR может понимать и использовать отношения между несколькими переменными. Это помогает описать динамическое поведение данных и обеспечивает лучшие результаты прогнозирования. Кроме того, реализовать VAR так же просто, как и любой другой одномерный метод (как вы увидите в последнем разделе).
4. Стационарность многомерных временных рядов.
Изучая одномерные концепции, мы знаем, что стационарные временные ряды, как правило, дают нам лучший набор прогнозов. Если вы не знакомы с понятием стационарности, сначала прочитайте эту статью:Нежное введение в обработку нестационарных временных рядов.
Таким образом, для заданного одномерного временного ряда:
y(t) = c*y(t-1) + εt
Если c
Примечание. I — единичная матрица.
Выражая уравнение через оператор запаздывания, имеем:
Все члены y(t) слева:
Коэффициенты y(t) называются полиномами запаздывания. Обозначим это как (L):
Собственное значение π(L) - 1π должно быть меньше 1 для ряда фиксированных точек. Это может показаться сложным, учитывая количество производных переменных. Идея ужевидеоЭто поясняется на простом числовом примере. Я настоятельно рекомендую посмотреть его, чтобы укрепить ваше понимание.
Подобно расширенному тесту Дики-Фуллера для одномерных рядов, у нас есть тест Йохансена для проверки стационарности любых данных многомерных временных рядов. Мы увидим, как проверить это в последнем разделе этой статьи.
5. Сплит проверки обучения
Если вы раньше работали с одномерными временными рядами, вы знаете набор для проверки обучения. Идея создания проверочного набора состоит в том, чтобы проанализировать производительность модели, прежде чем использовать ее для прогнозирования.
Создать проверочный набор для проблемы временных рядов сложно, потому что мы должны учитывать компонент времени. нельзя использовать напрямуюtrain_test_splitразделить илиK-Сложите проверку, поскольку это нарушает шаблон в последовательности. Наборы проверки должны создаваться с учетом значений даты и времени.
Предположим, нам нужно использовать данные за последние два года, чтобы предсказать умеренный климат, точку росы, процент облачности и т. д. на следующие два месяца. Один из возможных подходов — отложить данные за последние два месяца и обучить модель на оставшиеся 22 месяца.
После того, как модель обучена, мы можем использовать ее для прогнозирования проверочного набора. Основываясь на этих прогнозах и фактических значениях, мы можем проверить, насколько хорошо работает модель, и переменные, для которых модель не работает. Для окончательных прогнозов используется полный набор данных (объединенный набор для обучения и проверки).
6. Реализация Python
В этом разделе мы реализуем векторную модель дополненной реальности для игрушечного набора данных. Я использовал набор данных о качестве воздуха, который вы можете скачать здесь.
#import required packages
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
#read the data
df = pd.read_csv("AirQualityUCI.csv", parse_dates=[['Date', 'Time']])
#check the dtypes
df.dtypes
Date_Time object
CO(GT) int64
PT08.S1(CO) int64
NMHC(GT) int64
C6H6(GT) int64
PT08.S2(NMHC) int64
NOx(GT) int64
PT08.S3(NOx) int64
NO2(GT) int64
PT08.S4(NO2) int64
PT08.S5(O3) int64
T int64
RH int64
AH int64
dtype: object
Date_TimeТип данных столбцаObject, нам нужно изменить его наdatetime. Кроме того, для подготовки данных нам нужно, чтобы индекс имелdatetime. Следуйте приведенным ниже командам:
df['Date_Time'] = pd.to_datetime(df.Date_Time , format = '%d/%m/%Y %H.%M.%S')
data = df.drop(['Date_Time'], axis=1)
data.index = df.Date_Time
Следующим шагом будет работа с пропущенными значениями. Поскольку пропущенные значения в данных заменяются значением -200, нам придется использовать более точное число для подсчета пропущенных значений. Учтите это - если текущее значение точки росы отсутствует, мы можем с уверенностью предположить, что оно будет близко к значению предыдущего часа. Имеет смысл, верно? Здесь я заполню -200 предыдущим значением.
Вы можете заменить значение средним значением предыдущих значений или также использовать значение предыдущего дня (вы можете поделиться своими мыслями о вводе отсутствующих значений в разделе комментариев ниже).
#missing value treatment
cols = data.columns
for j in cols:
for i in range(0,len(data)):
if data[j][i] == -200:
data[j][i] = data[j][i-1]
#checking stationarity
from statsmodels.tsa.vector_ar.vecm import coint_johansen
#since the test works for only 12 variables, I have randomly dropped
#in the next iteration, I would drop another and check the eigenvalues
johan_test_temp = data.drop([ 'CO(GT)'], axis=1)
coint_johansen(johan_test_temp,-1,1).eig
Вот результаты теста:
array([ 0.17806667, 0.1552133 , 0.1274826 , 0.12277888, 0.09554265,
0.08383711, 0.07246919, 0.06337852, 0.04051374, 0.02652395,
0.01467492, 0.00051835])
Теперь мы можем продолжить и создать проверочный набор, соответствующий модели, и проверить производительность модели:
#creating the train and validation set
train = data[:int(0.8*(len(data)))]
valid = data[int(0.8*(len(data))):]
#fit the model
from statsmodels.tsa.vector_ar.var_model import VAR
model = VAR(endog=train)
model_fit = model.fit()
# make prediction on validation
prediction = model_fit.forecast(model_fit.y, steps=len(valid))
Прогнозы представлены в виде массива, где каждый список представляет прогноз для строки. Мы превратим это в более репрезентативный формат.
#converting predictions to dataframe
pred = pd.DataFrame(index=range(0,len(prediction)),columns=[cols])
for j in range(0,13):
for i in range(0, len(prediction)):
pred.iloc[i][j] = prediction[i][j]
#check rmse
for i in cols:
print('rmse value for', i, 'is : ', sqrt(mean_squared_error(pred[i], valid[i])))
Вывод приведенного выше кода:
rmse value for CO(GT) is : 1.4200393103392812
rmse value for PT08.S1(CO) is : 303.3909208229375
rmse value for NMHC(GT) is : 204.0662895081472
rmse value for C6H6(GT) is : 28.153391799471244
rmse value for PT08.S2(NMHC) is : 6.538063846286176
rmse value for NOx(GT) is : 265.04913993413805
rmse value for PT08.S3(NOx) is : 250.7673347152554
rmse value for NO2(GT) is : 238.92642219826683
rmse value for PT08.S4(NO2) is : 247.50612831072633
rmse value for PT08.S5(O3) is : 392.3129907890131
rmse value for T is : 383.1344361254454
rmse value for RH is : 506.5847387424092
rmse value for AH is : 8.139735443605728
Подгонка модели к полному набору данных после тестирования на проверочном наборе
#make final predictions
model = VAR(endog=data)
model_fit = model.fit()
yhat = model_fit.forecast(model_fit.y, steps=1)
print(yhat)
резюме
До того, как я начал этот пост, идея работы с многомерными временными рядами казалась пугающей по своим масштабам. Это сложная тема, поэтому найдите время, чтобы разобраться в деталях. Лучший способ научиться — это практика, поэтому я надеюсь, что приведенная выше реализация Python подойдет вам.
Я рекомендую вам использовать этот метод для набора данных по вашему выбору. Это еще больше укрепит ваше понимание этой сложной и очень полезной темы. Если у вас есть какие-либо предложения или вопросы, пожалуйста, поделитесь в разделе комментариев.