Управление ценовыми скидками: модели для количественного измерения эффекта на примере АЗС

в 8:24, , рубрики: Анализ и проектирование систем, Блог компании Инфосистемы Джет, машинное обучение
Управление ценовыми скидками: модели для количественного измерения эффекта на примере АЗС - 1

Мы продолжаем публиковать доклады, прозвучавшие на RAIF 2019 (Russian Artificial Intelligence Forum). На этот раз своим опытом делится Вадим Аббакумов, кандидат физико-математических наук, главный эксперт-аналитик «Газпромнефть-Альтернативное топливо». Передаем ему слово:

На форуме по системам искусственного интеллекта RAIF 2019 (организатор – «Инфосистемы Джет») мои коллеги больше говорили о прогрессе в технологиях, а я выступил с докладом о прорыве в бизнес-процессах.

Для начала – об измерении эффекта промо-акций. Мы продавали товар по одной цене, потом в течение месяца он шел со скидкой, а затем мы вернулись к старой цене. Теперь надо понять, осталась ли компания в плюсе, насколько увеличились продажи.

С одной стороны, авторы учебников утверждают, что в 60 % случаев проведение скидочных акций не приносит желаемого эффекта, такие действия убыточны. С другой стороны, объемы и частота промо-акций растут. Например, продажи кофе по скидкам составляют 69 %.

Почему так происходит? На самом деле почти ни у одной компании нет данных о том, какая акция была выгодной, а какая убыточной. Нет данных и о величине потерь. Как результат – нет инструментов управления процессом.

Мы давно знаем, как измерять эффективность промо-акций, но для огромного количества компаний это все еще остается проблемой – ко мне постоянно обращаются за консультациями: как это грамотно сделать? Поэтому я решил об этом рассказать.

Для примера возьмем нашу компанию. Вы спросите: при чем тут «Газпром-нефть»? Они бурят скважины, добывают нефть. Это правда, но далеко не вся. «Газпром-нефть» является одним из лидеров в продаже… кофе. У каждой автозаправки (а это 800 точек) свой магазин, и в каждом мы устраиваем промо-акции, пытаясь стимулировать покупки.

Сначала обсудим популярные, но неоптимальные методы.

Вариант 1. Так измеряют эффект промо-акций 80% компаний. Если скидки были в феврале, то сравниваем с февральскими продажами предыдущего года. Разница – и есть результат промо-акции. Если произошла накладка (например, в прошлом феврале тоже была какая-то акция и сравнить по этой схеме невозможно), то мы берем среднее арифметическое по продажам в январе и марте! Это вариант прекрасно просчитывается в Excel, но на самом деле не является оптимальным. Дело в том, что при этом игнорируются или изменение тренда, или же изменение сезонных составляющих.

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

Вариант 3(худший). Взять временной ряд продаж и сравнить значения в феврале предыдущего и текущего года, применив t-критерий Стьюдента. Кажется, что это и будет тот самый А/В-тест, однако полузнание хуже незнания: наблюдения временного ряда зависят друг от друга, в результате t-критерий применять нельзя.

Вариант 4 (оптимальный): Рассмотрим максимально простую схему, в которой мы имеем два ряда продаж. Красным цветом обозначены продажи без промо-акции, синим – модифицированный ряд, в котором с 4 по 6 наблюдение были скидки и, соответственно, увеличение продаж. Нам нужно измерить, насколько синяя линяя выше красной.

Управление ценовыми скидками: модели для количественного измерения эффекта на примере АЗС - 2

Построим пару обыкновенных линейных регрессионных моделей.

Для красной линии модель очевидна:

$продажи=a +bcdot t$

Для синей линии добавляем предиктор xt:

$продажи=a +bcdot t+ccdot x_{t}$

Как и для красной линии, тренд мы опишем прямой. Переменная xt равна единице в дни промо-акций и нулю в дни их отсутствия (если сохраняются продажи за каждый день). Переменная xt умножается на переменную с, которая и является показателем увеличения продаж. Если результат отрицательный, то значит продажи упали, а уменьшились они именно на с единиц. Так выглядит базовая схема.

Переменные вида xt называют индикаторами или dummy variables. Подобные переменные используются в разных ситуациях, например, в one-hot-encoding. В нашем случае xt является интервенцией, то есть событием, которое временно или навсегда меняет характер ряда.

Несмотря на то, что базовая схема очевидна, на этапе уточнения модели начинаются проблемы.

Тренд. Тренд чаще всего нелинейный, поэтому надо позаботиться, чтобы он не включал в себя подъемы и спуски, связанные с промо-акциями. И наоборот, надо позаботиться, чтобы эффект промо-акции не включал в себя подъемы и спуски, которые должны описываться трендом. Для решения этой проблемы хорошо себя проявила процедура Prophet (она же fbprophet). В ней тренд описывается кусочно-линейной функцией, отрезки гибко описывают локальный тренд.

Сезонность. У ряда может быть одна или несколько сезонных составляющих. Например, на АЗС три сезонности: внутрисуточная (ночью на автозаправке народу меньше, чем днем), внутринедельная (в пятницу на заправке больше клиентов, чем во вторник) и годовая (летом машин больше, чем зимой). При этом сезонность бывает мультипликативная или аддитивная. В продажах сезонность обычно мультипликативная.

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

Второй пример. Возможно, это чисто питерский феномен, но если на улице даже -30 оС, то люди покупают даже мороженое, а вот если пошел дождь – то покупатели пропадают. С начала до конца дождя продажи просто останавливаются, но почему так происходит – совершенно непонятно. Да и не важно, надо только в модель встроить множитель, который уменьшит продажи в те часы, когда идет дождь.

Добавлять дополнительные внешние переменные мы должны правильно и аккуратно, пользуясь здравым смыслом и пониманием бизнес-процессов. В анализе данных это называют feature ingeneering.

Модель уже имеет следующий вид:

$продажи=тренд+сезонность+сезонность+...+ccdot x_{t}+dcdot z_{t}$

где xt такой же, как раньше, а zt – вектор дополнительных предикторов. Дальнейшие улучшения включают в себя отказ от обыкновенных линейных регрессионных моделей.

Как еще можно улучшить описание промо-акции? Для той версии переменной xt, которая обсуждалась выше, имеем следующий график изменения во времени:

Управление ценовыми скидками: модели для количественного измерения эффекта на примере АЗС - 6

Если компания подняла цену не временно, а «навсегда», это будет интервенцией, влияние которой сохраняется. График будет иметь следующий вид:

Управление ценовыми скидками: модели для количественного измерения эффекта на примере АЗС - 7

Здесь продажи поднялись (а чаще – упали), и все это длится до бесконечности.

Я рекомендую следующий гибкий вариант описания интервенции:

Управление ценовыми скидками: модели для количественного измерения эффекта на примере АЗС - 8

Не слишком сложный, но и не слишком простой. Сначала идет подъем, потом эффект от акции потихонечку затухает. В этом случае начало и конец «акции» приходится подбирать вручную. Например, программисты Python обожают grid-search, с помощью которого можно определить начало и конец процесса.

Отвлечемся, чтобы обсудить пример интервенции, которая не является промо-акцией. Коллега работал в «Ленте», где перед одним из магазинов начали строить развязку. Добираться до этого супермаркета стало очень неудобно, как следствие – поток клиентов упал. Эффект этой интервенции можно измерить так, как описано выше. Необходимо оценить, сколько клиентов за все время строительства потерял магазин. Плюс к этому, когда развязку достроили, покупателям нужно было снова привыкнуть к мысли, что в этот супермаркет удобно добираться. Таким образом эффект от строительства потихонечку спал, но сохранялся в течение некоторого времени, и надо было это учитывать.

Теперь перейдем к реальному примеру оценки эффекта промо-акции. Предположим, мы продаем прохладительные напитки. На графике ниже желтым цветом обозначен размер скидки, а синим – объем продаж.

Управление ценовыми скидками: модели для количественного измерения эффекта на примере АЗС - 9

Несколько наблюдений.

В сентябре 2018 года скидка привела к увеличению продаж. Все логично – модель позволяет оценить такой рост.

В ноябре 2017-го была максимальная скидка, но она оставила продажи на прежнем низком уровне. Что остановило рост? Предполагаем влияние неучтенного фактора и аккуратно подбираем дополнительные характеристики.

В июне 2017 года небольшая скидка резко увеличила продажи. Может дело вовсе не в скидке, а летней жаре?

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

Выводы:

Иногда всё идет так, как оно должно идти, иногда наоборот.

Если модель работает, все хорошо.

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

Автор: Вадим Аббакумов, кандидат физико-математических наук, главный эксперт-аналитик «Газпром нефть».

Автор: JetHabr

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js