Оптимизация промо акций
Часть 4
Как померить бизнес-эффект? 💰💰
- Очевидно, А/В тестом!
- Да, но не все так просто. Опять мои любимые implementation details:)
Грабли #1: Выбор корректного теста
Классические А/В из учебников применяются не так часто, т.к. столкновение теории с реальностью разбивает первую вдребезги
Что же не так с А/В из учебника? Вспомним, что там пишут:
Шаг 1. Разбиваем юзеров на А и В группы.. Но стоп. Мы же делаем акции на товары в магазине, как же мы побьем юзеров? Правильно - никак. Нужно сплитить магазины
Шаг 2. Провести А/А тест. Обычно в лекциях это упоминается вскользь. Предполагают, что А/А тест всегда успешен. Но в кейсе со сплитом по магазинам зачастую это не так 🙅♀ Хьюстон, у нас проблемы
Причин может быть 2:
>> Магазинов мало (даже у Х5 и Магнита их ~20к по всей России) + А/В на полстраны вам запустить никто не даст. В итоге, дай бог, дадут 1-2к магазинов для теста
>> Магазины очень сильно отличаются (разные города, районы города, уровень зп,...)
Что же делать?
1. Можно стратифицированно сэмплировать магазины для А и В групп. Не рекомендую, т к очень сложно подобрать хорошие фичи, по которым вы будете стратифицировать (город? з/п? Население? Все сразу?)
2. Switch back тесты. Рекомендую.
Хорошая статья от DoorDash на эту тему:
https://www.google.com/amp/s/doordash.engineering/2019/02/20/experiment-rigor-for-switchback-experiment-analysis/amp/
TL;DR;
Раз в неделю (в идеале день, но у нас оффлайн ритейл) вы делаете сплитование заново. Если тест идёт 3 недели, то один и тот же магазин может на одной неделе быть в А группе, а на другой - в В. Это позволяет нивелировать различия между средними в А и В группах, и даже снизить дисперсию метрик (ускорить тест)
Вывод
Внимательно следите за тем, какую технику А/В вы используете
#pricing #timeseries
Часть 4
Как померить бизнес-эффект? 💰💰
- Очевидно, А/В тестом!
- Да, но не все так просто. Опять мои любимые implementation details:)
Грабли #1: Выбор корректного теста
Классические А/В из учебников применяются не так часто, т.к. столкновение теории с реальностью разбивает первую вдребезги
Что же не так с А/В из учебника? Вспомним, что там пишут:
Шаг 1. Разбиваем юзеров на А и В группы.. Но стоп. Мы же делаем акции на товары в магазине, как же мы побьем юзеров? Правильно - никак. Нужно сплитить магазины
Шаг 2. Провести А/А тест. Обычно в лекциях это упоминается вскользь. Предполагают, что А/А тест всегда успешен. Но в кейсе со сплитом по магазинам зачастую это не так 🙅♀ Хьюстон, у нас проблемы
Причин может быть 2:
>> Магазинов мало (даже у Х5 и Магнита их ~20к по всей России) + А/В на полстраны вам запустить никто не даст. В итоге, дай бог, дадут 1-2к магазинов для теста
>> Магазины очень сильно отличаются (разные города, районы города, уровень зп,...)
Что же делать?
1. Можно стратифицированно сэмплировать магазины для А и В групп. Не рекомендую, т к очень сложно подобрать хорошие фичи, по которым вы будете стратифицировать (город? з/п? Население? Все сразу?)
2. Switch back тесты. Рекомендую.
Хорошая статья от DoorDash на эту тему:
https://www.google.com/amp/s/doordash.engineering/2019/02/20/experiment-rigor-for-switchback-experiment-analysis/amp/
TL;DR;
Раз в неделю (в идеале день, но у нас оффлайн ритейл) вы делаете сплитование заново. Если тест идёт 3 недели, то один и тот же магазин может на одной неделе быть в А группе, а на другой - в В. Это позволяет нивелировать различия между средними в А и В группах, и даже снизить дисперсию метрик (ускорить тест)
Вывод
Внимательно следите за тем, какую технику А/В вы используете
#pricing #timeseries
👌1
Грабли #2: А/В тест длиною в жизнь
Допустим, мы выбрали относительно хороший дизайн А/В:
-- Метрика - прибыль на 1 магазин за 1 день
-- Switch back тест
-- Нам разрешили взять максимум 2к магазинов в тестовую группу
Всё, запускаем? Вообще, нужно бы посчитать, сколько недель нам нужно держать А/В. Считаем и получаем.. 2 года 😱
И тут мы приходим к необходимости ускорить А/В тест. Ускорить А/В = снизить дисперсию вашей метрики. Я оставлю ссылки на варианты решения этой проблемы и напишу TL; DR
Допустим, мы выбрали относительно хороший дизайн А/В:
-- Метрика - прибыль на 1 магазин за 1 день
-- Switch back тест
-- Нам разрешили взять максимум 2к магазинов в тестовую группу
Всё, запускаем? Вообще, нужно бы посчитать, сколько недель нам нужно держать А/В. Считаем и получаем.. 2 года 😱
И тут мы приходим к необходимости ускорить А/В тест. Ускорить А/В = снизить дисперсию вашей метрики. Я оставлю ссылки на варианты решения этой проблемы и напишу TL; DR
Ускорение А/В
Способ 1. Стратификация и CUPED
https://youtu.be/pZpUM08mv-E
Стратификация = Сначала посчитать средние в каждой группе (город/страна/сегмент юзеров по доходу/..), а потом взвещенно по кол-во наблюдений в группе усреднить
Тогда итоговое среднее останется таким же как и в классическом подходе, а дисперсия упадёт - - > тест нужно будет держать меньше
CUPED
В видео объяснение довольно сложное, но по сути вы просто строите линейную регрессию вашей целевой метрики на фичи
Важно (!): значение фичей должно быть известно ДО начала эксперимента
Пример фичей:
-- Целевая метрика магазина N недель назад
-- Город, в котором находится магазин
--...
Потом, вы из целевой метрики вычитание её прогноз. И считаете А/В на уже получившейся величине. Это сильно ускоряет тест, но снижает его интерпретируемость
P.S. Для любителей строгой мат.статистики - выше я описал лишь концепцию. Если вдаваться в детали, то текст выше в чем-то не совсем корректен. Но суть идеи передаёт отлично:)
Способ 1. Стратификация и CUPED
https://youtu.be/pZpUM08mv-E
Стратификация = Сначала посчитать средние в каждой группе (город/страна/сегмент юзеров по доходу/..), а потом взвещенно по кол-во наблюдений в группе усреднить
Тогда итоговое среднее останется таким же как и в классическом подходе, а дисперсия упадёт - - > тест нужно будет держать меньше
CUPED
В видео объяснение довольно сложное, но по сути вы просто строите линейную регрессию вашей целевой метрики на фичи
Важно (!): значение фичей должно быть известно ДО начала эксперимента
Пример фичей:
-- Целевая метрика магазина N недель назад
-- Город, в котором находится магазин
--...
Потом, вы из целевой метрики вычитание её прогноз. И считаете А/В на уже получившейся величине. Это сильно ускоряет тест, но снижает его интерпретируемость
P.S. Для любителей строгой мат.статистики - выше я описал лишь концепцию. Если вдаваться в детали, то текст выше в чем-то не совсем корректен. Но суть идеи передаёт отлично:)
YouTube
002. Увеличение чувствительности в A/B с помощью Cuped — Валерий Бабушкин
Доклад с совместного митапа Expfest x Яндекс.Практикум. Про эксперименты
❤1
Ускорение А/В
Способ 2. Выбрать другую метрику 😅
Да-да, вы не ослышались. Можно и иногда даже нужно выбирать другие метрики в А/В, чтобы ждать результатов не 2 года, а 2-3 недели
Прибыль = кол-во заказов * средняя прибыль с одного заказа
Невероятно, но факт (ну, почти всегда факт 😜): дисперсия этих множителей сильно меньше дисперсии прибыли
А значит, А/В успешен, если
хотя бы одна из метрик растёт, а другая - не падает
P.S. Но не забывайте про поправки (например, Бонферонни) для множественного тестирования гипотез
Способ 2. Выбрать другую метрику 😅
Да-да, вы не ослышались. Можно и иногда даже нужно выбирать другие метрики в А/В, чтобы ждать результатов не 2 года, а 2-3 недели
Прибыль = кол-во заказов * средняя прибыль с одного заказа
Невероятно, но факт (ну, почти всегда факт 😜): дисперсия этих множителей сильно меньше дисперсии прибыли
А значит, А/В успешен, если
хотя бы одна из метрик растёт, а другая - не падает
P.S. Но не забывайте про поправки (например, Бонферонни) для множественного тестирования гипотез
Ускорение А/В
Способ 3: Байесовская статистика
https://youtu.be/Wxw1lseUXVU
(про Байеса - в конце видео)
Одно из немногих успешних применений байеса - А/В тесты и многорукие бандиты
Тут TL;DR не получится, так как много теории. Если интересно, то лучше прочитайте об этом в годных статьях:
Байесовские А/В:
https://link.medium.com/9b4ukKvHK9
Байесовские многорукие бандиты:
https://lilianweng.github.io/lil-log/2018/01/23/the-multi-armed-bandit-problem-and-its-solutions.html
Способ 3: Байесовская статистика
https://youtu.be/Wxw1lseUXVU
(про Байеса - в конце видео)
Одно из немногих успешних применений байеса - А/В тесты и многорукие бандиты
Тут TL;DR не получится, так как много теории. Если интересно, то лучше прочитайте об этом в годных статьях:
Байесовские А/В:
https://link.medium.com/9b4ukKvHK9
Байесовские многорукие бандиты:
https://lilianweng.github.io/lil-log/2018/01/23/the-multi-armed-bandit-problem-and-its-solutions.html
YouTube
Как мы ускорили А/Б тесты в Яндекс Советнике в 10/100 раз – Нерсес Багиян
Перед нами встала задача ускорить А/Б тесты в сто раз и мы вышли за пределы дозволенного. Линеаризация, перевзвешивание, машинное обучение и даже Баес во славу А/Б.
Секция A/B testing
Moscow Data Science Major 31.08.2019
https://datafest.ru/major/
Презентации…
Секция A/B testing
Moscow Data Science Major 31.08.2019
https://datafest.ru/major/
Презентации…
Как вам посты про дизайн и ускорение А/В?
P.S. А ещё: стратификация, линеаризация, байес и т д - просто частные случаи CUPED
P.S. А ещё: стратификация, линеаризация, байес и т д - просто частные случаи CUPED
Грабли универсальные: Тесты ds-кода
Сразу оговорюсь, что я ни разу не ML Engineer / Devops. Бакалавриат я закончил вообще по мат.методам в экономике. И до начала работы почти ничего не слышал о юнит- и других тестах
Но как только мои модели начали использоваться, даже мне стало очевидно, что без тестов - никуда. Без них пайплайны падают, их починка отнимает кучу времени, а бизнес-заказчики недоумевают где их 300кк/сек от внедрения ML
А если ваши пайплайны падают слишком часто - не за горами тот момент, когда и вы будете недоумевать про свои 300кк/сек 🙂
Так что начнем мое небольшое введение в тестирование ML-пайплайнов!
ML-тесты очень специфичны. В продакшене каждый день мы обучаемся на немного разных данных. При этом даже на одних и тех же inputs можно получать разные outputs. Мы в общем случае не знаем, какой должен быть ответ на одном или другом примере
Поэтому я предлагаю покрывать отдельными тестами:
— входные данные (да-да, и для нейронок тоже)
— каждый этап трансформации данных
— predict
В моем идеальном мире, код может выглядеть примерно так:
Далее опишу тесты, которые яиспользую каждый день стараюсь использовать. А чтобы убедить вас, что тесты нужны, добавлю мои самые эпичные фейлы
Сразу оговорюсь, что я ни разу не ML Engineer / Devops. Бакалавриат я закончил вообще по мат.методам в экономике. И до начала работы почти ничего не слышал о юнит- и других тестах
Но как только мои модели начали использоваться, даже мне стало очевидно, что без тестов - никуда. Без них пайплайны падают, их починка отнимает кучу времени, а бизнес-заказчики недоумевают где их 300кк/сек от внедрения ML
А если ваши пайплайны падают слишком часто - не за горами тот момент, когда и вы будете недоумевать про свои 300кк/сек 🙂
Так что начнем мое небольшое введение в тестирование ML-пайплайнов!
ML-тесты очень специфичны. В продакшене каждый день мы обучаемся на немного разных данных. При этом даже на одних и тех же inputs можно получать разные outputs. Мы в общем случае не знаем, какой должен быть ответ на одном или другом примере
Поэтому я предлагаю покрывать отдельными тестами:
— входные данные (да-да, и для нейронок тоже)
— каждый этап трансформации данных
— predict
В моем идеальном мире, код может выглядеть примерно так:
df = read_data()
test_on_inputs(df)
df = first_transform(df)
test_on_transform(type='first')
df = second_transform(df)
test_on_transform(type='second')
model = MyFavoriteModel()
model.fit(df)
test_on_predict(model, df)Далее опишу тесты, которые я
На мой взгляд 90% ошибок - в самых элементарных вещах. Перепутали типы данных, сделали left join вместо inner и т.п. И если вы думаете, что это происходит "с любым, но точно не со мной" - скорее всего вы заблуждаетесь:) Для таких кейсов представляю вам:
Капитанский набор тестов для DS
.. и мои эпичнейшие фейлы:
1. Проверка типов входных данных
Прочитать pandas dataframe без указания типов данных и получить out of memory error - это уже стало классикой
2. Проверка кол-во строк в датафрейме
Вы обучили модель и она показала 99% AUC? Запускаете регулярный джоб на обучение и вдруг видите совершенно неадекватные предсказания и AUC около 50%? Поздравляю, еще одна классика: джоб автоматически обучил вашу SOTA модель на не собранной до конца базе (например, там оказалось 10к строк вместо 10кк)
3. Проверяйте долю NaN-ов и уникальных значений в каждом столбце
Я однажды сджойнил датафрейм с поминутными событиями и датафрейм "дата-праздник". Угадайте, для каких минут были не NaN-ы (для ХХ-ХХ-ХХ:00:00). Поэтому мои юзеры праздновали не только НГ исключительно 1 минуту в полночь, но и все остальные праздники
4. Проверяйте распределение фичей
- min/max значения (особенно актуально для дат)
- Среднее
Я встречал отрицательные цены, возраст в 5000+ лет, отрицательный прогноз продаж (хотя в трейне только положительные продажи, но бустингу все равно), даты после сегодняшнего дня в трейне и еще много артефактов. И да, замечаете вы их далеко не сразу. В свою защиту скажу, что и появляются такие артефакты тоже не всегда сразу
5. Тесты на логику
- Статистики по категориям (условно через df.groupby(store_id)['item_id'].nunique() посчитать, что в каждом магазине > 1000 товаров
- Продажи любого товара не больше 10к шт в день
Если в ваш магазин заехал оптовик и закупил 5 Камазов картошки по акции, то это легко сломает вам все модели
6. Тесты на логику predict
Вы же ожидаете, что прогноз продаж вырастет, если увеличить скидку на товар? Так напишите на это тест
Кстати, почти все эти тесты можно очень удобно закодить с помощью достаточно новой либы great-expectations:
https://docs.greatexpectations.io/en/latest/
Капитанский набор тестов для DS
.. и мои эпичнейшие фейлы:
1. Проверка типов входных данных
Прочитать pandas dataframe без указания типов данных и получить out of memory error - это уже стало классикой
2. Проверка кол-во строк в датафрейме
Вы обучили модель и она показала 99% AUC? Запускаете регулярный джоб на обучение и вдруг видите совершенно неадекватные предсказания и AUC около 50%? Поздравляю, еще одна классика: джоб автоматически обучил вашу SOTA модель на не собранной до конца базе (например, там оказалось 10к строк вместо 10кк)
3. Проверяйте долю NaN-ов и уникальных значений в каждом столбце
Я однажды сджойнил датафрейм с поминутными событиями и датафрейм "дата-праздник". Угадайте, для каких минут были не NaN-ы (для ХХ-ХХ-ХХ:00:00). Поэтому мои юзеры праздновали не только НГ исключительно 1 минуту в полночь, но и все остальные праздники
4. Проверяйте распределение фичей
- min/max значения (особенно актуально для дат)
- Среднее
Я встречал отрицательные цены, возраст в 5000+ лет, отрицательный прогноз продаж (хотя в трейне только положительные продажи, но бустингу все равно), даты после сегодняшнего дня в трейне и еще много артефактов. И да, замечаете вы их далеко не сразу. В свою защиту скажу, что и появляются такие артефакты тоже не всегда сразу
5. Тесты на логику
- Статистики по категориям (условно через df.groupby(store_id)['item_id'].nunique() посчитать, что в каждом магазине > 1000 товаров
- Продажи любого товара не больше 10к шт в день
Если в ваш магазин заехал оптовик и закупил 5 Камазов картошки по акции, то это легко сломает вам все модели
6. Тесты на логику predict
Вы же ожидаете, что прогноз продаж вырастет, если увеличить скидку на товар? Так напишите на это тест
Кстати, почти все эти тесты можно очень удобно закодить с помощью достаточно новой либы great-expectations:
https://docs.greatexpectations.io/en/latest/
Все то, что я описал выше, касается картинок и текстов тоже
Нет ничего более обидного, чем когда обучил Sota сетку с огромным входным размером изображения, а на вход в проде подаёшь микро картинку (условно, 256х256) и автоматически pad-ишь ее нулями.. Всё работает, но качество - так себе
Нет ничего более обидного, чем когда обучил Sota сетку с огромным входным размером изображения, а на вход в проде подаёшь микро картинку (условно, 256х256) и автоматически pad-ишь ее нулями.. Всё работает, но качество - так себе
Вам понравился пост про ML-тесты?
Если интересно услышать еще больше true sad stories про фейлы из-за отсутствия тестов (или рассказать свою историю) - добро пожаловать в комментарии
Если интересно услышать еще больше true sad stories про фейлы из-за отсутствия тестов (или рассказать свою историю) - добро пожаловать в комментарии
Рекомендательные системы
Всё, чему нас учили - неправда
Следующая серия постов будет посвящена получению Business Value от рекомендательных систем (RecSys). А пока поделюсь с вами довольно значимым научным открытием в 2020 году:
Оказалось, что некорректно использовать наши любимые NDCG, precision@k, recall@k для сравнения моделей, если эти метрики посчитаны на сэмпле данных. Вместо этого корректно использовать AUC@k 😱
А сэмплирование используется почти во всех продакшн-системах, так как товаров сотни тысяч, а то и миллионы (метрики считают обычно на сэмпле из 100-1000 товаров)
Видео с KDD-2020 на эту тему (всего 15 мин)
Для тех, кто не очень близок к сфере recsys: в 99% курсах на первом же уроке говорят, что использовать AUC для оценки качества ранжирования нельзя, т.к он плохо учитывает порядок рекомендаций
На очень годных курсах добавляют, что AUC@k чуть получше, но тоже не айс 🥶
И настоятельно советуют использовать те самые NDCG, precision@k, ...
Вот так и переворачиваются в момент все представления о задаче ранжирования
P.S. Сколько же раз, получается, я выбирал модель на основе некорректных метрик..
#recsys
Всё, чему нас учили - неправда
Следующая серия постов будет посвящена получению Business Value от рекомендательных систем (RecSys). А пока поделюсь с вами довольно значимым научным открытием в 2020 году:
Оказалось, что некорректно использовать наши любимые NDCG, precision@k, recall@k для сравнения моделей, если эти метрики посчитаны на сэмпле данных. Вместо этого корректно использовать AUC@k 😱
А сэмплирование используется почти во всех продакшн-системах, так как товаров сотни тысяч, а то и миллионы (метрики считают обычно на сэмпле из 100-1000 товаров)
Видео с KDD-2020 на эту тему (всего 15 мин)
Для тех, кто не очень близок к сфере recsys: в 99% курсах на первом же уроке говорят, что использовать AUC для оценки качества ранжирования нельзя, т.к он плохо учитывает порядок рекомендаций
На очень годных курсах добавляют, что AUC@k чуть получше, но тоже не айс 🥶
И настоятельно советуют использовать те самые NDCG, precision@k, ...
Вот так и переворачиваются в момент все представления о задаче ранжирования
P.S. Сколько же раз, получается, я выбирал модель на основе некорректных метрик..
#recsys
Рекомендательные системы
Часть 1
А зачем?
Новая серия постов будет посвещена классике - рекомендательныем системам в ритейле. На этот раз представьте себя на месте data scientist, который работает в крупной сети бытовой техники / мебели (IKEA, М.Видео, Hoff)
К вам приходит менеджер и предлагает сделать персональную e-mail рассылку с товарами. Но прежде чем радоваться новой челленджевой задаче, задайте ему вопрос "А зачем?"
Многие очень стесняются его задавать, думая, что выглядят глупо. Но поверьте, подавляющее большинство людей (разработчики, менеджеры, да чего уж мелочиться: data scientist-ы тоже) не знают хотя бы +/- точного ответа на этот вопрос
#recsys
Часть 1
А зачем?
Новая серия постов будет посвещена классике - рекомендательныем системам в ритейле. На этот раз представьте себя на месте data scientist, который работает в крупной сети бытовой техники / мебели (IKEA, М.Видео, Hoff)
К вам приходит менеджер и предлагает сделать персональную e-mail рассылку с товарами. Но прежде чем радоваться новой челленджевой задаче, задайте ему вопрос "А зачем?"
Многие очень стесняются его задавать, думая, что выглядят глупо. Но поверьте, подавляющее большинство людей (разработчики, менеджеры, да чего уж мелочиться: data scientist-ы тоже) не знают хотя бы +/- точного ответа на этот вопрос
#recsys
Представим, что на вопрос нашего воображаемого ds менеджер ответил "Чтобы повысить продажи". Вы уже знаете, что под продажами можно понимать все что угодно
И вроде бы в голове есть картинка:
1. Рекомендуем вот этот шкаф
2. Юзеру нравится рекомендация
3. Юзер приезжает к нам (заходит в интернет-магазин) и покупает его
Но опытные DS сразу увидят подвох:
>> В нашем магазине у клиентов довольно мало покупок (вы часто покупаете холодильник или шкаф?)
>> Очень сложно угадать конкретный предмет для рекомендаций
В общем, стандартный кейс для холодного старта
Поэтому, скорее всего, вы просто не сможете нормально обучить рекомендательную систему. Что же делать?
И вроде бы в голове есть картинка:
1. Рекомендуем вот этот шкаф
2. Юзеру нравится рекомендация
3. Юзер приезжает к нам (заходит в интернет-магазин) и покупает его
Но опытные DS сразу увидят подвох:
>> В нашем магазине у клиентов довольно мало покупок (вы часто покупаете холодильник или шкаф?)
>> Очень сложно угадать конкретный предмет для рекомендаций
В общем, стандартный кейс для холодного старта
Поэтому, скорее всего, вы просто не сможете нормально обучить рекомендательную систему. Что же делать?
Telegram
ML for Value / Ваня Максимов
Оптимизация промо-акций.
Часть 1
Зачем понимать ДО начала проекта, что хочет бизнес 💼
Представьте, что вы работаете DS-ом в крупном ритейлере (условно, Дикси/Пятерочка). К вам приходит менеджер и предлагает оптимизировать промо-акции с помощью ML, выбирая…
Часть 1
Зачем понимать ДО начала проекта, что хочет бизнес 💼
Представьте, что вы работаете DS-ом в крупном ритейлере (условно, Дикси/Пятерочка). К вам приходит менеджер и предлагает оптимизировать промо-акции с помощью ML, выбирая…
Давайте ещё раз зададим вопрос "А зачем? ", внимательно смотря на нашу схему:
1. Рекомендуем вот этот шкаф
2. Юзеру нравится рекомендация
3. Юзер приезжает к нам (заходит в интернет-магазин) и покупает его
Начнём с конца (3): "юзер .. покупает его". Нам точно нужно именно это? А если юзер купит не тот шкаф, что мы рекомендовали, а другой? Другой шкаф = тоже успех! Значит, нам нужно, чтобы юзер купил хоть что-то
Если нужно, чтобы он купил хоть что-то, но рекомендации хотим все ещё персональные, то мы можем рекомендовать не товар, а категорию товаров
А чтобы юзеру точно понравились рекомендации, можно дать ему небольшую скидку на категорию
И вот, наша рекомендация "шкаф такой-то", где мы очень вряд ли сможем угадать предпочтение пользователя, превратилась в "Скидка на шкафы 10%". Уже лучше, не правда ли? И нашу итоговую цель мы точно также достигаем
И получаем схему :
1. Рекомендуемвот этот шкаф категорию и скидку на нее
2. Юзеру нравится рекомендация
3. Юзер приезжает к нам (заходит в интернет-магазин) и покупаетего хоть что-то
Вывод
Всегда спрашивайте, зачем вас просят что-то сделать. Очень вероятно, что вы найдёте более удачный способ добиться конечной цели
1. Рекомендуем вот этот шкаф
2. Юзеру нравится рекомендация
3. Юзер приезжает к нам (заходит в интернет-магазин) и покупает его
Начнём с конца (3): "юзер .. покупает его". Нам точно нужно именно это? А если юзер купит не тот шкаф, что мы рекомендовали, а другой? Другой шкаф = тоже успех! Значит, нам нужно, чтобы юзер купил хоть что-то
Если нужно, чтобы он купил хоть что-то, но рекомендации хотим все ещё персональные, то мы можем рекомендовать не товар, а категорию товаров
А чтобы юзеру точно понравились рекомендации, можно дать ему небольшую скидку на категорию
И вот, наша рекомендация "шкаф такой-то", где мы очень вряд ли сможем угадать предпочтение пользователя, превратилась в "Скидка на шкафы 10%". Уже лучше, не правда ли? И нашу итоговую цель мы точно также достигаем
И получаем схему :
1. Рекомендуем
2. Юзеру нравится рекомендация
3. Юзер приезжает к нам (заходит в интернет-магазин) и покупает
Вывод
Всегда спрашивайте, зачем вас просят что-то сделать. Очень вероятно, что вы найдёте более удачный способ добиться конечной цели