Проекты / кластеризация точек продаж

Проект · Python, SQL, DuckDB, scipy

Кластеризация точек продаж аптечной сети

Точки одной сети сильно различаются: центральная аптека, аптека у дома, дискаунтер, точка в торговом центре. Единый ассортимент для всех - это излишки в одних точках и упущенная выручка в других. Расчёт делит точки на сегменты с трёх сторон сразу: размер, ассортимент и цены.

Данные синтетические. Исходный расчёт выполнен для реальной аптечной сети, её данные публиковать нельзя. Здесь тот же подход воспроизведён на сгенерированной базе: справочник лекарств взят из открытого реестра Минздрава (перечень жизненно необходимых лекарств, ЖНВЛП), точки, чеки и остатки сгенерированы. Цифры не описывают реальный бизнес, но показывают, как работает метод.

Коротко
  • Задача. Один ассортимент на всю сеть означает излишки в одних точках и упущенную выручку в других. Нужно понять, какие типы точек есть в сети.
  • Что сделано. 234 аптеки разбиты на 13 сегментов по размеру, ассортименту и ценам - полностью автоматически, с понятными названиями вида «Большие · сердце и кровь · эконом».
  • Результат. Ассортиментным матрицам, построенным по этим сегментам, нужно на 43,0 млн ₽ меньше денег в остатках, чтобы удержать прибыль действующей матрицы. Для сравнения тот же метод, но без сегментов: одной матрице на всю сеть для той же прибыли понадобится на 63,1 млн ₽ больше остатков, чем сейчас, а матрицам по нынешним категориям площади A-E - на 26,7 млн ₽ больше остатков, чем сейчас: у маленьких аптек матрица по площади получается шире, чем им нужно. Подробности - на странице матрицы.
Аптек в расчёте
234 из 260
Строк чеков за 4 недели
562 тыс.
Товаров
3 200
Итоговых сегментов
13

1. Какие точки попадают в расчёт

В расчёт идут только аптеки, которые работают не меньше полугода: у новых точек ещё нет устойчивой истории продаж. Формат «оптика» сегментируется отдельно. Из чеков за 2 марта - 29 марта убираются опт, заказы через сторонние маркетплейсы, уценённый товар с коротким сроком годности и нетоварные позиции (пакеты, доставка): остаётся 562 тыс. строк из 622 тыс.

2. Размер: площадь и деньги

Размер точки меряется двумя способами: площадью торгового зала и «весом» в деньгах (выручка и число чеков). Их расхождение само по себе сигнал: большая площадь со слабыми продажами или маленькая точка с огромным трафиком. Точки с похожими показателями объединяются в группы (кластеры) алгоритмом иерархической кластеризации.

Выручка и число чеков точек за 4 неделиТочка на графике - аптека, цвет - группа по деньгам. Лучи из начала координат - форматы с разным средним чеком.
Подробнее: как выбирается число групп

Алгоритм склеивает точки снизу вверх: сначала каждая аптека - отдельная группа, затем на каждом шаге объединяются две самые похожие группы, пока не останется одна. У каждого склеивания есть «цена» - насколько выросла разнородность внутри групп. Пока объединяются похожие точки, цена маленькая; когда приходится склеивать действительно разные группы, она резко подскакивает. Останавливаемся перед скачком - это «локоть». Для проверки используется второй критерий - коэффициент силуэта: насколько каждая точка ближе к своей группе, чем к соседней (выше - чётче разделение). Число групп ищется в разумном для бизнеса диапазоне: деление сети всего на две группы для решений бесполезно.

По площади оба критерия указывают на одно и то же число. По ассортименту (локоть - 6, силуэт - 5), деньгам (локоть - 4, силуэт - 2) и цене (локоть - 4, силуэт - 3) силуэт предпочитает меньше групп: он награждает крупные, хорошо разделённые группы, а локоть ловит и более тонкие различия. Итоговый выбор проверяется деньгами: матрицами по сегментам на неделях, которых расчёт не видел.

3. Цена: дорогой или дешёвый товар выбирают покупатели

Сначала каждый товар получает ценовой уровень внутри своей группы сравнения: 30% самых дешёвых пачек - «дешёвые», 30% самых дорогих - «дорогие», остальные - «средние». Покупатель платит за пачку, поэтому сравнивается цена пачки, но только с пачками похожего объёма из той же подкатегории: иначе упаковка на 100 таблеток всегда казалась бы «дорогой», а на 10 - «дешёвой». Сиропы, мази и нелекарственный ассортимент сравниваются по цене упаковки внутри подкатегории.

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

Ценовые группы аптекКаждая строка - группа аптек, а не товаров: аптеки в ней похожи тем, какую долю выручки делают на дешёвом, среднем и дорогом товаре. Группы идут от самой экономичной к самой премиальной.

4. Ассортимент: на что «заточена» точка

Точка описывается долями категорий в своей выручке, независимо от размера. Индекс категории в группе показывает, во сколько раз её доля выше или ниже средней по сети. По нему группа и получает название: категории с индексом от 1,3 - это её «уклон».

Индекс категорий в ассортиментных группах1,0 - как в среднем по сети. Красный - категория продаётся заметно больше среднего, синий - меньше. В скобках - число аптек.

5. Итоговые сегменты

Каждая аптека получает три метки - группу по размеру, по ассортименту и по цене. Группы переводятся в понятные слова: размер - по шкале от «малых» до «крупных», ассортимент - в уклон («сердце и кровь», «мать и дитя, косметика» или «универсальный»), цена - от «эконома» до «премиума». Сегмент - сочетание трёх слов, например «Большие · сердце и кровь · эконом». Сочетания, в которые попало меньше 5 аптек, вливаются в самый похожий крупный сегмент. В исходном расчёте этот шаг делали вручную в Excel, здесь он полностью автоматический.

Схема сборки сегментаКоды групп (В, А, Ц) и точки (TP1003) условные, в скобках - число аптек. Выделен путь одной аптеки.
Размергруппы по выручке и чекам
В1 (32)→ Малые
В2 (63)→ Средние
В3 (105)→ Большие
В4 (34)→ Крупные
по средней выручке: шкала от «малых» до «крупных»
Ассортиментгруппы по долям категорий
А01 (43)→ простуда, опорно-двигательная
А02 (23)→ мать и дитя, косметика
А03 (18)→ косметика, БАД
А04 (16)→ антибиотики и противовирусные, сердце и кровь
А05 (75)→ универсальный
А06 (59)→ сердце и кровь
категории с индексом от 1,3, не больше двух
Ценагруппы по долям дешёвого и дорогого
Ц1 (41)→ эконом
Ц2 (56)→ медиум -
Ц3 (119)→ медиум +
Ц4 (18)→ премиум
крайние - «эконом» и «премиум», между ними «медиум -» и «медиум +»
Сегмент = размер · уклон · ценаTP1003: В3 + А06 + Ц1 = «Большие · сердце и кровь · эконом»Сочетания меньше 5 аптек вливаются в самый похожий сегмент.
СегментАптекПлощадь, м²Выручка, млн ₽Средний чек, ₽Доля дорогого
Крупные · универсальный · медиум +201746,82 96556%
Крупные · мать и дитя, косметика · медиум +131145,32 33858%
Большие · мать и дитя, косметика · медиум +101254,02 43659%
Большие · косметика, БАД · премиум18823,54 09471%
Большие · универсальный · медиум +39992,92 29654%
Средние · универсальный · медиум +14822,02 29654%
Большие · сердце и кровь · эконом31701,91 12434%
Большие · простуда, опорно-двигательная · медиум -13521,81 54650%
Средние · антибиотики и противовирусные, сердце и кровь · медиум +14301,42 32756%
Средние · простуда, опорно-двигательная · медиум -21471,31 51248%
Средние · простуда, опорно-двигательная · медиум +9381,11 61653%
Малые · сердце и кровь · эконом10380,61 47838%
Малые · сердце и кровь · медиум -22350,61 52947%

Медианы по аптекам сегмента за 4 недели; доля дорогого - средняя доля выручки в дорогом товаре подкатегории.

Какие маленькие сочетания влились в крупные сегменты (13)
СочетаниеАптекВлилось в сегмент
Большие · универсальный · медиум -1Большие · универсальный · медиум +
Малые · простуда, опорно-двигательная · медиум +1Средние · простуда, опорно-двигательная · медиум +
Средние · сердце и кровь · эконом1Большие · сердце и кровь · эконом
Малые · антибиотики и противовирусные, сердце и кровь · медиум -1Малые · сердце и кровь · медиум -
Малые · сердце и кровь · медиум +1Малые · сердце и кровь · медиум -
Малые · антибиотики и противовирусные, сердце и кровь · эконом1Малые · сердце и кровь · эконом
Малые · антибиотики и противовирусные, сердце и кровь · медиум +1Средние · антибиотики и противовирусные, сердце и кровь · медиум +
Крупные · сердце и кровь · эконом1Большие · сердце и кровь · эконом
Большие · простуда, опорно-двигательная · медиум +2Большие · простуда, опорно-двигательная · медиум -
Средние · универсальный · медиум -2Средние · универсальный · медиум +
Большие · универсальный · эконом2Большие · сердце и кровь · эконом
Средние · сердце и кровь · медиум -2Малые · сердце и кровь · медиум -
Средние · косметика, БАД · премиум4Большие · косметика, БАД · премиум

Сегменты читаются как управленческие решения. Премиальный сегмент (18 точек) с уклоном в косметику и БАД - кандидат на расширенный ассортимент лечебной косметики. Эконом-аптеки (41 точка) с уклоном в препараты для сердца и крови - на широкий выбор недорогих дженериков. Конкретный список товаров для полки каждого сегмента - ассортиментная матрица - строится в следующем проекте.

6. Проверка: нашёл ли алгоритм заложенную структуру

Такая проверка возможна только на синтетике. Генератор данных заранее назначил каждой аптеке скрытый тип - архетип (центральная, классическая, у дома, дискаунтер, премиум, в ТЦ, сельская, при поликлинике), а алгоритм его не видел. Совпадение сегментов с архетипами меряется скорректированным индексом Рэнда: доля совпадения с поправкой на случайность, где 0 - как у случайного разбиения, 1 - полное совпадение.

Итоговые сегменты0,69
Только ассортимент0,72
Только цена0,33
Только размер0,27

Ближе всего к архетипам ассортимент (0,72): тип аптеки лучше всего виден по тому, что в ней покупают. Размер и цена по отдельности совпадают с архетипами слабо (0,27 и 0,33). Итоговые сегменты (0,69) совпадают чуть хуже одного ассортимента, потому что дополнительно делят аптеки по размеру и цене. Целиком в одном сегменте оказались аптеки при поликлиниках, дискаунтеры и премиум-аптеки. Остальные архетипы алгоритм дробит по размеру и цене: аптеки в ТЦ - на 2, аптеки у дома - на 3, классические аптеки - на 2 и сельские аптеки - на 2 сегмента - для управления ассортиментом это скорее плюс.

Из каких архетипов состоит каждый сегментЧисло аптек в каждой паре «сегмент × архетип». Если строка сегмента почти целиком в одном столбце, сегмент совпал с архетипом.

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

Дальше: матрица под сегментНоутбук на GitHubГенератор данных