ML for Value / Ваня Максимов – Telegram
ML for Value / Ваня Максимов
5.59K subscribers
191 photos
1 video
1 file
119 links
Путь от ML-модели до Value для компании | RecSys, Search, LLM, Pricing и CLTV

Ваня Максимов, @Ivan_maksimov
Head of AI | Recsys, search, llm @Y.Market, ex-WB, ex-Delivery Club

Консультирую компании, Веду курсы
Публикую релевантную рекламу
Download Telegram
Как вам посты про дизайн и ускорение А/В?

P.S. А ещё: стратификация, линеаризация, байес и т д - просто частные случаи CUPED
Грабли универсальные: Тесты ds-кода

Сразу оговорюсь, что я ни разу не 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/
*На самом деле тесты вам помогут найти баги в пайплайне и даже улучшить качество модели!

Но это не точно
Все то, что я описал выше, касается картинок и текстов тоже

Нет ничего более обидного, чем когда обучил Sota сетку с огромным входным размером изображения, а на вход в проде подаёшь микро картинку (условно, 256х256) и автоматически pad-ишь ее нулями.. Всё работает, но качество - так себе
Вам понравился пост про ML-тесты?

Если интересно услышать еще больше 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
Рекомендательные системы
Часть 1
А зачем?

Новая серия постов будет посвещена классике - рекомендательныем системам в ритейле. На этот раз представьте себя на месте data scientist, который работает в крупной сети бытовой техники / мебели (IKEA, М.Видео, Hoff)

К вам приходит менеджер и предлагает сделать персональную e-mail рассылку с товарами. Но прежде чем радоваться новой челленджевой задаче, задайте ему вопрос "А зачем?"

Многие очень стесняются его задавать, думая, что выглядят глупо. Но поверьте, подавляющее большинство людей (разработчики, менеджеры, да чего уж мелочиться: data scientist-ы тоже) не знают хотя бы +/- точного ответа на этот вопрос

#recsys
Представим, что на вопрос нашего воображаемого ds менеджер ответил "Чтобы повысить продажи". Вы уже знаете, что под продажами можно понимать все что угодно

И вроде бы в голове есть картинка:
1. Рекомендуем вот этот шкаф
2. Юзеру нравится рекомендация
3. Юзер приезжает к нам (заходит в интернет-магазин) и покупает его

Но опытные DS сразу увидят подвох:
>> В нашем магазине у клиентов довольно мало покупок (вы часто покупаете холодильник или шкаф?)
>> Очень сложно угадать конкретный предмет для рекомендаций

В общем, стандартный кейс для холодного старта

Поэтому, скорее всего, вы просто не сможете нормально обучить рекомендательную систему. Что же делать?
Ну и какой конкретно шкаф вы порекомендуете юзеру, по которому нет / почти нет данных?
Давайте ещё раз зададим вопрос "А зачем? ", внимательно смотря на нашу схему:

1. Рекомендуем вот этот шкаф
2. Юзеру нравится рекомендация
3. Юзер приезжает к нам (заходит в интернет-магазин) и покупает его

Начнём с конца (3): "юзер .. покупает его". Нам точно нужно именно это? А если юзер купит не тот шкаф, что мы рекомендовали, а другой? Другой шкаф = тоже успех! Значит, нам нужно, чтобы юзер купил хоть что-то

Если нужно, чтобы он купил хоть что-то, но рекомендации хотим все ещё персональные, то мы можем рекомендовать не товар, а категорию товаров

А чтобы юзеру точно понравились рекомендации, можно дать ему небольшую скидку на категорию

И вот, наша рекомендация "шкаф такой-то", где мы очень вряд ли сможем угадать предпочтение пользователя, превратилась в "Скидка на шкафы 10%". Уже лучше, не правда ли? И нашу итоговую цель мы точно также достигаем

И получаем схему :
1. Рекомендуем вот этот шкаф категорию и скидку на нее
2. Юзеру нравится рекомендация
3. Юзер приезжает к нам (заходит в интернет-магазин) и покупает его хоть что-то

Вывод
Всегда спрашивайте, зачем вас просят что-то сделать. Очень вероятно, что вы найдёте более удачный способ добиться конечной цели
Вчера написал пост про скидки на категорию - сегодня получил аж 2 таких скидки в смс:)

У М.Видео скидки оказались весьма годными
А вот Алиэкспресс предлагает мне скидки на платья😜

В их защиту скажу, что раньше я ничего не покупал на Али - кейс экстремально холодного юзера
Рекомендательные системы
Часть 2
Если бы да кабы

Вы никогда не делали очень классную ML модель, которая оказалась бесполезной? У каждого DS есть такая история. Вроде бы и поняли, зачем делать проект, и он всем нужен, но.. 87% ML проектов не доходят до прода

Чтобы таких кейсов было как можно меньше, пишу свой чек-лист перед началом проекта. Он получился из огромного количества граблей и ошибок (моих и не только). На первый взгляд вам может показаться, что я написал прям очевидные вещи, но это не так 😅

В будущих постах я разберу подробно каждый из пунктов на примере нашей истории про рекомендации

#recsys
Чек лист перед началом ML-проекта

1. Спроси "А зачем?" перед тем, как бежать делать проект. И уточни, что хочет в итоге получить менеджер/бизнес

2. Проверь, достаточно ли:
-- данных
-- вычислительных мощностей
-- времени у ds-специалистов

3. Представь, как пошагово ты будешь решать проблему через ML. Не получается? Возможно, решения через ML не существует

4. Представь, что модель уже готова. Подумай, что ещё нужно сделать (бизнес-ограничения, катить в продакшн, получить согласования,..)

5. А в самом лучшем случае, сколько денег это нам принесёт? Сравни свою оценку доп. денег с оценкой менеджера

6. Что и где может пойти не так? Если рисков слишком много, то, может, пока и не стоит начинать?
ML for Value / Ваня Максимов pinned «Чек лист перед началом ML-проекта 1. Спроси "А зачем?" перед тем, как бежать делать проект. И уточни, что хочет в итоге получить менеджер/бизнес 2. Проверь, достаточно ли: -- данных -- вычислительных мощностей -- времени у ds-специалистов 3. Представь…»
Рекомендательные системы
Часть 2
Грабли #1: А достаточно ли данных?

На первый взгляд, ответить можно за пару минут: вспомнить, что у нас пишутся данные по онлайн и оффлайн продажам уже 2 года и все, но.. Нет

1. Есть ли привязка юзера к покупке?

Данные по продажам, может и записываются. Но вопрос в том, пишется ли в каком-то виде id-шник юзера в заказе

В ритейле это, как правило, либо логин (~онлайн id) для онлайн покупок, либо id карты лояльности для оффлайн. Обидно будет, если только у 3% юзеров есть такие id-шники

2. Есть ли данные по скидкам?

Мы ведь хотим давать персональные скидки в рекомендациях. Будет непросто это сделать без данных о том, когда, на какой товар и какая скидка была

В моей практике далеко не у всех компаний были такие данные. Были кейсы, когда историю промо вели понедельно в csv..

Если вдруг данных нет, то можно попробовать восстановить размер скидки из истории цен. Например, сравнивать цену товара в неделю week_t со средней ценой товара за week_{t-3} - week_{t-1}. Но на это вам стоит заложить сразу +2-3 недели: в таких алгоритмах много подводных камней

3. А e-mail-ы то есть?

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

Если вдруг email-ов нет, то можно:
- Рассылать рекомендации ещё и через смс (вдруг телефоны есть)
- Делать push up уведомления в приложении / на сайте
- Печатать персональные скидки на чеке (так делает ритейлеры Виктория, Перекрёсток)
- Начать бесплатно раздавать карты лояльности с регистрацией через e-mail / cмс. Так со временем мы получим привязку юзера к заказу
- Стимулировать онлайн-покупки. Например, М.Видео даёт скидку в 3% на любую покупку онлайн. Это происходит в том числе, чтобы потом направить всю мощь персонализации на юзера
👍2
Рекомендательные системы
Часть 2
Грабли #2: А как это будет выглядеть? 🙈 vs 😍

Юзеру все равно, используете ли вы под капотом набор эвристик или SOTA. Ему важно, чтобы продукт:
-- Выполнял его базовую потребность (купить новый холодильник да подешевле)
-- Был визуально приятен
-- Был удобен

Ваша моделька прямиком с KDD2020 будет бесполезной, если у рекомендуемого товара нет фото, описания или цены

Идеальный loss и метрики не помогут, если вы будете писать название товара также как в базе данных (СТИРАЛ.МАШ. BOSH 13К сер.17)

Никто не купит больше товаров, если не откроет письмо из-за его неудачного заголовка

Если вы будете рекомендовать пакеты / подарочные упаковки и прочие очень популярные, но далеко не ключевые товары в вашем магазине (а все мы помним, что recsys зачастую имеют bias в сторону популярных товаров), то ваши бизнес-оунер и юзеры не будут рады

Не ждите отклика на e-mail рассылки, если вы забыли про часовые пояса в России и разослали всем письма в 20:00 по Мск.. или в 2 ночи по Хабаровскому времени

Вывод
Перед началом проекта представьте, как будет выглядеть финальный ML-продукт. А лучше разошлите 5 писем с вручную составленными рекомендациями своим коллегам. И запросите их фидбек. Узнаете много интересного:)

Делайте ML-продукты, а не ML-модели