Использование кластеризации временных рядов для более точного прогнозирования спроса

Это седьмая часть серии Временные ряды изменения климата. Список статей:

Сокращение пищевых отходов

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

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

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

Кластеризация временных рядов спроса на продовольствие

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

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

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

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

Кластеризация временных рядов спроса также полезна для бизнеса. Выявление похожих продуктов полезно для создания более эффективных стратегий маркетинга или продвижения.

Руки вверх

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

  • суммировать набор временных рядов, используя извлечение признаков;
  • используйте K-Means и иерархический метод для кластеризации временных рядов.

Полный код доступен на Github:

Набор данных

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

Ниже приведен пример набора данных:

Вот как выглядят все данные:

Кластеризация временных рядов на основе признаков

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

  1. Суммируйте каждый временной ряд в набор функций, таких как среднее значение;
  2. Примените обычный алгоритм кластеризации к набору признаков, например K-средних.

Давайте сделаем каждый шаг по очереди.

Извлечение признаков с помощью tsfel

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

Существует несколько инструментов для извлечения признаков временных рядов. Мы будем использовать tsfel, который обеспечивает конкурентоспособную производительность по сравнению с другими подходами [3].

Вот как вы можете использовать tsfel:

import pandas as pd
import tsfel

# get configuration
cfg = tsfel.get_features_by_domain()

# extract features for each food subcategory
features = {col: tsfel.time_series_features_extractor(cfg, data[col])
            for col in data}

features_df = pd.concat(features, axis=0)

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

Ниже мы применяем три операции к набору функций:

  • нормализация: преобразование переменных в диапазон значений 0–1;
  • выбор по дисперсии: удалить любую переменную с 0 дисперсией;
  • выбор по корреляции: удалить любую переменную с высокой корреляцией с другой существующей.
from sklearn.preprocessing import MinMaxScaler
from sklearn.feature_selection import VarianceThreshold
from src.correlation_filter import correlation_filter

# normalizing the features
features_norm_df = pd.DataFrame(MinMaxScaler().fit_transform(features_df),
                                columns=features_df.columns)

# removing features with 0 variance
min_var = VarianceThreshold(threshold=0)
min_var.fit(features_norm_df)
features_norm_df = pd.DataFrame(min_var.transform(features_norm_df),
                                columns=min_var.get_feature_names_out())

# removing correlated features
features_norm_df = correlation_filter(features_norm_df, 0.9)
features_norm_df.index = data.columns

Кластеризация с помощью K-средних

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

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

Ниже мы тестируем K-средние до 24 кластеров. Затем мы выбираем количество кластеров, которое максимизирует оценку силуэта. Эта метрика количественно определяет сплоченность полученных кластеров.

from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

kmeans_parameters = {
    'init': 'k-means++',
    'n_init': 100,
    'max_iter': 50,
}

n_clusters = range(2, 25)
silhouette_coef = []
for k in n_clusters:
    kmeans = KMeans(n_clusters=k, **kmeans_parameters)
    kmeans.fit(features_norm_df)

    score = silhouette_score(features_norm_df, kmeans.labels_)

    silhouette_coef.append(score)

Оценка силуэта максимальна для 5 кластеров, как показано на рисунке ниже.

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

Мы также можем использовать информацию о кластерах для улучшения моделей прогнозирования спроса. Например, путем построения модели для каждого кластера. Статья в ссылке [5] является хорошим примером такого подхода.

Иерархическая кластеризация

Иерархическая кластеризация является альтернативой K-средним. Он итеративно объединяет пары кластеров, что приводит к древовидной структуре. Библиотека scipy обеспечивает реализацию этого метода.

import scipy.cluster.hierarchy as shc

# hierarchical clustering using the ward method
clustering = shc.linkage(features_norm_df, method='ward')

# plotting the dendrogram
dend = shc.dendrogram(clustering,
                      labels=categories.values,
                      orientation='right',
                      leaf_font_size=7)

Результаты иерархической модели кластеризации лучше всего визуализировать с помощью графика дендрограммы:

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

Ключевые выводы

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

Спасибо за прочтение и до встречи в следующей истории!

Рекомендации

[1] Дженни Густавссон, Кристель Седерберг, Ульф Сонессон, Роберт Ван Оттердейк и Александр Мейбек. 2011. Глобальные потери продовольствия и пищевые отходы. Продовольственная и сельскохозяйственная организация Объединенных Наций, Рим.

[2] Еженедельные розничные продажи продуктов питания Службы экономических исследований (Лицензия: общественное достояние)

[3] Хендерсон, Трент и Бен Д. Фулчер. «Анализ временных рядов на основе признаков в R с использованием пакета кражи». препринт arXiv arXiv:2208.06146 (2022).

[4] Ролник, Дэвид и др. «Борьба с изменением климата с помощью машинного обучения». Вычислительные исследования ACM (CSUR) 55.2 (2022): 1–96.

[5] Касун Бандара, Кристоф Бергмейр и Славек Смил. Прогнозирование по базам данных временных рядов с использованием рекуррентных нейронных сетей для групп похожих рядов: подход кластеризации. Экспертные системы с приложениями, 140:112896, 2020.