Анализируйте тренд и компоненты сезонности из временного ряда
Анализ сезонности из данных временных рядов часто может быть полезен в аналитике данных. Это помогает анализировать сезонность для принятия решений, а также для более точных прогнозов. Python можно использовать для разделения этих трендовых и сезонных компонентов.
Набор данных
Обзор
Данные временных рядов, которые мы будем анализировать, - это Сводка преступлений в Канзас-Сити, а именно количество преступлений взлома и проникновения в месяц. Как вы думаете, будут ли в этих данных какие-либо сезонные составляющие? Давайте разберемся.
Первоначальная визуализация
Для начала исходные данные визуализируются ниже с помощью Power BI - это помогает увидеть любую сезонность, которую можно обнаружить визуально. Похоже, есть общая тенденция к снижению и, похоже, некоторая сезонность - февраль часто является самой низкой точкой, в то время как количество преступлений возрастает летом и в праздничные дни.
Однако насколько сильно зависит от сезонности по сравнению с тенденцией и как автоматизировать разделение компонентов сезонности?
Сезонная декомпозиция
Обзор
В библиотеке statsmodels в Python есть функция Season_decompose, которая делает именно это. Для данного временного ряда данных функция разделяется на отдельные составляющие тренда, сезонности и остаточного (шума).
После загрузки и переформатирования данных в эту функцию будут загружены дата и метрика для анализа отдельных частей.
Загрузка данных
Чтобы получить данные в правильной форме, нужно сделать 4 основных шага:
- Считывание данных: данные будут считаны в фрейм данных pandas с помощью функции pandas.read_csv.
- Выделите только столбцы даты и метрики: нам нужны только компонент даты (ежемесячно для этого набора данных) и метрика (столбец Кража со взломом / Нарушение и ввод).
- Нормализация данных. Поскольку в каждом месяце разное количество дней, деление ежемесячных итогов на количество дней в месяце дает более сопоставимое среднее дневное количество, которое можно использовать.
- Установите индекс даты фрейма данных: установка нашего столбца даты в качестве индекса фрейма данных pandas позволяет упростить настройку при использовании функции сезонного разложения. Дополнительные примеры по установке индекса можно найти здесь.
Код для этих четырех шагов следующий:
Шаг 1. Загрузка данных
# Load Data
df = pd.read_csv("../data/Kansas_City_Crime__NIBRS__Summary.csv")
# Choose only necessary columns
df = df[['Date', 'Burglary/Breaking and Entering']]
# Normalize Metric
df['Burglary/Breaking and Entering'] = \
df['Burglary/Breaking and Entering'] \
/ pd.to_datetime(df['Date']).dt.day
# Set date index
df = set_date_index(df, 'Date') # custom helper function
В качестве вспомогательной функции используется одна настраиваемая функция, установить индекс даты, чтобы выделить форматирование даты в отдельную функцию.
Он создает копию фрейма данных (чтобы оставить исходные данные нетронутыми), устанавливает столбец даты в тип datetime и, наконец, сортирует и устанавливает индекс.
Вспомогательная функция: сортировка и установка индекса даты и времени
def set_date_index(input_df, col_name='Date'):
"""Given a pandas df, parse and set date column to index.
col_name will be removed and set as datetime index.
Args:
input_df (pandas dataframe): Original pandas dataframe
col_name (string): Name of date column
Returns:
pandas dataframe: modified and sorted dataframe
"""
# Copy df to prevent changing original
modified_df = input_df.copy()
# Infer datetime from col
modified_df[col_name] = pd.to_datetime(modified_df[col_name])
# Sort and set index
modified_df.sort_values(col_name, inplace=True)
modified_df.set_index(col_name, inplace=True)
return modified_df
Тренд или сезонность
Следующая часть фактически выполняет сезонную декомпозицию. Фрейм данных передается в качестве аргумента, а также period = 12 для представления наших ежемесячных данных и определения годовой сезонности. # Seasonal decompose
sd = seasonal_decompose(df, period=12)
combine_seasonal_cols(df, sd) # custom helper function
Одна дополнительная вспомогательная функция использовалась для простого добавления результатов в исходный фрейм данных в виде новых столбцов.
Вспомогательная функция: сочетание сезонного_decompose с исходными столбцами
def combine_seasonal_cols(input_df, seasonal_model_results):
"""Adds inplace new seasonal cols to df given seasonal results
Args:
input_df (pandas dataframe)
seasonal_model_results (statsmodels DecomposeResult object)
"""
# Add results to original df
input_df['observed'] = seasonal_model_results.observed
input_df['residual'] = seasonal_model_results.resid
input_df['seasonal'] = seasonal_model_results.seasonal
input_df['trend'] = seasonal_model_results.trend
Вывод
Наконец, результаты были записаны в локальный CSV-файл для визуализации в Power BI. Если бы это был повторяющийся процесс, мы могли бы настроить API или использовать облачные сервисы для размещения нашей модели; однако для одноразового запуска вполне подойдет локальный CSV-файл.
Вывод результатов для визуализации
df.to_csv("../data/results.csv")
Визуализируйте результаты
Визуализируя окончательный результат, к исходному графику добавляются новые сезонные (темно-синие) и трендовые (оранжевые) линии.
Была выявлена небольшая тенденция к снижению наряду с сезонной составляющей (добавление или вычитание из тенденции до 4 преступлений в день).
Изящная часть этой методологии состоит в том, что компоненты тренда, сезонности и остатка добавляются к исходному временному ряду. На визуализации ниже вы увидите, как добавление компонентов тренда и сезонности более или менее возвращает к исходному набору данных (остаточная часть / шум - это оставшаяся часть).
Преступления, кажется, самые низкие в феврале из-за сезонности (холодная погода?), И возрастают в летние месяцы и в праздничные дни.
Резюме
Используя библиотеку statsmodels в Python, мы смогли разделить временные ряды на сезонные и трендовые компоненты. Это может быть полезно для прогнозирования - например, для расширения тренда и последующего добавления тех же сезонных подъемов и падений в будущее. Это также может быть полезно при анализе важности сезонности степени - например, если вы хотите узнать, в какое время года следует сосредоточить ресурсы.
Заинтересованы в ваших мыслях, если вы нашли этот подход полезным или использовали разные подходы в прошлом для решения аналогичных проблем - прокомментируйте ниже!
Все примеры и файлы доступны на Github.
Первоначально опубликовано на https://datastud.dev.