XYZ-анализ закупок по вариативности
ABC отвечает, сколько денег уходит на категорию. XYZ отвечает, насколько ровно эти деньги уходят: одинаковая сумма каждый месяц или один пик и десять месяцев тишины. Для закупщика разница практическая. Ровный спрос позволяет держать рамочный договор и торговаться объёмом. Рваный — требует запаса, срочных закупок и запаса по цене.
Меру разброса берут относительную: среднеквадратичное отклонение делят на среднее. Это коэффициент вариации, CV. Он безразмерный, поэтому категории с разными суммами можно сравнивать между собой.
Та же purchases, но счёт идёт не по категориям, а по парам «категория —
месяц». Сначала сворачиваем заказы в месячные суммы, потом считаем разброс
этих сумм. Такой двухшаговый расчёт — обычная схема: сначала агрегат нужного
уровня, затем статистика по нему.
В датасете у каждой категории ровно 24 месяца с заказами. В живых данных бывает иначе: пустой месяц — это не пропуск, а ноль затрат, и он тоже входит в расчёт, иначе разброс занижается.
WITH m AS ( SELECT category, strftime(order_date, '%Y-%m') AS mon, sum(amount) AS spend FROM purchases GROUP BY category, mon),stat AS ( SELECT category, count(*) AS months, avg(spend) AS avg_spend, stddev_samp(spend) AS sd FROM m GROUP BY category)SELECT category AS "категория", months AS "месяцев", round(avg_spend / 1000, 1) AS "средний, тыс. ₽", round(100 * sd / avg_spend, 1) AS "CV, %", CASE WHEN sd / avg_spend < 0.10 THEN 'X' WHEN sd / avg_spend <= 0.25 THEN 'Y' ELSE 'Z' END AS "класс"FROM statORDER BY sd / avg_spend;┌─────────────────┬─────────┬─────────────────┬───────┬───────┐│ категория │ месяцев │ средний, тыс. ₽ │ CV, % │ класс │├─────────────────┼─────────┼─────────────────┼───────┼───────┤│ Металлопрокат │ 24 │ 5416.6 │ 5.5 │ X ││ Крепёж │ 24 │ 480.9 │ 5.6 │ X ││ Химия и ГСМ │ 24 │ 380.4 │ 6.2 │ X ││ Упаковка │ 24 │ 361.4 │ 8.9 │ X ││ Электрика │ 24 │ 1287.8 │ 18.1 │ Y ││ ИТ-оборудование │ 24 │ 2186.1 │ 21.4 │ Y ││ Логистика │ 24 │ 840.9 │ 39.7 │ Z ││ Спецодежда │ 24 │ 531.5 │ 60.0 │ Z ││ Канцелярия │ 24 │ 94.2 │ 65.0 │ Z │└─────────────────┴─────────┴─────────────────┴───────┴───────┘Четыре категории попали в X: Металлопрокат, Крепёж, Химия и ГСМ, Упаковка. Их месячные затраты отклоняются от среднего на 5,5–8,9% — это ровный поток, для которого работают годовые договоры и плановые цены.
Две категории в Y: Электрика (18,1%) и ИТ-оборудование (21,4%). Здесь уже видна сезонность: месячные затраты уходят вверх к концу года и остаются высокими в январе.
Три категории в Z. Канцелярия — 65,0%: пик в июле-августе, к новому учебному году, и провал в феврале. Спецодежда — 60,0%: закупки к отопительному сезону. Логистика — 39,7%: декабрьский пик отправок. Для таких категорий бессмысленно считать «средний месячный расход»: он не описывает ни один реальный месяц.
Обратите внимание на пару Металлопрокат — Канцелярия: 130,0 млн ₽ против 2,3 млн ₽ за два года, но по стабильности это разные полюса. ABC поставил бы их в разные классы по деньгам, XYZ — по ритму, и решения нужны оба.
Сезонный профиль
Заголовок раздела «Сезонный профиль»Цифра CV говорит, что разброс есть, но не говорит, какой он формы. Форму видно на месячном ряду. Для Канцелярии за 2024 год:
SELECT strftime(order_date, '%Y-%m') AS "месяц", round(sum(amount) / 1000) AS "канцелярия, тыс. ₽"FROM purchasesWHERE category = 'Канцелярия' AND order_date < DATE '2025-01-01'GROUP BY 1 ORDER BY 1;┌─────────┬────────────────────┐│ месяц │ канцелярия, тыс. ₽ │├─────────┼────────────────────┤│ 2024-01 │ 21.0 ││ 2024-02 │ 9.0 ││ 2024-03 │ 22.0 ││ 2024-04 │ 53.0 ││ 2024-05 │ 94.0 ││ 2024-06 │ 137.0 ││ 2024-07 │ 177.0 ││ 2024-08 │ 173.0 ││ 2024-09 │ 165.0 ││ 2024-10 │ 135.0 ││ 2024-11 │ 90.0 ││ 2024-12 │ 51.0 │└─────────┴────────────────────┘Максимум — июль и август (177 и 173 тыс. ₽), минимум — февраль (9 тыс. ₽). Разница почти в двадцать раз. Это не случайный разброс, а календарь: если планировать закупку канцелярии на февраль по «среднему», денег не хватит в августе.
Границы X, Y, Z
Заголовок раздела «Границы X, Y, Z»Границы 10% и 25% — рабочая договорённость, а не закон. Сдвиньте их, и те же данные дадут другие классы: часть категорий переедет из X в Y или из Y в Z. Поэтому правило простое: границы фиксируют до расчёта и пишут в описании отчёта. Иначе спор о том, «правильно ли категория попала в Z», превращается в спор о порогах.
Второе: CV считается по выборке (stddev_samp), а не по генеральной
совокупности. Для 24 месяцев разница между ними около 2% — не критично,
но в отчёте должно быть указано, что именно считали.
Типичные ошибки
Заголовок раздела «Типичные ошибки»| Ошибка | Что происходит | Как правильно |
|---|---|---|
| Считать CV по суммам заказов, а не по месяцам | Разброс отражает размер заказов, а не регулярность спроса | Сначала свернуть в месячные суммы, потом считать разброс |
| Выбрасывать месяцы без заказов | Разброс падает, сезонная категория выглядит стабильной | Пустой месяц — это ноль, он входит в ряд |
| Сравнивать CV в рублях между категориями | У крупной категории абсолютный разброс всегда больше | Сравнивать относительную величину — сам коэффициент |
| Считать «средний месячный расход» для категории Z | Число не описывает ни один месяц | Для Z планируют по пику и по календарю |
| Менять границы после расчёта | Категория «переезжает» в удобный класс | Границы фиксируются до расчёта |
Что читать дальше
Заголовок раздела «Что читать дальше»- ABC-анализ по сумме закупок — первая координата
- Концентрация поставщиков — следующая ось
- ABC и XYZ анализ закупок — матрица 3×3 и стратегии