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

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

  1. Обработка пропущенных значений
  2. Удалить тренд
  3. Удалить сезонность
  4. Проверить на стационарность и при необходимости сделать стационарным
  5. Нормализация данных
  6. Удалить выбросы
  7. Сглаживание данных

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

Первые шаги

Мы будем использовать набор данных из Kaggle, который собирает значения ежемесячного производства пива в Австралии с 1956 по 1995 год.

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

# Import required libraries
import pandas as pd
import numpy as np

# Read dataset file
df = pd.read_csv("/monthly-beer-production-in-austr.csv")

# Check data types
print(df.dtypes)

# Show the top five rows of the dataset
df.head()

Мы замечаем две вещи:

  • Дата имеет неправильный тип данных, она должна быть datetime.
  • Индекс не является датой кадра данных, и это важное требование, когда мы имеем дело с данными временных рядов.

Поэтому следующим шагом будет преобразование даты в datetime и установка ее в качестве индекса.

# Convert the month column to datetime
df['Month'] = pd.to_datetime(df['Month'], format='%Y-%m')

# Set the date as the index
df = df.set_index('Month')

# Convert the dataframe to series
df_beer = df['Monthly beer production']

Как только это будет сделано, мы можем построить это:

# Import required libraries
import matplotlib.pyplot as plt

# Plot data
df_beer.plot(figsize=(14,6))
plt.xlabel('Date')
plt.ylabel('Monthly beer production')
plt.grid()
plt.show()

Давайте попробуем обобщить основные проблемы данных, просто взглянув на предыдущий график:

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

Вот некоторые из вопросов, которые нам необходимо решить в процессе очистки данных.

Очистка данных

Обработка пропущенных значений

Нам нужно проверить, есть ли у нас пропущенные значения или нет.

# Check for missing values
df.isna().sum()

На этот раз нам повезло, пропущенных значений нет.

Если бы мы это сделали, мы могли бы справиться с этим такими методами, как:

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

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

# Imputation of constant value
df_beer = df_beer.fillna(0)

# Mean imputation
df_beer = df_beer.fillna(df_beer.mean())

# Backward-fill imputation (or last observation carried forward)
df_beer = df_beer.bfill()

# Linear interpolation
df_beer = df_beer.interpolate(method='linear')

Но, как упоминалось ранее, при текущих данных в этом нет необходимости.

Удалить тренд

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

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

  1. Разница: вычитание наблюдений из предыдущего периода времени для стабилизации среднего значения ряда с течением времени.
  2. Разложение: разбиение временного ряда на трендовые, сезонные и остаточные компоненты и удаление трендового компонента.
  3. Скользящие средние: вычисление среднего значения наблюдений за фиксированное количество периодов времени и вычитание его из каждого наблюдения.
  4. Полиномиальная аппроксимация: подбор полиномиальной кривой к данным временного ряда и вычитание ее из исходного ряда для удаления тренда.
  5. Фильтры трендов: использование таких фильтров, как фильтр Ходрика-Прескотта или фильтр Калмана, для удаления компонента тренда.
  6. Log Transformations: логарифмирование данных временного ряда для уменьшения величины тренда и стабилизации дисперсии ряда.
  7. Преобразования Бокса-Кокса: преобразование данных временных рядов с использованием степенного преобразования для стабилизации дисперсии и придания тренду линейности.

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

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

# Take the first difference of the data to remove the trend
df_beer = df_beer.diff()

# Drop the first NaN value coming from taking the difference 
df_beer = df_beer.dropna()

# Plot the data to see the outcome
df_beer.plot(figsize=(15,5))
plt.xlabel('Date')
plt.ylabel('Beer production increase rate')
plt.grid()
plt.show()

Мы видим, что среднее значение теперь приблизительно постоянно около нуля. Однако есть еще одна проблема, которую необходимо решить: непостоянная или растущая дисперсия.

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

# Calculate each year's variance (equivalent to standard deviation)
annual_variance = df_beer.groupby(df_beer.index.year).std()
mapped_annual_variance = df_beer.index.map(
    lambda x: annual_variance.loc[x.year])

# Standardize each year's variance
df_beer = df_beer / mapped_annual_variance

# Plot outcome
df_beer.plot(figsize=(15,5))
plt.xlabel('Date')
plt.ylabel('Standardized beer production rate')
plt.grid()
plt.show()

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

Вы можете получить доступ к блокноту в нашем репозитории на github.

Смотрите все части серии очистки данных:

  1. Пропущенные значения и детрендирование
  2. Убрать сезонность и нормализовать данные
  3. Удаление выбросов
  4. Сглаживание данных

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

Подпишитесь на DDIntel Здесь.

Посетите наш сайт здесь: https://www.datadriveninvestor.com

Присоединяйтесь к нашей сети здесь: https://datadriveninvestor.com/collaborate