Учёт эффекта каннибализации в моделях прогнозирования спроса (в ритейл-сети)
Компания
SAS
Учебный семестр
Осень 2018
Учебный курс
3-й курс
Максимальное количество студентов, выбравших проект: 2-5
Содержание
Что это за проект?
Проблема обнаружения эффекта каннибализации – самая острая из открытых аналитических задач в ритейле. Понятие каннибализации появилось в 70-х годах прошлого века, и означало эффект снижения спроса на один товар в результате дополнения ассортимента другим товаром. Сегодня это название используют и для объяснения других причин, вызывающих падение продаж какого-либо товара, которыми могут являться, например, открытие в непосредственной близости конкурирующих магазинов (возможно, той же розничной сети), промо-активность по другим товарам внутри категории, ценовая политика. В нашем проекте предлагается разработать подход для учета каннибализации при прогнозировании спроса в розничной сети с помощью методов Machine Learning. Результатом проекта будет являться реализация модели прогнозирования спроса, учитывающей эффекты каннибализации, и оценка значимости разных эффектов каннибализации, в том числе на реальных данных продаж в розничной сети.
Чему научатся студенты? Что самое интересное в проекте?
Организация работы (Как студенты будут работать в команде?)
Основные моменты взаимодействия:
Компоненеты (Из каких частей состоит проект?)
Какие будут использоваться технологии?
Для реализации проекта студентам потребуется освоить ПО SAS. Будут использоваться следующие продукты:
Какие начальные требования?
Темы вводных занятий
Критерии оценки
Минимальные требования (на 4-5):
Похожие проекты
Автоматическое обнаружение взаимно каннибализируемых и взаимно дополняемых групп товаров (розничные сети)
Предлагаю обсудить тему «эффект каннибализации». Под эффектом каннибализации понимается сокращение потребления одного товара (услуги) при выходе на рынок нового товара (услуги).
На практике эффект каннибализации возникает повсеместно и, полагаю, вопрос будет актуальным для специалистов разных отраслей: пищевая промышленность, телекоммуникации, FMCG…
Основная проблема — как предвидеть эффект, как его точно оценить. Оценка эффекта каннибализации нужна, чтобы определить реальный финансовый эффект от запуска нового продукта (услуги), а также для предотвращения падения кумулятивной прибыли (суммы прибыли от старого продукта и нового продукта вместе взятых).
Обсуждение предлагаю разделить по двум направлениям:
Не знаю, правомерно ли относить 1-е направление к каннибализации, но взглянем на вопрос с такой точки зрения: если бы новый продукт (обновленный) не вышел на рынок, а старый продукт еще какое-то время продавался, можно ли считать «потерянные» (неполученные) доходы от старого продукта сканнибализированными новым продуктом. Считаю, что можно. Основным вопросом, при этом, будет: как оценить с финансовой точки зрения целесообразность замены старого продукта новым?
Что касается 2-го направления (расширение продуктовой линейки, часто называется Line extention), то здесь с точки зрения финансов каннибализация может касаться доходов (рентабельности), а также оценки стоимости бренда (марочного капитала). Каннибализация доходов (прибыли) возможна при ошибке в прогнозировании спроса на продукты компании, т.е. когда более дешевые субституты, выпущенные на рынок для закрытия отдельных ниш, начинают приобретаться вместо оригинального продукта. Каннибализация марочного бренда, скорее, вопрос все-таки более маркетинговый, но потенциально имеющий финансовую оценку.
Оптимально, когда эффект каннибализации не приводит к негативным результатам по обозначенным направлениям финансовой оценки.
По-моему, существует еще 3-е направление для обсуждения — оценка эффекта от каннибализации при капитальных вложениях в новое производство (когда новая технология или производство производит как абсолютно новые товары (услуги), так и аналоги старых товаров). Здесь принципиальным моментом будет являться оценка целесообразности капитальных затрат с учетом их размера, срока выхода на рынок, основываясь на разнице доходов от выпуска продукции (услуг) и сканнибализированных доходов по продукции (услугам), выпускаемой на предыдущем оборудовании.
Расчёт каннибализации на основе классического A/B-теста и метод bootstrap’а
В данной статье рассмотрен метод расчёта каннибализации для мобильного приложения на основе классического A/B-теста. В данном случае рассматриваются и оцениваются целевые действия в рамках процесса реаттрибуции с рекламного источника (Direct, Criteo, AdWords UAC и прочих) по сравнению с целевыми действиями в группе, на которую реклама была отключена.
В статье дан обзор классических методик сравнения независимых выборок с кратким теоретическим базисом и описанием примененных библиотек, в т.ч. вкратце описывается суть метода bootstrap’а и его реализация в библиотеке FaceBook Bootstrapped, а также проблемы, возникающие на практике при применении этих методик, и способы их решения.
Фактические данные либо обфусцированы, либо не приводятся с целью сохранения none- disclosure agreement.
В дальнейшем я планирую дополнять и немного дорабатывать эту статью по мере появления новых фактов, так что данную версию можно считать первым релизом. Буду благодарна за замечания и рецензии.
Введение
Каннибализация – процесс перетекания траффика, полного и целевого, из одного канала в другой.
Маркетологи обычно используют данный показатель как дополнительный коэффициент К при рассчёте CPA: предрассчитанный CPA домножается на 1+K. Под CPA в данном случае подразумеваются суммарные траты на привлечение траффика/количество целевых действий, монетизируемых прямо, то есть принесших фактический профит – например, целевой звонок, и/или монетизируемых косвенно – например, увеличение объема базы объявлений, рост аудитории и так далее.
Когда бесплатные каналы (например, заходы с органической выдачи SERP’ов, переходы по ссылкам на сайтах, размещение на которых для нас является бесплатным) каннибализируются платными (Direct, Adwords вместо органики, реклама в feed’ах социальных сетей вместо переходов по объявлениям, бесплатно размещенным в группах, и так далее), это несет с собой риски финансовых потерь, поэтому важно знать коэффициент каннибализации.
В нашем случае стояла задача расчёта каннибализации «органических» переходов в приложение переходами из рекламной сети Criteo. Наблюдением считается устройство или пользователь-uid (GAID/ADVID и IDFA).
Подготовка эксперимента
Можно подготовить аудиторию для эксперимента, разбив в интерфейсе аналитической системы AdJust пользователей на группы для вычленения тех, которые будут видеть рекламу из определённой рекламной сети (контрольная выборка), и тех, кому реклама не будет показываться, используя соответственно в дальнейшем GAID или ADVID и IDFA (AdJust предоставляет API Audience Builder). Далее на контрольную выборку можно включить рекламную кампанию в исследуемой в эксперименте рекламной сети.
Отмечу от себя, что, как интуитивно кажется, более грамотной в данном случае была бы следующая реализация эксперимента: выбрать четыре группы – тех, у кого был отключен retargeting со всех каналов (1), в качестве экспериментальной группы, и тех, у кого был включен только retargeting с Criteo (2); тех, у кого был отключен только retargeting с Criteo (3), тех, у кого был включен весь retargeting (4). Тогда можно было бы рассчитать (1)/(2), получив фактическое значение каннибализации рекламными кампаниями сети Criteo «органических» переходов в приложение, и (3)/(4), получив каннибализацию Criteo в «естественной» среде (ведь Criteo, очевидно, может каннибализировать и другие платные каналы). Этот же эксперимент следовало бы повторить и для других рекламных сетей, чтобы выяснить impact каждой из них; в идеальном мире хорошо бы исследовать ещё и cross-каннибализацию между всеми ключевыми платными источниками, составляющими наибольшую долю в общем траффике, но это потребовало бы столько времени (как для подготовки экспериментов с точки зрения разработки, так и для оценки результатов), что вызвало бы критику за необоснованную дотошность.
Фактически наш эксперимент осуществлялся в условиях (3) и (4), выборки были разбиты в соотношении 10% к 90%, эксперимент проводился 2 недели.
Предподготовка и верификация данных
Перед началом любого исследования важным этапом является грамотная предподготовка и очистка данных.
Следует отметить, что фактически активных устройств за период эксперимента было в 2 раза меньше (42.5% и 50% от контрольной и экспериментальной групп, соответственно), чем устройств в полных исходных выборках, что объясняется природой данных:
В нашем случае важно проверить следующие пункты:
Непосредственная оценка эксперимента
Мы будем рассматривать изменение следующих целевых метрик: абсолютной – количество звонков, и относительной — количество звонков на пользователя в контрольной (видели рекламу в сети Criteo) и экспериментальной (реклама была отключена) группах. В приводимом ниже коде под переменной data понимается структура pandas.DataFrame, которая формируется из результатов экспериментальной или контрольной выборки.
Существуют параметрические и непараметрические методики оценки статистической значимости различия значений в несвязанных выборках. Параметрические критерии оценки дают большую точность, однако имеют ограничения в своём применении – в частности, одно из основных условий – это то, что измеренные значения для наблюдений в выборке должны быть распределены нормально.
1. Исследование распределений значений в выборках на нормальность
Первый шаг – исследовать существующие выборки на вид распределения значений и равенство дисперсий выборок при помощи стандартных тестов – критериев Колмогорова-Смирнова и Шапиро-Уилкса и критерия Бартлетта, реализованных в библиотеке sklearn.stats, приняв p-value = 0.05:
Дополнительно для визуальной оценки результатов можно воспользоваться функцией построения гистограмм.
Читать гистограмму можно так: 10 раз в выборке встретилась конверсионность 0.08, 1 – 0.14. О количестве устройств как наблюдений для какого-либо из конверсионных показателей это ничего не говорит.
В нашем случае распределение значения параметра как в абсолютных значениях, так и в относительных (количество звонков на устройство) в выборках не является нормальным. В таком случае можно применить либо непараметрический критерий Вилкоксона, реализованный в стандартной библиотеке sklearn.stats, либо попробовать привести распределения значений в выборках к нормальному виду и применить один из параметрических критериев — критерий Стьюдента aka t-test или Шапиро-Уилкса.
2. Методы приведения распределения значений в выборках к нормальному виду
Одним из подходов к приведению распределения к нормальному виду является метод sub-bucket’ов. Суть его проста, а теоретическую основу составляет следующий математический тезис: согласно классической центральной предельной теореме распределение средних стремится к нормальному – сумма n независимых одинаково распределённых случайных величин имеет распределение, близкое к нормальному, и, эквивалентно, распределение выборочных средних первых n независимых одинаково распределённых случайных величин стремится к нормальному. Поэтому можно разбить существующие bucket’ы на sub-bucket’ы и, соответственно, взяв средние значения по sub-bucket’ам для каждого из bucket’ов, мы можем получить близкое к нормальному распределение:
Вариантов разбиения может быть множество, всё зависит от фантазии и нравственных устоев разработчика – можно взять честный random или использовать hash от исходного bucket’а, тем самым учтя в схеме механизм его выдачи.
Однако на практике из нескольких десятков запусков кода мы получили нормальное распределение только однажды, то есть данный метод не является ни гарантированным, ни стабильным.
Кроме того, отношение целевых действий и пользователей к общему числу действий и пользователей в sub-bucket’ах может быть не консистентно исходным backet’ам, поэтому необходимо предварительно проверить, что соотношение сохраняется.
В процессе такой проверки мы выяснили, что конверсионные соотношения для subbucket’ов относительно исходной выборки не сохраняются. Поскольку нам необходимо дополнительно гарантировать консистентность соотношения доли звонков в выходных и исходных выборках, мы применяем балансировку классов, добавив взвешенность – чтобы данные отдельно выбирались по подгруппам: отдельно из наблюдений с целевыми действиями и отдельно из наблюдений без целевых действий в нужной пропорции. Кроме того, в нашем случае выборки были разбиты неравномерно; интуитивно кажется, что среднее при этом измениться не должно, а вот как неравномерность выборок влияет на дисперсию, неочевидно из формулы дисперсии. Для того, чтобы уточнить, влияет ли разница в размерах выборок на результат, используется критерий Xi-квадрат – если выявлена статистически значимая разница, то будет произведено sample’ирование большего data-frame’а по размеру меньшего:
На выходе получаем сбалансированные по размеру и консистентные исходным по конверсионным соотношениям данные, исследуемые метрики (рассчитанные для средних значений по sub-bucket’ам) в которых уже распределены нормально, что видно как визуально, так и по результатам применения уже известных нам критериев-тестов на нормальность (при p-value >= 0.05). Например, для относительных показателей:
Теперь к средним по sub-bucket’ам можно применить t-test (таким образом, в качестве наблюдения выступает уже не device_id, не устройство, а sub-bucket).
Убедившись, что изменения являются статистически значимыми, можно с чистой совестью провести то, ради чего мы всё это затеяли – расчёт каннибализации:
В знаменателе должен быть траффик без рекламы, то есть экспериментальный.
3. Метод Bootstrap’а
Метод bootstrap’а является расширением метода sub-bucket’ов и представляет собой его более продвинутый и усовершенствованный вариант; программную реализацию этого метода на языке Python можно найти в библиотеке Facebook Bootstrapped. Кратко идею bootstrap’а можно описать следующим образом: метод представляет собой не что иное, как конструктор выборок, формируемых аналогично методики sub-bucket’ов случайным образом, но с возможными повторениями. Можно сказать, размещения из генеральной совокупности (если таковой можно назвать исходную выборку) с возвращением. На выходе формируются средние (или медианы, суммы, etc.) от средних для каждой из сформированных подвыборок.
Основные методы библиотеки FaceBook Bootstrap: – реализует механизм формирования подвыборок; по умолчанию возвращает lower bound (5 перцентиль) и upper bound (95 перцентиль); чтобы вернуть дискретное распределение в этом диапазоне, необходимо установить параметр return_distribution = True (его генерирует вспомогательная функция generate_distributions()).
Можно задать число итераций при помощи параметра num_iterations, в которых будет осуществляться формирование подвыборок, и количество подвыборок iteration_batch_size для каждой итерации. На выходе generate_distributions() будет сформирована выборка размером, равным числу итераций num_iterations, элементы которой будут представлять собой среднее от значений выборок iteration_batch_size, рассчитанных на каждой итерации. При больших объемах выборок данные могут перестать влезать в память, поэтому в таких случаях желательно уменьшать значениие iteration_batch_size.
Пример: пусть исходная выборка имеет размер 2 000 000; num_iterations = 10 000, iteration_batch_size = 300. Тогда на каждой из 10 000 итераций в памяти будет храниться 300 списков по 2 000 000 элементов.
Функция также позволяет производить параллельные вычисления на нескольких ядрах процессора, на нескольких thread’ах, устанавливая необходимое число при помощи параметра num_threads.
производит все те же действия, что и описанная выше функция bootstrap(), однако дополнительно также производится агрегация средних значений методом, указанным в stat_func – от значений num_iterations. Далее рассчитывается метрика, указанная в параметре compare_func, и производится оценка статистической значимости.
– класс функций, предоставляющий инструментарий для формирования метрик для оценки:
– класс функций, из которого выбирается способ агрегации исследуемой метрики:
В качестве stat_func можно применять и custom’ную пользовательскую функцию, например:
По сути, (test_stat — ctrl_stat)/test_stat и есть формула для расчёта нашей каннибализации.
В качестве альтернативы или с целью практичекого эксперимента можно первоначально получить распределения при помощи bootstrap(), проверить статистическую значимость различий целевых метрик при помощи t-test’а и затем применить к ним необходимые манипуляции. Пример того, насколько «качественное» нормальное распределение можно получить при помощи этого метода:
Более подробную документацию можно прочитать на странице репозитория.
На текущий момент это всё, о чём хотелось (или успелось) рассказать. Постаралась кратко, но понятно описать применяемые методики и процесс их реализации. Не исключено, что методологии требуют корректировки, поэтому буду благодарна за feedback и рецензии.
Также хочу выразить благодарность моим коллегам за помощь в подготовке данной работы. В случае, если статья получит преимущественно позитивный feedback, укажу здесь их имена или ники (по предварительному согласованию).