Инструменты перекрестной проверки для временных рядов

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

В этой публикации я рассмотрю методы перекрестной проверки, подходящие для моделей машинного обучения, работающих с (определенным типом) данных временных рядов, на основе превосходной работы Маркоса Лопеса де Прадо Достижения в области финансового машинного обучения. Классы стиля Scikit-learn, реализующие описанные ниже алгоритмы перекрестной проверки, можно найти на Github. По причинам, которые станут ясны, они не совсем следуют стандартному шаблону Scikit-learn.

Данные временного ряда

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

Рассмотрим следующую проблему.

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

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

  • В систематической торговой стратегии мы могли бы зафиксировать некоторые правила, определяющие, когда закрывать открытые торговые позиции. Учитывая эти правила, мы хотели бы использовать алгоритм машинного обучения для открытия позиций таким образом, чтобы максимизировать прибыль. В определенный момент нам нужно решить, открывать позицию или нет. Однако доходность позиции (ответ) не будет известна ранее неизвестного времени, а именно до тех пор, пока позиция не будет закрыта в соответствии с правилами закрытия.
  • Предположим, что сервис, подобный GoogleMap, пытается спрогнозировать условия дорожного движения и соответствующее время в пути в поездке, где доступно несколько маршрутов. Модель машинного обучения отправит своих пользователей по маршруту, который, по ее мнению, является самым быстрым во время прогнозирования, но эффективное время в пути каждого пользователя (ответ) будет доступно только позже, когда они завершат свое путешествие.

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

Мы обсудим стратегии перекрестной проверки, адаптированные к такого рода задачам.

Проблемы со стандартными алгоритмами перекрестной проверки

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

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

При применении этих классических алгоритмов перекрестной проверки к данным временных рядов возникают две проблемы:

  • Данные временных рядов упорядочены по времени. В реальных приложениях мы используем прошлые наблюдения для прогнозирования будущих наблюдений. Рандомизация в стандартном алгоритме перекрестной проверки не сохраняет временной порядок, и в конечном итоге мы делаем прогнозы для некоторых выборок, используя модель, обученную на апостериорных выборках. Мы увидим, что само по себе это не такая уж большая проблема. Следующая проблема гораздо серьезнее.
  • Данные временных рядов часто сильно коррелированы по оси времени (подумайте о примере GoogleMap: пробка затрагивает всех пользователей на одном и том же маршруте в данный момент времени). Рандомизация повысит вероятность того, что для каждой выборки в наборе проверки существует множество строго коррелированных выборок в наборе поездов. Это сводит на нет саму цель наличия набора для проверки: модель по существу «знает» о наборе проверки уже, что приводит к завышению показателей производительности на наборе проверки в случае переобучения.

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

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

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

  1. Набор поездов: блоки с 1 по p, набор для проверки: блок p + 1
  2. Набор поездов: блоки с 2 по p + 1, набор для проверки: блок p + 2

Таким образом, «идя вперед» в полном наборе примеров, можно построить k-p разбиения. Это большое улучшение по сравнению с классическими алгоритмами перекрестной проверки, но некоторые проблемы остаются.

  1. Вблизи точки разделения у нас могут быть обучающие выборки, время оценки которых является апостериорным временем предсказания проверочных выборок. Такие перекрывающиеся выборки вряд ли будут независимыми, что приведет к утечке информации из набора поездов в набор для проверки.
  2. Невозможно сделать k-p очень большим, что приведет к большим разбросам в статистике производительности.
  3. Самая важная часть набора данных, а именно самая последняя, ​​также используется меньше всего. Это может быть проблемой для временных рядов, подверженных изменениям режима в течение длительных периодов времени, как это часто бывает в финансовых временных рядах.

Очистка

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

Комбинаторная перекрестная проверка

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

Комбинаторная K -кратная перекрестная проверка аналогична K -кратной перекрестной проверке, за исключением того, что мы принимаем набор проверки, состоящий из j ‹K блоки образцов. Затем мы должны K выбрать j возможных различных разделений. Это позволяет нам легко создавать большое количество разбиений, просто взяв j = 2 или 3 для решения проблемы 2. Поскольку все блоки выборок обрабатываются одинаково, это также решает проблему 3.

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

Затрудняющий

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

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

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

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

Простая прямая перекрестная проверка доступна в scikit-learn. Реализация продуванной сквозной перекрестной проверки также доступна в книге Маркоса Лопеса де Прадо.

Я реализовал очищенную прямую перекрестную проверку и удаленную комбинаторную перекрестную проверку, запрещенную к использованию. Код можно найти на Github. Строки документации различных классов и функций должны быть достаточно понятными. API максимально похож на API scikit-learn. Основные отличия:

  • Метод split принимает в качестве аргументов не только значения предикторов X, но также время прогнозирования pred_times и время оценки eval_times каждого образца.
  • Чтобы максимально приблизиться к API scikit-learn, эти данные передаются как отдельные параметры. Но чтобы гарантировать, что они правильно выровнены, X, pred_times и eval_times должны быть pandas DataFrames / Series с одним и тем же индексом.

Подобно модулям scikit-learn, split - это генератор, который генерирует пару массивов numpy, содержащих позиционные индексы образцов в наборе поездов и проверок соответственно.