Всем привет!

Мы продолжаем наш открытый курс машинного обучения новой статьей о временных рядах.

Давайте посмотрим, как работать с временными рядами в Python, какие методы и модели мы можем использовать для прогнозирования. что такое двойное и тройное экспоненциальное сглаживание; что делать, если стационарность вам не нравится; как построить САРИМА и остаться в живых; как делать прогнозы с помощью xgboost. Все это будет применено к (суровому) примеру из реального мира.

Краткое содержание статьи

  1. Введение
    - Основные определения
    - Показатели качества
  2. Перемещение, сглаживание, оценка
    - Оценка скользящего окна
    - Экспоненциальное сглаживание, модель Холта-Винтерса
    - Перекрестная проверка временных рядов, выбор параметров
  3. Эконометрический подход
    - Стационарность, единичный корень
    - Избавление от нестационарности
    - Интуиция SARIMA и построение модели
  4. Линейные (и не совсем) модели во временных рядах
    - Извлечение признаков
    - Линейные модели, важность признаков
    - Регуляризация, выбор признаков
    - XGBoost
  5. Задание №9

Следующий контент лучше просматривать и воспроизводить как Jupyter-notebook

В своей повседневной работе я почти каждый день сталкиваюсь с задачами, связанными с временными рядами. Самый частый вопрос - что будет с нашими метриками в следующий день / неделю / месяц / и т. Д. - сколько игроков установят приложение, сколько времени они проведут в сети, сколько действий выполнят пользователи и т. Д. Мы можем подойти к задаче прогнозирования, используя разные методы, в зависимости от требуемого качества прогноза, продолжительности прогнозируемого периода и, конечно же, времени, в течение которого мы должны выбирать функции и настраивать параметры для достижения желаемых результатов.

Вступление

Небольшое определение временного ряда:
Временной ряд - это ряд точек данных, проиндексированных (или перечисленных, или графически отображенных) во временном порядке.

Поэтому данные организованы вокруг относительно детерминированных временных меток и, следовательно, по сравнению со случайными выборками могут содержать дополнительную информацию, которую мы попытаемся извлечь.

Давайте импортируем несколько библиотек. В первую очередь нам понадобится библиотека statsmodels, которая имеет массу функций статистического моделирования, включая временные ряды. Для профессионалов (которым пришлось перейти на python) статистические модели определенно будут выглядеть знакомыми, поскольку они поддерживают определения моделей, такие как Заработная плата ~ Возраст + образование.

В качестве примера рассмотрим реальные данные о мобильных играх о ежечасной рекламе, которую игроки просматривают, и о ежедневной потраченной внутриигровой валюте:

Показатели качества прогнозов

Перед тем, как на самом деле делать прогнозы, давайте разберемся, как измерять качество прогнозов, и взглянем на наиболее распространенные и широко используемые показатели.

  • R в квадрате, коэффициент детерминации (в эконометрике его можно интерпретировать как процент дисперсии, объясняемой моделью), (-inf, 1] sklearn.metrics.r2_score
  • Средняя абсолютная ошибка, это интерпретируемая метрика, поскольку она имеет ту же единицу измерения, что и исходный ряд, [0, + inf)
    sklearn.metrics.mean_absolute_error
  • Средняя абсолютная ошибка, снова интерпретируемый показатель, особенно интересный, поскольку он устойчив к выбросам, [0, + inf)
    sklearn.metrics.median_absolute_error
  • Среднеквадратичная ошибка, наиболее часто используемая, дает более высокий штраф за большие ошибки и наоборот, [0, + inf)
    sklearn.metrics.mean_squared_error
  • [ 0, + inf)
    sklearn.metrics.mean_squared_log_error
  • Средняя абсолютная процентная ошибка, такая же, как MAE, но в процентах, - очень удобно, когда вы хотите объяснить качество модели своему руководству, [0, + inf), а не реализовано в sklearn

Отлично, теперь мы знаем, как измерять качество прогнозов, какие показатели мы можем использовать и как передавать результаты начальнику. Осталось немногое - построить модель.

Двигайся, сглаживай, оценивай

Давайте начнем с наивной гипотезы - «завтра будет таким же, как сегодня», но вместо такой модели, как ŷ (t) = y (t − 1) (которая на самом деле является отличной базой для любых задач прогнозирования временных рядов, а иногда и невозможно превзойти его с помощью какой-либо модели) мы предположим, что будущее значение переменной зависит от среднего n ее предыдущих значений, и поэтому мы будем использовать скользящее среднее.

Out: 116805.0

К сожалению, мы не можем сделать этот прогноз долгосрочным - чтобы получить его для следующего шага, нам нужно, чтобы предыдущее значение действительно соблюдалось. Но у скользящей средней есть еще один вариант использования - сглаживание исходного временного ряда для выявления тенденций. У Pandas есть реализация DataFrame.rolling(window).mean(). Чем шире окно - тем плавнее будет тренд. В случае очень зашумленных данных, которые очень часто встречаются в финансовой сфере, эта процедура может помочь выявить общие закономерности.

Сглаживание за последние 4 часа
plotMovingAverage(ads, 4)

Сглаживание за последние 12 часов
plotMovingAverage(ads, 12)

Сглаживание на 24 часа - получаем дневной тренд
plotMovingAverage(ads, 24)

Как видите, применение ежедневного сглаживания для почасовых данных позволило нам четко увидеть динамику просмотренной рекламы. В выходные дни значения выше (выходные - время для игр), а в будние дни, как правило, ниже.

Мы также можем построить доверительные интервалы для наших сглаженных значений
plotMovingAverage(ads, 4, plot_intervals=True)

А теперь давайте создадим простую систему обнаружения аномалий с помощью скользящей средней. К сожалению, в этой конкретной серии все более или менее нормально, поэтому мы намеренно сделаем одно из значений аномальным во фрейме данных ads_anomaly

Посмотрим, сможет ли этот простой метод выявить аномалию
plotMovingAverage(ads_anomaly, 4, plot_intervals=True, plot_anomalies=True)

Аккуратный! А как насчет второй серии (с еженедельным сглаживанием)?
plotMovingAverage(currency, 7, plot_intervals=True, plot_anomalies=True)

О, нет! Вот и обратная сторона нашего простого подхода - он не улавливал месячную сезонность в наших данных и отмечал почти все 30-дневные пики как аномалии. Если вы не хотите, чтобы у вас было так много ложных срабатываний, лучше рассмотреть более сложные модели.

Средневзвешенное - это простая модификация скользящего среднего, внутри которого наблюдения имеют разные веса, суммируя их до одного, обычно более свежие наблюдения имеют больший вес.

Out: 98423.0

Экспоненциальное сглаживание

А теперь давайте посмотрим, что произойдет, если вместо взвешивания последних nn значений временного ряда мы начнем взвешивать все доступные наблюдения, экспоненциально уменьшая веса по мере продвижения назад в исторических данных. В этом нам поможет формула простого экспоненциального сглаживания:

Здесь значение модели представляет собой средневзвешенное значение между текущим истинным значением и предыдущими значениями модели. Вес α называется сглаживающим фактором. Он определяет, насколько быстро мы «забудем» последнее доступное истинное наблюдение. Чем меньше α, тем большее влияние оказывают предыдущие значения модели и тем более гладким будет ряд.

Экспоненциальность кроется в рекурсивности функции - мы каждый раз умножаем (1 − α) на предыдущее модельное значение, которое, в свою очередь, также содержит (1 − α) и так далее до самого начала.

Двойное экспоненциальное сглаживание

До сих пор все, что мы могли получить от наших методов в лучшем случае, было просто предсказанием одной будущей точки (а также некоторым приятным сглаживанием), это круто, но недостаточно, поэтому давайте расширим экспоненциальное сглаживание, чтобы мы могли предсказать две будущие точки (конечно , мы также получаем некоторое сглаживание).

Разложение по ряду должно нам помочь - мы получаем две составляющие: перехват (также, уровень) ℓ и тренд (также, наклон) b. Мы научились прогнозировать точку пересечения (или ожидаемое значение ряда), используя предыдущие методы, и теперь мы применим такое же экспоненциальное сглаживание к тренду, наивно полагая или, возможно, нет, что будущее направление изменений временного ряда зависит от предыдущих взвешенных изменений. .

В результате мы получаем набор функций. Первый описывает точку пересечения, так как раньше он зависит от текущего значения ряда, а второй член теперь разбивается на предыдущие значения уровня и тренда. Вторая функция описывает тренд - он зависит от изменения уровня на текущем шаге и от предыдущего значения тренда. В этом случае коэффициент β является весом экспоненциального сглаживания. Окончательный прогноз - это сумма модельных значений точки пересечения и тренда.

Теперь нам нужно настроить два параметра - α и β. Первый отвечает за сглаживание ряда вокруг тренда, а второй - за сглаживание самого тренда. Чем больше значения, тем больший вес будут иметь последние наблюдения и тем менее сглаженным будет модельный ряд. Комбинации параметров могут давать действительно странные результаты, особенно если они установлены вручную. Мы рассмотрим возможность автоматического выбора параметров чуть позже, сразу после тройного экспоненциального сглаживания.

Тройное экспоненциальное сглаживание, также известное как Холт-Винтерс

Ура! Мы успешно достигли следующего варианта экспоненциального сглаживания, на этот раз тройного.

Идея этого метода в том, что мы добавляем еще одну, третью составляющую - сезонность. Это означает, что мы не должны использовать этот метод, если наши временные ряды не имеют сезонности, что не относится к нашему примеру. Сезонный компонент в модели будет объяснять повторяющиеся вариации вокруг точки пересечения и тенденции, и он будет описываться продолжительностью сезона, другими словами, периодом, после которого вариации повторяются. Для каждого наблюдения в сезоне есть отдельный компонент, например, если продолжительность сезона 7 (еженедельная сезонность), у нас будет 7 сезонных компонентов, по одному на каждый день недели.

Теперь у нас новая система:

Теперь пересечение зависит от текущего значения ряда за вычетом соответствующего сезонного компонента, тренд остается неизменным, а сезонный компонент зависит от текущего значения ряда за вычетом точки пересечения и от предыдущего значения компонента. Учтите, что компонент сглаживается по всем доступным сезонам, например, если у нас есть компонент понедельника, то он будет усредняться только с другими понедельниками. Подробнее о том, как работает усреднение и как выполняется начальное приближение тренда и сезонных составляющих, вы можете прочитать здесь. Теперь, когда у нас есть сезонная составляющая, мы можем прогнозировать не один и даже не два, а произвольные миллиметровые будущие шаги, что очень обнадеживает.

Ниже приведен код модели тройного экспоненциального сглаживания, также известной по фамилиям ее создателей - Чарльза Холта и его ученика Питера Винтерса. Дополнительно в модель был включен метод Брутлага для построения доверительных интервалов:

где T - продолжительность сезона, d - прогнозируемое отклонение, а другие параметры были взяты из тройного экспоненциального сглаживания. Подробнее о методе и его применении для обнаружения аномалий во временных рядах можно прочитать здесь.

Перекрестная проверка временных рядов

Прежде чем мы начнем строить модель, давайте сначала поговорим о том, как автоматически оценивать параметры модели.

В этом нет ничего необычного, поскольку мы всегда должны выбрать функцию потерь, подходящую для задачи, которая скажет нам, насколько близко модель аппроксимирует данные. Затем, используя перекрестную проверку, мы оценим выбранную нами функцию потерь для заданных параметров модели, вычислим градиент, настроим параметры модели и так далее, смело снижаясь до глобального минимума ошибки.

Вопрос в том, как выполнять перекрестную проверку временных рядов, потому что, как вы знаете, временные ряды имеют временную структуру, и нельзя просто случайным образом смешивать значения в свертке без сохранения этой структуры, иначе все временные зависимости между наблюдениями будут потеряны. . Вот почему нам придется использовать более хитрый подход к оптимизации параметров модели, я не знаю, есть ли у него официальное название, но на CrossValidated, где можно найти все ответы, кроме Ответа на Окончательный. В качестве названия был предложен вопрос жизни, вселенной и всего остального, перекрестная проверка на постоянной основе.

Идея довольно проста - мы обучаем нашу модель на небольшом отрезке временного ряда, от начала до некоторого t, делаем прогнозы на следующие t + n шагов и вычислите ошибку. Затем мы расширяем нашу обучающую выборку до значения t + n и делаем прогнозы от t + n до t + 2 ∗ n, и мы продолжаем перемещать наш тестовый сегмент временного ряда, пока не дойдем до последнего доступного наблюдения. В результате получается столько складок, сколько n поместится между начальной обучающей выборкой и последним наблюдением.

Теперь, зная, как настроить перекрестную проверку, мы найдем оптимальные параметры для модели Холта-Винтерса, напомним, что у нас есть ежедневная сезонность в рекламе, отсюда и параметр slen=24

В модели Холта-Винтерса, как и в других моделях экспоненциального сглаживания, существует ограничение на то, насколько большими могут быть параметры сглаживания, каждый из них находится в диапазоне от 0 до 1, поэтому, чтобы минимизировать функцию потерь, мы должны выбрать алгоритм, поддерживающий ограничения на параметры модели, в нашем случае - сопряженный градиент усеченного Ньютона.

0.11652680227350454 0.002677697431105852 0.05820973606789237
CPU times: user 1.96 s, sys: 17.3 ms, total: 1.98 s
Wall time: 2 s

Код отрисовки диаграммы

Судя по графику, наша модель смогла успешно аппроксимировать начальный временной ряд, уловив суточную сезонность, общий нисходящий тренд и даже некоторые аномалии. Если вы посмотрите на смоделированное отклонение, то ясно увидите, что модель довольно резко реагирует на изменения в структуре ряда, но затем быстро возвращает отклонение к нормальным значениям, «забывая» прошлое. Эта особенность модели позволяет нам быстро создавать системы обнаружения аномалий даже для довольно шумных серий, не тратя слишком много времени и денег на подготовку данных и обучение модели.

Мы применим тот же алгоритм для второй серии, которая, как мы знаем, имеет тенденцию и 30-дневную сезонность.

0.012841445048055122 0.04883371471892228 0.00943678056045777
CPU times: user 3.03 s, sys: 24.8 ms, total: 3.05 s
Wall time: 3.11 s

Выглядит вполне адекватно, модель уловила как восходящий тренд, так и сезонные всплески и в целом хорошо соответствует нашим ценностям.

Эконометрический подход

Стационарность

Прежде чем приступить к моделированию, следует упомянуть такое важное свойство временных рядов, как стационарность.

Если процесс является стационарным, это означает, что он не меняет своих статистических свойств с течением времени, а именно, среднее значение и дисперсия не меняются с течением времени (постоянство дисперсии также называется гомоскедастичностью), а также функция ковариации не зависит от времени (должна зависит только от расстояния между наблюдениями). Вы можете увидеть это наглядно на фотографиях из поста Шон Абу:

  • Красный график ниже не является стационарным, потому что среднее значение увеличивается со временем.

  • Нам не повезло с дисперсией, мы видим, как меняются значения во времени.

  • Наконец, ковариация i-го члена и (i + m) -го члена не должна быть функцией времени. На следующем графике вы заметите, что с увеличением времени спред становится ближе. Следовательно, ковариация не постоянна во времени для правильного графика.

Так почему же так важна стационарность? Потому что легко делать прогнозы на основе стационарных рядов, поскольку мы предполагаем, что будущие статистические свойства не будут отличаться от наблюдаемых в настоящее время. Большинство временных рядов так или иначе моделируют и предсказывают эти свойства (например, среднее значение или дисперсию), поэтому прогнозы были бы неверными, если бы исходный ряд не был стационарным. К сожалению, большинство временных рядов, которые мы видим вне учебников, нестационарны, но мы можем (и должны) это изменить.

Итак, чтобы бороться с нестационарностью, мы должны, так сказать, знать своего врага. Посмотрим, как это обнаружить. Для этого мы теперь посмотрим на белый шум и случайные блуждания, и мы узнаем, как бесплатно, без регистрации и SMS, переходить от одного к другому.

Диаграмма белого шума:

Таким образом, процесс, генерируемый стандартным нормальным распределением, является стационарным и колеблется около 0 с отклонением 1. Теперь на основе этого процесса мы сгенерируем новый, в котором каждое следующее значение будет зависеть от предыдущего: x (t) = ρ * x (t − 1) + e (t)

Код отрисовки диаграммы

На первом графике вы можете увидеть тот же стационарный белый шум, который вы видели раньше. На втором значение ρρ увеличилось до 0,6, в результате чего на графике появились более широкие циклы, но в целом он все еще остается стационарным. Третий график еще больше отклоняется от среднего значения 0, но все еще колеблется вокруг него. Наконец, значение ρ, равное 1, дает нам процесс случайного блуждания - нестационарный временной ряд.

Это происходит потому, что после достижения критического значения ряд x (t) = ρ * x (t − 1) + e (t) не возвращается к своему среднему значению. Если мы вычтем x (t − 1) из левой и правой части, мы получим x (t) −x (t − 1) = (ρ − 1) * x (t − 1) + e (t), где выражение слева называется первой разницей. Если ρ = 1, то первая разность дает нам стационарный белый шум e (t). В этом заключается основная идея теста Дики-Фуллера на стационарность временных рядов (наличие единичного корня). Если мы можем получить стационарный ряд из нестационарного, используя первую разность, мы называем эти ряды интегрированными порядка 1. Нулевая гипотеза теста - временной ряд нестационарен, был отклонен на первых трех графиках и принят на последнем. . Мы должны сказать, что первой разницы не всегда достаточно для получения стационарного ряда, поскольку процесс может быть интегрирован в порядке d, d ›1 (и иметь несколько единичных корней), в таких случаях используется расширенный тест Дики-Фуллера. которая проверяет сразу несколько лагов.

Мы можем бороться с нестационарностью, используя разные подходы - различные различия в порядке, удаление тренда и сезонности, сглаживание, а также с использованием преобразований, таких как Бокс-Кокса или логарифмические.

Избавляемся от нестационарности и строим SARIMA

Теперь давайте построим модель ARIMA, пройдя через все адские круги этапов превращения серий в стационарные.

Код отрисовки диаграммы

Удивительно, но начальные ряды стационарны, тест Дики-Фуллера отверг нулевую гипотезу о наличии единичного корня. Собственно, это видно на самом графике - у нас нет видимой тенденции, поэтому среднее значение постоянно, а дисперсия в значительной степени стабильна на протяжении всей серии. Остается только сезонность, с которой мы должны столкнуться перед моделированием. Для этого возьмем «сезонную разницу», которая означает простое вычитание ряда из самого себя с запаздыванием, равным сезонному периоду.

Так лучше, видимая сезонность исчезла, однако функция автокорреляции по-прежнему имеет слишком много значительных лагов. Чтобы удалить их, возьмем первые разности - вычитание ряда из себя с лагом 1.

Идеально! Теперь наш ряд выглядит как нечто неописуемое, колеблющееся около нуля, Дики-Фуллер указывает, что он стационарный, и количество значимых пиков в ACF уменьшилось. Наконец-то мы можем приступить к моделированию!

Ускоренный курс ARIMA-family

Несколько слов о модели. Буквально по буквам построим полное название - SARIMA (p, d, q) (P, D, Q, s), Модель сезонной авторегрессии скользящего среднего:

  • AR (p) - модель авторегрессии, то есть регрессия временного ряда на себя. Основное предположение - текущие значения ряда зависят от его предыдущих значений с некоторым лагом (или несколькими лагами). Максимальное отставание в модели обозначается как p. Чтобы определить начальное p, вам нужно взглянуть на график PACF - найти наибольшую значительную задержку, после которой большинство других задержек перестают существенный.
  • MA (q) - модель скользящей средней. Не вдаваясь в подробности, он моделирует ошибку временного ряда, опять же предположение - текущая ошибка зависит от предыдущей с некоторым запаздыванием, которое обозначается как q. Начальное значение можно найти на графике АКФ по той же логике.

Давайте сделаем небольшой перерыв и объединим первые 4 буквы:

AR (p) + MA (q) = ARMA (p, q)

У нас есть модель авторегрессии - скользящего среднего! Если ряд является стационарным, его можно аппроксимировать этими 4 буквами. Продолжим?

  • I (d) - порядок интеграции. Это просто количество несезонных различий, необходимых для того, чтобы сделать ряд стационарным. В нашем случае это просто 1, потому что мы использовали первые различия.

Добавление этой буквы к четырем предыдущим дает нам модель ARIMA, которая знает, как обрабатывать нестационарные данные с помощью несезонных различий. Круто, осталось последнее письмо!

  • S (s) - эта буква отвечает за сезонность и равна продолжительности периода сезона в ряду.

После прикрепления последней буквы обнаруживаем, что вместо одного дополнительного параметра получаем три подряд - (P, D, Q)

  • P - порядок авторегрессии для сезонного компонента модели, опять же, может быть получен из PACF, но на этот раз вам нужно посмотреть на количество значительных лагов, которые являются кратные длине периода сезона, например, если период равен 24 и, глядя на PACF, мы видим, что 24-е и 48-е лагы значительны, что означает начальное P должно быть 2.
  • Q - та же логика, но для модели скользящего среднего сезонной составляющей используйте график ACF.
  • D - порядок сезонной интеграции. Может быть равно 1 или 0, в зависимости от того, применялись сезонные разницы или нет.

Теперь, зная, как установить начальные параметры, давайте еще раз посмотрим на окончательный график и зададим параметры:
tsplot(ads_diff[24+1:], lags=60)

  • p, скорее всего, равно 4, поскольку это последнее существенное отставание от PACF, после которого большинство других становятся несущественными.
  • d просто равно 1, потому что у нас были первые различия
  • q должно быть где-то около 4, как показано на ACF
  • P может быть 2, так как 24-е и 48-е лагы несколько значительны для PACF.
  • D снова равно 1 - мы провели сезонную дифференциацию.
  • Q, вероятно, 1, 24-е отставание от ACF - значительное, а 48-е - нет.

Теперь мы хотим протестировать разные модели и посмотреть, какая из них лучше.

Out: 54
CPU times: user 41.3 s, sys: 2.76 s, total: 44.1 s
Wall time: 37.4 s

Давайте проверим остатки модели
tsplot(best_model.resid[24+1:], lags=60)

Что ж, ясно, что остатки стационарны, явных автокорреляций нет, давайте сделаем прогнозы по нашей модели

В конце концов, мы получили вполне адекватные прогнозы, наша модель в среднем была ошибочной на 4,01%, что очень хорошо, но общие затраты на подготовку данных, создание стационарных рядов и выбор параметров методом грубой силы могут не стоить такой точности.

Линейные (и не совсем) модели на временных рядах

Снова небольшое лирическое отступление. Часто в моей работе мне приходится строить модели, руководствуясь единственным принципом, которым я руководствуюсь: быстро, хорошо, дешево. Это означает, что некоторые модели никогда не будут готовы к производству, поскольку они требуют слишком много времени для подготовки данных (например, SARIMA), или требуют частого переобучения на новых данных (опять же, SARIMA), или их сложно настроить. (хороший пример - SARIMA), поэтому очень часто гораздо проще выбрать пару функций из существующих временных рядов и построить простую линейную регрессию или, скажем, случайный лес. Хорошо и дешево.

Возможно, этот подход не подкреплен теорией, нарушает различные предположения (например, теорему Гаусса-Маркова, особенно о некоррелированности ошибок), но он очень полезен на практике и довольно часто используется в соревнованиях по машинному обучению.

Выделение признаков

Хорошо, модели нужны функции, и все, что у нас есть, - это одномерный временной ряд, с которым можно работать. Какие функции мы можем исключить?

Конечно, лаги временных рядов

Статистика окна:

  • Максимальное / минимальное значение серии в окне
  • Среднее / медианное значение в окне
  • Окно дисперсии
  • и т.п.

Функции даты и времени:

  • Минута часа, час дня, день недели, вы понимаете
  • Этот день праздник? Может, случилось что-то особенное? Сделайте это логической функцией

Целевая кодировка

Прогнозы от других моделей (хотя в этом случае мы можем потерять скорость предсказания)

Давайте рассмотрим некоторые методы и посмотрим, что мы можем извлечь из нашей серии объявлений.

Лаги временных рядов

Сдвигая ряд n на шаг назад, мы получаем столбец характеристик, в котором текущее значение временного ряда выравнивается с его значением в момент времени t − n . Если мы сделаем сдвиг на 1 задержку и обучим модель этой функции, модель сможет прогнозировать на 1 шаг вперед, наблюдая за текущим состоянием ряда. Увеличение задержки, скажем, до 6 позволит модели делать прогнозы на 6 шагов вперед, однако она будет использовать данные, полученные на 6 шагов назад. Если что-то коренным образом изменит ряд в течение этого ненаблюдаемого периода, модель не уловит эти изменения и будет возвращать прогнозы с большой ошибкой. Таким образом, при выборе начального лага необходимо найти баланс между оптимальным качеством прогноза и длиной горизонта прогнозирования.

Замечательно, у нас есть набор данных, почему бы нам не обучить модель?

Что ж, простые лаги и линейная регрессия дали нам прогнозы, которые по качеству не так уж далеки от SARIMA. Есть много ненужных функций, но мы сделаем их выбор чуть позже. А теперь продолжим разработку!

Мы добавим в наш набор данных час, день недели и логическое значение для выходных. Для этого нам нужно преобразовать текущий индекс фрейма данных в формат datetime и извлечь из него hour и weekday.

Мы можем визуализировать полученные особенности

Поскольку теперь у нас есть разные шкалы переменных - тысячи для запаздывающих характеристик и десятки для категориальных, разумно преобразовать их в ту же шкалу, чтобы продолжить изучение важности функций, а позже - регуляризацию.

Погрешность теста немного уменьшается и, судя по графику коэффициентов, можно сказать, что weekday и is_weekend - весьма полезные функции.

Целевая кодировка

Хочу добавить еще один вариант кодирования категориальных переменных - по среднему значению. Если нежелательно разбивать набор данных с помощью множества фиктивных переменных, которые могут привести к потере информации о расстоянии, и если они не могут использоваться в качестве реальных значений из-за конфликтов типа «0 часов‹ 23 часа », тогда это можно закодировать переменную с немного более интерпретируемыми значениями. Естественная идея заключается в кодировании со средним значением целевой переменной. В нашем примере каждый день недели и каждый час дня можно закодировать соответствующим средним количеством просмотров рекламы в течение этого дня или часа. Очень важно убедиться, что среднее значение рассчитывается только по набору поездов (или только по текущей кратной перекрестной проверке), чтобы модель не знала о будущем.

Давайте посмотрим на средние часовые

Наконец, объедините все преобразования в одну функцию

А вот и переоснащение! Переменная Hour_average была настолько хороша в наборе данных поезда, что модель решила сосредоточить на ней все свои силы - в результате качество прогнозов упало. К этой проблеме можно подойти разными способами, например, мы можем вычислить целевую кодировку не для всего набора поездов, а вместо этого для некоторого окна, таким образом кодировки из последнего наблюдаемого окна, вероятно, будут лучше описывать текущее состояние серии. Или мы можем просто сбросить его вручную, так как мы уверены, что здесь это только ухудшает ситуацию.

Регуляризация и выбор функций

Как мы уже знаем, не все функции одинаково полезны, некоторые из них могут привести к переобучению, и их следует удалить. Помимо ручной проверки, мы можем применить регуляризацию. Две самые популярные модели регрессии с регуляризацией - это регрессии Риджа и Лассо. Оба они добавляют еще несколько ограничений к нашей функции потерь.

В случае регрессии гребня - эти ограничения представляют собой сумму квадратов коэффициентов, умноженную на коэффициент регуляризации. Т.е. чем больше коэффициент - тем больше будут наши потери, поэтому мы постараемся оптимизировать модель, сохраняя при этом коэффициенты на довольно низком уровне.

В результате такой регуляризации, которая носит гордое название L2, у нас будет более высокое смещение и более низкая дисперсия, поэтому модель будет лучше обобщать (по крайней мере, мы надеемся, случаться).

Вторая модель - Лассо-регрессия, здесь мы добавляем к функции потерь не квадраты, а абсолютные значения коэффициентов, в результате в процессе оптимизации коэффициенты несущественных признаков могут стать нулями , поэтому регрессия Лассо позволяет автоматически выбирать функции. Этот тип регуляризации называется L1.

Во-первых, убедитесь, что у нас есть вещи, которые можно выбросить, и что данные действительно имеют сильно коррелированные функции.

Мы можем ясно видеть, как коэффициенты становятся все ближе и ближе к нулю (мысли никогда не достигают этого), поскольку их важность в модели падает.

Регрессия лассо оказалась более консервативной и удалила 23-е отставание от наиболее важных функций (а также полностью отбросила 5 функций), что только улучшило качество предсказания.

Повышение

Почему бы не попробовать XGBoost сейчас?

Вот победитель! Самая маленькая ошибка на тестовом наборе среди всех моделей, которые мы пробовали до сих пор.

Тем не менее, эта победа неутешительна, и, возможно, это не самая лучшая идея установить xgboost, как только вы получите в свои руки данные временных рядов. Как правило, древовидные модели плохо обрабатывают тенденции в данных по сравнению с линейными моделями, поэтому вам нужно сначала избавиться от тренда в своих рядах или использовать некоторые уловки, чтобы волшебство произошло. В идеале - сделайте ряд стационарным, а затем используйте XGBoost, например, вы можете прогнозировать тренд отдельно с помощью линейной модели, а затем добавлять прогнозы из xgboost, чтобы получить окончательный прогноз.

Заключение

Мы познакомились с различными методами и подходами к анализу и прогнозированию временных рядов. К сожалению, а может быть, к счастью, серебряной пули для решения подобных проблем не существует. Методы, разработанные в 60-х годах прошлого века (а некоторые даже в начале XIX века), до сих пор популярны наряду с LSTM и RNN (в этой статье не рассматриваются). Частично это связано с тем, что задача прогнозирования, как и любая другая задача, связанная с данными, является творческой во многих аспектах и ​​определенно требует исследования. Несмотря на большое количество формальных показателей качества и подходов к оценке параметров, часто требуется искать и пробовать что-то свое для каждого временного ряда. И последнее, но не менее важное: баланс между качеством и стоимостью. В качестве хорошего примера упомянутая здесь модель SARIMA не один или два раза может дать впечатляющие результаты после должной настройки, но может потребовать многочасовых манипуляций с временными рядами танца бубна, так как в то же время простая модель линейной регрессии может быть построена за 10 минут, давая более или менее сопоставимые результаты.

Задание №9

Полные версии заданий объявляются каждую неделю в новом прогоне курса (1 октября 2018 г.). А пока вы можете потренироваться с демо-версией: Kaggle Kernel, nbviewer.

Полезные ресурсы

Автор: Дмитрий Сергеев. Перевод и редакция: Борис Зибров, Юаньюань Пао.