DS с завода
766 subscribers
24 photos
5 files
37 links
Про аналитику, DS и ML простыми словами.
Download Telegram
Channel created
Всем привет!
Меня зовут Стас Носуленко, я Staff Data Scientist в BP в Лондоне.

После 4 лет работы в стратегическом консалтинге я огляделся вокруг и понял, что вместо еженедельных командировок на металлургические заводы можно с умным видом копировать код из stackoverflow, попивая смузи в уютном офисе. Так я перешел в аналитику.

С тех пор успел поработать в разных компаниях, научился кодить, проводить A/B-тесты, строить модели, работать с облаками, выстраивать процессы и управлять командой.

В отличие от классического аналитика, получившего относительно релевантные знания от терпеливых преподавателей в вузе, мне пришлось набивать необходимое количество шишек собственноручно. Ну а дальше осталось только убедить себя, что кому-то будет интересно про эти шишки почитать.
5🔥1
Здесь я буду делиться вещами которые кажутся мне неочевидными (или казались таковыми когда-то):
- Расти в Data Science и аналитике
- Руководить командой
- Создавать себе задачи и находить решения
- И при этом не забывать получать удовольствие от жизни

Контент будет разный:
1. Мои личные мысли — то, что вряд ли встретите где-то ещё.
2. Сложно нагуглить — темы, которые требуют глубокого контекста или не имеют «правильного» ответа.
3. Легко нагуглить, но… — материал, который почему-то редко встречается в моей выборке коллег и кандидатов на собеседованиях.

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

Добро пожаловать!
👍4
Оглавление
#ABtesting - A/B тесты и как их готовить
#Marketing - маркетинговая аналитика и МММ
[Сообщение про запас]
[Сообщение про запас]
innovators_AB.pdf
1.1 MB
Вчера выступал в Innovators Guild, рассказывал про A/B тесты, зачем они нужны и как их готовить.
Планирую чуть позже выложить весь рассказ здесь в виде серии постов, а пока что вот презентация.
#ABtesting
6
Что такое A/B тест и зачем он нужен
A/B-тест — это способ проверить, какая из двух версий продукта (или его элемента) работает лучше, показывая их разным людям и сравнивая результаты.

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

1️⃣ Просто взять и раскатить, без всей этой дурацкой аналитики.
Плюсы - быстро, дешево и сердито
Минусы - не понимаем, заработали мы денег или потеряли, улучшили пользовательский опыт или ухудшили.

2️⃣ Замерить ключевые метрики до раскатки и после. Если метрики упали - откатить обратно, иначе - оставить новинку.
Плюсы - появляется надежда, что мы оставляем только "хорошие" изменения, которые растят нужные нам метрики.
Минусы - у нас нет возможности отделить эффект от нашего воздействия от миллиона параллельных внешних факторов. Например, запустили мы новую рекомендательную модель начиная с первого сентября и увидели подскок в продажах школьных товаров. Мы решим, что это модель помогла, хотя на самом деле все объясняется простой сезональностью.
Есть способы немного улучшить этот подход с помощью более точных форкастов и методов вроде синтетического контроля - об этом будет отдельный пост.

3️⃣ Показать части пользователей старый вариант продукта, а части - новый.
Плюсы - мы "очищаем" эффект от влияния внешних факторов (1 сентября наступает одновременно у обеих групп) и получаем возможность объективно замерить эффект именно нашего воздействия
Минусы - помимо необходимости ресурсов и разработчиков, в некоторых случаях A/B тест провести просто невозможно. Например, если мы хотим замерить эффект от рекламы на федеральном канале - вряд ли мы сможем показать ее только половине зрителей, еще и выбранных случайно.
#ABtesting
Таким образом, три задачи A/B теста:
Ответить на вопрос «А изменилось ли что-то?» и оценить величину эффекта

🧹Очистить эффект от внешних факторов - сезональности, рыночных шоков, действий конкурентов и множества других вещей, которые мы никогда не сможем предугадать

🤖 Насколько возможно снизить влияние человеческого фактора на процесс принятия решения (мы перекрашиваем конпку из серого в зеленый не потому что считаем, что это красиво, а потому что видим, что это растит конверсию)

При этом оценивать мы можем практически что угодно:
- Дизайн кнопки в корзине
- Алгоритм поиска в приложении
- Расположение товаров на стеллажах в магазине
- Размер скидочного купона в СМС рассылке
Главное - чтобы была возможность разбить пользователей на две группы и сравнить по ним метрики.
#ABtesting
24
Есть три сущности, понимание которых является основой для понимания всех концепции A/B тестирования.

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

Предположим, что в группе А мы видим конверсию 4.0%, а в группе B - 4.1%.
Значит ли это что вариант B объективно лучше? Как будто бы нет. А если конверсия в группе B 4.2%? 4.5%? 5%? 10%? Задача теста - помочь нам найти ту отсечку, где различие становится статистически значимым.

Чаще всего в A/B тестировании используются 2 подхода:
1️⃣ T-test - ищет разницу в средних между группами. Самый привычный тест, который при наличии достаточно больших выборок почти всегда можно применять, если задача - сравнить именно их средние, нет слишком большого количества выбросов.

2️⃣ Bootstrap - позволяет оценивать примерно любую метрику, которую захотим (среднее, медиану, квантиль, ...). В этой статье от Х5 хорошо описано, как и зачем его применять - рекомендую к прочтению. Бутстрап снимает многие головные боли, позволяя меньше волноваться о выбросах, ненормальности распределений, невозможности оценить интересующую нас метрику и т.д.
Минус бутстрапа - требуемые для его реализации вычислительные мощности. Внутри алгоритма бустстрапа происходит многократное сэмплирование наблюдений из оцениваемой выборки, что занимает время и вычислительные ресурсы. Если это не проблема - как правило имеет смысл применять его.

Другие тесты, которые часто упоминаются упоминаются в литературе - Манна-Уитни, Колмогорова-Смирнова - тяжелее в интерпретации и объяснению бизнесу. Рекомендую посмотреть вот это видео от karpov.courses чтобы составить представление, имеют ли они смысл в ваших задачах.
#ABtesting
3🔥31
Вторая сущность — это понятие ошибок I и II рода.

Ни один статистический тест не бывает прав в 100% случаев. Ошибиться он может двумя способами:

🔹 Ошибка I рода (α) — тест показывает, что эффект есть, хотя на самом деле его нет. Например, мы решили, что перекрас баннера поднял конверсию, но разница, которую видим, оказалась просто шумом. Обычно вероятность ошибки I рода (α) фиксируют на уровне 5%.

🔹 Ошибка II рода (β) — тест показывает, что эффекта нет, хотя на самом деле он есть. В отличие от α, β напрямую зависит от размера эффекта (маленький эффект больше шансов не заметить). При планировании экспериментов обычно выбирают такой размер групп, чтобы мощность теста (1-β) при заданном минимальном детектируемом эффекте (MDE) была хотя бы 80%, что соответствует β ≈ 20%.
#ABtesting
3
Наконец, третья сущность — MDE (Minimum Detectable Effect).

MDE — это минимальный эффект, который тест способен «заметить» при заданных вероятностях ошибок I и II рода. Если ожидаемый эффект меньше MDE, стоит ещё на этапе планирования пересмотреть конфигурацию теста — например, увеличить длительность или долю пользователей.

Чем меньше MDE — тем лучше: мы снижаем риск «пропустить» эффект. Но достичь маленького MDE сложнее: для этого нужно больше данных или более «чистая» метрика.

Если мы хотим оценить разницу средних между двумя группами, MDE нашего теста будет зависить от нескольких факторов:

1️⃣ Выбранные уровни ошибок I и II рода. Чем строже мы задаём α и β, тем больше нужна выборка, а значит, при фиксированном её размере MDE будет выше.

2️⃣ Дисперсия метрики. Чем выше разброс значений, тем сложнее отловить маленький эффект. Например, если все пользователи тратят около 100 ₽, заметить рост в 1 ₽ проще, чем в ситуации, где кто-то тратит 100 ₽, кто-то 10, а кто-то 10 000.
Повлиять на дисперсию можно двумя способами:
- выбирать метрику с низким разбросом
- использовать методы снижения дисперсии (стратификацию, CUPED и др.). Про это будет отдельный пост.

3️⃣ Размер выборки. MDE обратно пропорционален √n: чем больше наблюдений, тем меньший эффект мы способны обнаружить. Зачастую самый простой способ отловить маленький эффект - увеличить длительность теста или долю пользователей в нем.
#ABtesting
5
Если связать все три сущности в единую историю, то получается примерно вот так:

Когда мы проводим A/B тест, мы разделяем аудиторию на две группы и показываем им два варианта нашего продукта, замеряя важные для нас метрики (пусть для примера будет конверсия в покупку). Мы считаем наше изменение успешным, если конверсия в группе с внедренным изменением (группа B ) выше, чем в контрольной группе со старой версией продукта (группа A).

Конверсия между двумя группами всегда будет хотя бы немного различаться. Чтобы понять, действительно ли разница вызвана нашим изменением, а не случайным шумом - мы используем статистический тест 🧪.

При этом мы не забываем, что стат тест 🧪 может ошибаться - вероятность либо найти ложный эффект, либо пропустить существующий называются вероятностями ошибок I/II рода ⚠️ соответственно.

Если мы знаем, какой стат тест 🧪 собираемся использовать для измерения наших метрик, и на каком уровне мы хотим удержать вероятности ошибок I/II рода ⚠️ - мы можем оценить минимальный детектируемый эффект (MDE 🎯), в зависимости от выбранного размера аудитории.

Если MDE 🎯 оказывается слишком большим (то есть, мы считаем, что настоящий эффект от нашего изменения меньше, чем тот, который мы сможем отловить), нам придется либо добавлять в тест пользователей, либо каким-то образом снижать дисперсию отслеживаемой метрики.
#ABtesting
3🔥2
Сегодня мы отдыхаем от A/B тестирования и вместо этого немного поговорим про не менее животрепещущую тему - маркетинговую аналитику

После запуска канала я "проинвестировал" в два маркетинговых канала (маркетинговый канал = платформа, на которой мы продвигаем свой продукт, в данном случае - телеграм канал. Примеры - реклама в VK, пост на других ТГ-каналах, телевидение, реклама на фасадах зданий):
1. Стори в моем профиле в телеграме
2. Пост в моем профиле в линкедине

Через несколько дней настало время подвести итоги - на приложенной картинке можно увидеть:
- Сколько людей подписалось на канал в день публикации (t0) и последующие дни, перейдя по каждой из двух ссылок
- Сколько людей просмотрело каждый из двух постов (views) и какой был в итоге Conversion Rate (подписки / показы)

Несколько вещей, которые из этих данных можно увидеть:
1️⃣ Сравнение конверсии
Если смотреть только на CR - линкедин выглядит достаточно грустно (понадобилось в 7 раз больше показов чтобы привести то же число людей). Если бы я платил за каждый показ (одна из схем оплаты на многих площадках), то подписчики из линка мне обходились бы дороже.

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

2️⃣ Отложенный эффект
После первого дня стори уже почти не приносит подписчиков (что логично, все, кому надо - уже их просмотрели), а вот линк даже на третий день продолжает бодриться и приносить подписки (видимо, часть пользователей заходит на платформу не каждый день и впервые увидят мой пост в своей ленте через сутки-двое после его публикации). В итоге на горизонте 3х дней оба маркетинговых канала принесли примерно одинаковое число подписок (а через пару дней авось линк и опередит телегу).

То, насколько значимым в конкретном маркетинговом канале является "отложенный" эффект (продажи/подписчики, пришедшие к нам через какой-то период после инвестиций в канал) описывается термином Adstock - чем он выше, тем дольше нам нужно будет ждать полной отдачи от инвестиций.

Adstock очень важно учитывать при сравнении ROI (return on investment) каналов - например, в большом бизнесе реклама на ТВ может начать приносить эффект только через дни или недели после запуска, в то время как эффект от рекламы на площадках Яндекса или Гугла будет практически мгновенным.

3️⃣ "Выгорание" маркетингового канала
Другая важная характеристика маркетингового канала, которую по одному посту увидеть пока что нельзя - эффект насыщения (saturation).

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

Через недельку выложу еще по одному посту в каждом из каналов - посмотрим, где у нас эффект насыщения наступит позже!
#Marketing
9
Обнаружилось, что по хэштегу AB выскакивают объявления китайского эскорта. Поскольку это немного не бьется с тематикой канала, пришлось обновить теги у всех постов.
🆒3
Новые посты пока что не пишутся по абсолютно зависящим от меня причинам, так что пока что вот вам наглядное сравнение флеш- и про- версий Gemini.

Вопрос: как мне пить из чашки если у нее нет дна и заварен верх?

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

Ссылки на чаты (можно раскрыть и почитать ризонинг)
Flash
Pro
😁5
На этой неделе много работал с агентами в Claude Code, и так впечатлился результатом, что решил сдуть пыль с этого блога (ну и еще @bogdanisssimo настаивает, что нельзя такое в себе держать).

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

Осложняется все это кучей корпоративных ограничений - например, чтобы запустить один пайплайн на препроде, нужно прогнать два CI/CD пайплайна на ADO, затем кликнуть на кнопочку в кастомной системе мониторинга (предварительно указав правильные параметры, взятые из предыдущих прогонов), дождаться ближайшего окна запуска на AWS и уже там смотреть на результат. В общем, сложно и больно это все.

Весь процесс был собран в пятистраничную инструкцию и передан в Claude Code с Опусом 4.5, вместе с задачей сделать агентскую систему, полностью снимающую груз с хрупких плеч кожаных мешков.

После доработок и нескольких итераций пришли к следующей мультиагентской структуре:

👮‍♂️ Координатор, раздающий задачи и отвечающий за верхнеуровневый процесс
🕵️‍♂️ Сыщик, ищущий релевантные файлы для заданного пайплайна и выстраивающий схему зависимостей
👨‍💻 Аналитик, формулирующий бизнес-логику пайплайна
👨‍🏫 Эксперт, имеющий доступ к документации по улучшению спарк-пайплайнов и предлагающий улучшения
👨‍⚕️ Хирург (название сам Клод выбрал), внедряющий изменения в код
💂‍♀️ Страж, делающий ревью
👨‍🔬 Тестировщик, прогоняющий пайплайн в препрод окружении и замеряющий эффект  

Для повторяющихся задач написали скиллы и sh/py скрипты, чтобы снизить объем самодеятельности агентов.
Дополнительно для каждого прогона создается структурированный md-файл, в котором агенты оставляют друг другу заметки и отчет обо всем, что они сделали. Ну и отдельная секция с проблемами (например, задачи, для выполнения которых не было доступного стандартного скилла).

Работает все это, мягко говоря, впечатляюще - несколько часов смотреть на работающего агента ничуть не менее залипательно, чем на работающего человека. Вчера без единого вмешательства с моей стороны был переписан и оттестирован первый небольшой пайплайн - обещается 30% улучшение, ждем подтверждение от дата-инженеров и будем пробовать масштабировать.
1👍7🔥54
DS с завода
На этой неделе много работал с агентами в Claude Code, и так впечатлился результатом, что решил сдуть пыль с этого блога (ну и еще @bogdanisssimo настаивает, что нельзя такое в себе держать). Задача такая: есть океан из плохо оптимизированных дата-пайплайнов…
Как у меня выглядит процесс сборки всего этого мультиагентского табора:

1️⃣ Формулируем верхнеуровневую задачу и передаем ее любой нормальной ЛЛМке (Claude, GPT, Gemini - не так важно), вместе со ссылкой на эту страницу с документацией. Дальше либо предлагаем свой вариант перечня субагентов, либо генерим его с нуля вместе с ЛЛМкой. Для каждого из субагентов просим составить 1-2 абзаца описания.

2️⃣ Описания передаем в интерфейс создания агентов Claude Code - он нам сгенерит под каждого агента по .md файлу в стандартном формате. Заодно указываем, какие инструменты доступны каждому субагенту - например, для изучения архитектуры кодовой базы можно ограничиться Read-only инструментами.

3️⃣ Добавляем отдельные файлы с точечными знаниями (для тех агентов, которым они требуются). Например, для Спарк-эксперта можно составить отдельный файл с наиболее часто встречающимися антипаттернами и способами их исправления.

4️⃣ Генерим CLAUDE.md - это основная точка входа для нашего агента, с описанием всего процесса, информацией о субагентах и моментах, когда их нужно вызывать.

5️⃣ Добавляем в CLAUDE.md указание вести на каждом прогоне отдельный файл с заметками (для него лучше сразу подготовить темплейт). В этом файле нужна отдельная секция Issues. В нее агентам сказать логгировать моменты, когда они почему-то начали ходить по кругу, их запросы к API выдавали ошибки, не получилось найти нужный файл в хранилище и т.д. Также туда говорим заносить все случаи, когда агент писал кастомный код (те же запросы к апишкам или небольшие py-скрипты).

6️⃣ Отлаживаем субагентов одного за другим - прогоняем их, смотрим на результат, редактируем промпт. Задача - чтобы максимальный % случаев, где они сами пишут какой-то код, были вынесены в SKILL.md файлы - это поможет и агентам меньше времени тратить, и нам меньше сомневаться в командах, которые они выполняют.

7️⃣ Делаем уже то же самое на уровне верхнеуровневого агента - проверяем работу на задаче end-to-end

8️⃣ Смотрим на магию и трепещем 🥰

Я стараюсь не давать файлам с инструкциями разрастаться больше, чем на ~300 строк.
Если выходит больше - либо дробить на субагентов, либо выделять инструкции в отдельные скиллы. Это помогает предотвратить разрастание контекста - ведь когда субагент выполняет выданную ему задачку, он возвращает не весь свой мыслительный процесс, а только выжимку и результат.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17🤣2
Ну и отдельное удовольствие доставляет чтение пометок, который Claude генерит своим субагентам.
Например, для "хирурга":
You are the Surgeon. Precision is your art. Preservation is your oath. Execute with discipline.

Или для стража:
You are the last line of defense. Be vigilant, be precise, be helpful.

Ощущение, что не трутней-работяг отправляешь в коде копаться, а собираешь пачку на сражение с драконом
🔥13😁92