Пропуски во временных рядах | Анализ и обработка данных

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

Все курсы > Анализ и обработка данных > Занятие 7

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

Откроем ноутбук к этому занятию

Подготовка данных

Продолжим работать с данными об авиаперевозках и рождаемости. Скачаем и подгрузим датасеты.

Почему именно эти два датасета?

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

Добавим пропуски в данные о пассажирских перевозках.

Посмотрим на результат.

пропуски во временных рядах, датасет passengers

Обсудим.

  • В столбце reference сохранились все данные без пропусков.
  • В столбце target мы случайным образом создали 20 процентов пропущенных значений. Именно этот столбец мы будем использовать в процессе заполнения пропусков.
  • В столбце missing, наоборот, пропусками являются те значения, которые заполнены в target. Этот столбец мы будем использовать исключительно для построения визуализаций.

Проделаем то же самое с датасетом о рождаемости.

пропуски во временных рядах, датасет births

Визуализация

Выведем данные на графиках. Перед этим в учебных целях сократим временные интервалы.

  • Это упростит применение методов заполнения пропусков, поскольку на полных временных рядах некоторые методы оставляют отдельные пропуски незаполненными.
  • Кроме того, иллюстрации станут более наглядными.
визуализация пропущенных значений во временных рядах: датасет passengers

Сделаем то же самое с данными о рождаемости.

визуализация пропущенных значений во временных рядах: датасет births

Итак, говоря проще, нам нужно заполнить значения зеленых точек на основе значений оранжевых точек.

Заполнение средним и медианой

Самый простой подход к заполнению пропусков — использовать среднее арифметическое или медиану.

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

Заполнение предыдущим и последующим значениями

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

  • Подход last observation carried forward (LOCF) предполагает, что мы берем предыдущее от пропущенного значение и заполняем им пропуск.
  • Подход next observation carried backward (NOCB), наоборот, заполняет пропуск последующим значением.

В библиотеке Pandas для реализации этих подходов есть соответственно методы .ffill() и .bfill().

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

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

Заполнение скользящим средним и медианой

Для заполнения пропусков можно использовать не одно предыдущее или последующее значение, а несколько. Вспомним про скользящее среднее, которое рассчитывается с помощью методов .rolling() и .mean(). Помимо среднего арифметического ничто не мешает нам рассчитать медиану окна и заполнить ею пропущенное значение.

Здесь нужно уточнить настройки:

  • Размер окна (параметр window).
  • Минимальное количество периодов для расчета среднего и медианы (min_periods). Установим этот параметр на уровне min_periods = 1, чтобы избежать сохранения незаполненных значений.

Интерполяция

Понятие интерполяции

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

Что важно знать про интерполяцию:

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

Введем некоторые термины:

  • Значения $x$ каждой из известных точек, по которым строится интерполирующая функция, называются узлами (knots)
  • Совокупность точек — интерполяционной сеткой (grid)
  • Сама функция называется интерполянтом (interpolant)

Посмотрим на график ниже (код для построения графика можно найти в ноутбуке, он нам сейчас не важен).

график линейной интерполяции и интерполяции кубическим сплайном

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

Рассмотрим эти способы интерполяции более подробно.

Способы интерполяции

Линейная интерполяция

Самый простой способ — построить линейную функцию, проходящую через две соседние точки. Например, предположим, что соседними наблюдениями ($x_0$, $y_0$) и ($x_1$, $y_1$) являются точки с координатами (1, 3) и (3, 5). Найдем значение в точке $x = 2$.

Так как все три точки лежат на одной прямой, наклон этой прямой между любыми двумя точками одинаков. Из уравнения наклона,

$$ \frac{y-y_0}{x-x_0} = \frac{y_1-y_0}{x_1-x_0} $$

$$ y = \frac{y_0(x_1-x)+y_1(x-x_0)}{x_1-x_0} $$

Тогда в точке $x = 2$

$$ y = \frac{3(3-2)+5(2-1)}{3-1} = 4 $$

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

$$ \begin{cases} y_0 = a_0 + a_1 \cdot x_0 \\ y_1 = a_0 + a_1 \cdot x_1 \end{cases} $$

Подставив известные точки,

$$ \begin{cases} 3 = a_0 + a_1 \cdot 1 \\ 5 = a_0 + a_1 \cdot 3 \end{cases} $$

Решив систему линейных уравнений, получим

$$ y = x + 2 $$

Значение функции в точке $x = 2$ равно четырем.

Полиномиальная интерполяция

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

Полиномиальная интерполяция имеет ряд недостатков. В частности, с ростом числа точек у кривой могут возникнуть колебания (осциляции), которые негативно скажутся на точности заполнения пропусков. Эта особенность называется феноменом Рунге (Runge’s phenomenon).

Сплайн

При линейной интерполяции мы строили отдельную линейную функцию между каждой парой известных точек. Сплайн (от англ. spline, «чертежное лекало») также состоит из нескольких функций (по одной на каждый отрезок), но не линейных, а полиномиальных.

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

Перейдем к практике.

Реализация на Питоне

В Питоне интерполяцию можно выполнить либо с помощью модуля interpolate⧉ библиотеки Scipy, либо с помощью во многом опирающегося на этот модуль метода .interpolate()⧉ библиотеки Pandas.

Создадим список из названий методов интерполяции, которые передадим в .interpolate()

Обратите внимание, как видно из документации Scipy, значения параметра method = ‘quadratic’ и method = ‘cubic’ метода .interpolate() в Pandas рассчитывают квадратичный и кубический сплайны, а не полиномы второй и третьей степени.

В цикле for найдем интеполирующую функцию с помощью каждого из методов и используем ее для заполнения пропусков (создания нового столбца с полными значениями).

Сравнение методов

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

Напишем функцию для сравнения методов.

Сравним методы заполнения пропусков.

сравнение методов, датасет passengers
сравнение методов, датасет births

Выведем «лидеров» на графиках и сравним с соответствующими референтными значениями.

заполнение пропусков в данных о пассажирах методом spline 5-го порядка
заполнение пропусков в данных о рождаемости средним арифметическим

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

Библиотека imputena

Еще один способ заполнения пропусков в нестационарных временных рядах заключается в том, чтобы

Такой способ называется заполнением пропусков с сезонной корректировкой (seasonal adjustment), и он реализован в библиотеке imputena⧉.

Прежде чем перейти непосредственно к заполнению пропусков, воспользуемся функцией recommend_method() для получения рекомендации по тому, какой метод использовать.

Алгоритм согласился с тем, что интерполяция с сезонной корректировкой будет наиболее удачным методом. Применим ее с помощью функции seasonal_interpolation().

Рассчитаем RMSE.

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

Подведем итог

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

Выбор конкретного способа интерполяции во многом зависит от стационарности и шага временного ряда.

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