PPC для сверхразумов | Александр Хитро – Telegram
(3/4) Вы теряете 20–50% трафика по самым частотным ключам в Директе.

Предыдущие части:
Часть 1.
Часть 2.

Зафиксируем ещё один важный термин.

Словоформы с учётом стоп-слов — фразы, отличающиеся разными стоп-словами или их отсутствием, а не просто другими склонениями и порядком одних и тех же слов в строке.


💓 Скрин 1 — отличие ТОЛЬКО в словоформах и порядке слов, но слова в строке — те же.

Словоформы с учётом стоп-слов — в предыдущем посте на последнем скрине в самом последнем столбце.

Для консолидации ("схлопывания" в одну строчку) статистики всех неявных дублей с другими словоформами и порядком слов автоматически по каждой лемме со стоп-словами комбайн вычисляет одну самую частотную словоформу с учётом стоп-слов.

Делается это в несколько сортировок показателей и вертикальных сопоставлений по массиву лемм фраз с предлогами и без, чтобы найти:

1️⃣ Самую частотную форму маски без предлогов — столбец "ВЧ_Формы_Лемм_БезСтоп".

2️⃣ Самую частотную форму каждой леммы с предлогами — столбец "ВЧ_Формы_Лемм_СоСтоп".

Чтобы не искажать данные статистики в сторону первой словоформы с учётом стоп-слов, вычисляем в Power BI по всему датасету столбец, в котором по каждой лемме без учёта стоп-слов и порядка слов выводим не просто подсчёт числа уникальных словоформ (от 1 до 10 и более), а всего два значения:

«1» — если у леммы без стоп-слов только одна словоформа с учётом стоп-слов.
«2+» — если словоформ с учётом стоп-слов две и более.

💓 Скрин 2 — подсчёт форм с группировкой до двух значений: «1» или «2+» — для юзабилити отчёта, так удобнее переключаться в 1 клик для фильтрации лемм, у которых словоформ более одной.

Здесь уже виден масштаб проблемы — если в РК Яндекс Директа собрать неправильные словоформы с учётом стоп-слов, которые являются не самыми частотными вариациями написания каждой маски фразы, можно лишиться 53% трафика и 58% конверсий.

Этот столбец применяем:
— Как критерий фильтрации в слайсере (интерактивном фильтре).
— Как критерий группировки в сводной таблице.

💓 Скрин 3 — вся целевая семантика без фильтров. Просто для сравнения.

💓 Скрин 4 — фильтруем значение «2+» в столбце "N Форм".

Получаем, что в среднем по всей семантике у масок фраз (лемм без стоп-слов и порядка слов) с двумя и более словоформами на вторую и более словоформы с учётом стоп-слов пришлось 27% охвата.

Будем сравнивать эту цифру с отдельными отфильтрованными сегментами на следующих скриншотах.

Доля охвата второй и более словоформы с учётом стоп-слов по отдельным сегментам:

💓 С главными словами (скрин 5) — 29% охвата (субъект, над которым совершается действие — "мусор, отходы, утиль").

💓 С действиями (скрин 6) — 29% охвата (в этой b2b нише вывоза мусора это слова "вывоз, вывезти, утилизировать, утилизация" и прочие синонимы).

💓 С подкатегориями (скрин 7) — 29% охвата (разные качественные характеристики).

💓 С цифрами (скрин 8) — 18% охвата (масса, размеры и т.д.).

💓 С топонимами (скрин 9) — 29% охвата.

💓 С горячими добавками (скрин 10) — 24% охвата.

💓 С брендом — 0,14% охвата.

Важно:

Проблема не в 29% охвата по каждому сегменту, а в том, что у конкретных масок фраз распределение охвата по словоформам со стоп-словами иногда 50/50, а иногда и вовсе 99/1.

То есть взяли только одну или не самую частотную форму с учётом стоп-слов — и порезали по отдельным маскам фраз вплоть до 99% охвата.


Решение:

В [квадратные] [скобки] в РК брать из каждой маски фразы более одной частотных словоформ с учётом стоп-слов:
⚡️ Топ-2 — это уже 98–99% целевого охвата в среднем по семантике.
⚡️ Топ-3 — 99–100% охвата.

В первом посте на скрине в самых частотных фразах ниши прекрасный пример. У второй по частотности формы от 20–30% до 40–55% охвата маски фразы.

⬇️ В следующем посте — скриншоты с итогами и ответы на вопросы.

via @ppc_bigbrain
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍3💊3😁21🤣1🆒1
(4/4) Вы теряете 20–50% трафика по самым частотным ключам в Директе.

Предыдущие части:
Часть 1.
Часть 2.
Часть 3.

Вопрос из чата:

А как это доказать, что есть потеря трафика?


Оцифровать самые частотные словоформы поисковых запросов и сравнить с ключами. То, что не попало в систематическую ошибку выжившего по всему аккаунту — это именно то, что потеряно.

То есть:

1️⃣ Взять фразы со стоп-словами (например, "купить окна В москве").

2️⃣ Удалить из них все стоп-слова, лемматизировать, развернуть слова в строке от А до Я.

3️⃣ Получить леммы фраз без стоп-слов ("купить москва окно"), которые нужно найти в леммах поисковых запросов, тоже развернутых от А до Я в строке.

4️⃣ Если такие поисковые запросы без стоп-слов найдены — проверить, по каким ключевым фразам они показывались, есть ли там стоп-слова, какие и в каком месте фразы.

5️⃣ Если не найдены — вы получили ответ на вопрос, как доказать потерю трафика.

Если в ключах каждое слово в [квадратных] [скобках], то независимо от того, закреплено ли стоп-слово в квадратных скобках, его не будет в поисковом запросе. Это уже потеря трафика априори.

Вопрос из чата:

В чем разница между всеми словоформами и [одним] [ключом] без стоп-слов?


Разница в том, что:

1️⃣ Я тяну разные ключи из группы в разные статические заголовки комбинаторного объявления.

2️⃣ Я тяну их #шаблоном# в один или несколько заголовков, при этом если из фразы удалить предлоги, получится нечитабельная херня, за которую ещё и по голове от клиента получишь.

3️⃣ Нецелевых стоп-слов во много раз больше, чем целевых. Обычно их соотношение от 10 к 1 вплоть до 20 к 1, т.е. целевых стоп-слов в 10–20 раз меньше, чем нецелевых. Поэтому идея выгребать все существующие запросы — заведомо провал.

4️⃣ Есть бесчисленное количество кейсов, когда только с определённым предлогом фраза является целевой, обычно это явление наблюдается в категориях и подкатегориях. Прекрасные примеры — предлоги "для", "без", "с", которые полностью могут поменять суть фразы.

5️⃣ Смена сути фразы требует другой URL. Вы не посадите трафик с разных поисковых запросов с разными стоп-словами, меняющими смысл запроса, на разные урлы на сайте, используя один ключевик [тумба] [раковина], из которого удалены все стоп-слова.

Есть множество вариаций запросов с этими двумя словами, перечислю по памяти только некоторые из них:

тумба с раковиной
тумба без раковины
тумба под раковину
раковина с тумбой
раковина без тумбы
раковина под тумбу
раковина на тумбе
тумба и раковина


Можете проверить — они все частотные. В действительности этих вариаций ещё больше.

Попробуйте посадить эти поисковые запросы по ключу [тумба] [раковина] на разные урлы в разных разделах сайта.

Использование [одного] [ключевика] без стоп-слов якобы для выгребания всех возможных вариантов стоп-слов — лишь ленивая полумера и работа на похер.

На скринах выше — данные о том, сколько в среднем может приходиться охвата на словоформы с учётом стоп-слов с первым, вторым, третьим и более индексами по убыванию охвата.

Пищу для размышлений я вам дал.

Сколько словоформ фраз с учётом стоп-слов использовать в [квадратных] [скобках] — решать вам.


————

У меня в комбайне вся эта обработка автоматизирована и в Power BI, и в Excel, результаты грузятся в модель данных и выводятся в готовые сводные таблицы и фильтры.

Для изучения любой семантики таблицу с индексами и количеством словоформ можно отфильтровать:

1️⃣ Любыми стандартными атрибутами из рекламного кабинета, в т.ч. любой группировкой дат.

2️⃣ Любым из ~200 автосоздаваемых столбцов:

— Сегментами целевой семантики.
— Их обнаружением (наличием в строке).
— Их извлечением (точными значениями в строке).
— Подсчётом слов в них (насколько фразы "широкие").
— Очищенными урлами без параметров и utm-меток.
— Частями урлов, обрезанными до нужного уровня вложенности.

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

Обнови запрос.


Объём данных, набор и названия полей, исходный язык и количество языков значения не имеют.

via @ppc_bigbrain
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
46👍2🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
🎅 Не итоги года, а предсказания

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

Эксперты Яндекс Рекламы, маркетологи и инфлюенсеры — объединили всех, чтобы поздравить вас с новым годом.

Всё просто:

➡️ включайте видео
➡️ ставьте на паузу
➡️ то, на чём остановилось — ваше предсказание на 2026 год


🩵 Делитесь в комментариях, что вам выпало
Please open Telegram to view this post
VIEW IN TELEGRAM
39👍4🔥4🤣1
Digital Awards 2025

«Хейтер» года 2025 - Александр Хитро!

С перевесом в один голос (видимо, комбайн обрел сознание и решил помочь Создателю), поздравляем с попаданием в новый топ директологов!
3😁206🔥6
Digital Awards 2025

«Душнила» года 2025 - Александр Хитро!

Ещё одна победа в этом году, заряжающая на победу в сражении с африканскими львами в следующем году. Поздравляем!
4😁235🔥4
Коллеги, кто?

via @ppc_bigbrain
😁27😍2🔥1💩1
Создавать идеальные для автотаргетинга объявления ещё никогда не было проще.

Апдейт комбайна, который изменит жизнь каждого, кто запускает Директ.

Для самых ленивых сверхразумов.


Автообработка семантики теперь ещё и из Букварикса со всеми присущими ему особенностями.

Правила и регулярки для обработки 250+ названий единиц измерений и их сокращений.

Их извлечение из слов и фраз:

— Во всех словоформах.
— В любом порядке слов.

Автозамена ~5000 новых слов и фраз на единые написания.

Новая логика автогруппировки синонимов.

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

Это позволяет:

— Не дробить синонимы на разные кластеры.
— Корректно приоритизировать сегменты.

Самое интересное:

⬇️⬇️⬇️

Автосоздание загрузочного файла РК одновременно:

— На поиск ЯД.
— В РСЯ.
— И с ключами.
— И без ключей на чистом автотаргетинге.

(Вау, Хитро не дрочит на семантику? Это вообще законно?)


⬆️⬆️⬆️

В каждой группе:

— 3 разных комбинаторных объявления.
— 21 разный заголовок.

😮 Сверхразумы спросят:

«21? Но как?»

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

(А чё, так можно было?)


Для чего это нужно:

🔣 Заголовки максимально наполнены наиболее важными и частотными словами, формирующими вектор интересов (интент).

🔣 В каждой группе набор таких слов в заголовках относится только к данному смысловому кластеру.

🔣 Исключено дублирование слов в заголовке.

Что это значит:

10+ лет назад на "курсах" по контексту "учили" протягивать в Excel по всей семантике одну универсальную добавку в конце заголовка.

Это приводило к нечитабельной ерунде и дублированию слов в заголовках:

купить кроссовки купить
суши москва москва
цены на ремонт окон цена

Комбайн вместо бездумной сцепки берёт действительные фразы из семантики.


🔣 И берёт их:

— В самых частотных по показателям формулировках.
— С корректным порядком слов.
— В корректных словоформах.

Пример:

В группе — широкие категорийные фразы:

окна пвх
окна из пвх
пластиковые окна
окна из пластика


Т.е. «Предмет + Материал».

Если эти фразы бездумно передать в заголовки, получатся короткие обрубки, ничем не полезные:
— Ни пользователям.
— Ни автотаргетингу.
— Ни рекламодателю.

И, казалось бы, сиди вручную добавляй в заголовки "купить", "москва" и т.д.

Решение:

В том же категорийном кластере «Предмет + Материал» ищем в других группах наиболее полные и полезные фразы с наличием:

— Геодобавки.
— Нескольких самых частотных в данном кластере комбинаций горячих добавок.

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

В 21 заголовке — по одной фразе из каждого кластера наиболее полных и частотных комбинаций добавок.

То есть:

С проверкой длины строки вместо одинаковых добавок во все заголовки:

"купить" + "москва"

подставляем действительные фразы из других схожих групп с сохранением порядка слов и падежей:

купить пластиковые окна в москве с установкой цена

В заголовки группы передаём до 21 разной фразы из данного смыслового кластера.


🔣 Учтена пользовательская библиотека добавок в начало и конец заголовков до максимальной длины строки.

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

🔣 Редактировать заголовки вручную не нужно.

🔣 Даже если редкие заголовки получатся неудачными (т.к. они собираются всё-таки из ключей или поисковых запросов, где иногда рандомный порядок слов), число вынужденных редактирований сведено к минимуму.

🔣 Вычитываем и полируем остатки вручную или нейронкой.

🔣 В 1 клик собираем в 21 или 63 разных заголовка ровно то, что нужно автотаргетингу, для более точного нацеливания на нужную вам ЦА.

🔣 Скармливаем Крипте Яндекса в заголовках, которыми она нацеливается на ЦА, «самые жирные» векторы интересов, чтобы она автотаргетингом и на поиске, и в РСЯ сопоставила их с такими же векторами интересов ЦА.

via @ppc_bigbrain
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍13🔥7😁62🤔1💩1
Хочешь вайбкодить — учись технические промпты писать.

Заметили, что нейронки хуже стали справляться с вашими задачами? Тогда эта серия постов для вас.

Особенно полезным это станет для вайбкодеров. Спустя тысячи попыток и миллиарды инсультов у меня наконец стало получаться, но не всегда, писать промпты так, чтобы получать правильно и быстро работающий код.

Наткнулся на интересное видео, которое стало для меня триггером к написанию серии из 10+ постов о том, в чём я провёл последний год как одержимый — в разработке комбайна по автоматизации огромного количества задач в контекстной рекламе.

Но здесь не будет саморекламы — только прожитая боль. Возможно, кто-то увидит в этом себя. Возможно, кому-то это спасёт кучу времени, денег и нервов.

Свои время, деньги и нервы мне уже не вернуть. Попробую спасти хотя бы ваши.

Этот пост — ознакомительный. Дальше — практика.

▶️ Смотреть видео на Youtube

О чём видео (на английском, включаем RU субтитры, переводим статьи):

— Что в нейросетях и промптах изменилось за 2025.
— Что в промптах уже не работает и бесполезно.
— Исследования на эту тему.
— Что только вредит результату.
— Что действительно полезно.
— Как изменить свои промпты.
— Детальность vs. явность.
— Как получать ожидаемый результат.

Исследования, документация от Anthropic и OpenAI:

1️⃣ Исследование Уортонской школы бизнеса «Я заплачу тебе или убью тебя — но тебе будет все равно?» (2025)
— Эмоциональные призывы не работают. Никаких существенных улучшений.

2️⃣ Руководство по подсказкам OpenAI GPT-4.1
— Существующие подсказки могут не сработать сразу. Неявные правила больше не выводятся. ИИ теперь буквально следует инструкциям.
— Лучше всего работают инструкции в начале И в конце (метод «сэндвича»).
— Использование ЗАГЛАВНЫХ БУКВ приводит к избыточному вниманию.
— Подсказки ролей больше не заполняют спецификации поведения.

Google с последним не согласен и в документации к Gemini советует указывать роль, например:
"Ты — Senior BI разработчик".

3️⃣ Рекомендации по использованию Anthropic Claude 4
— Клиентам может потребоваться более явно запрашивать действия, которые раньше выполнялись автоматически.
— Предполагаемые форматы. Модели больше не определяют формат вывода.
— Для получения поведения, превосходящего ожидания, характерного для предыдущих моделей Claude, может потребоваться более явно запрашивать это поведение.

4️⃣ 4 лучших практики Anthropic Claude
— Слово «Предложить» интерпретируется буквально.
— Агрессивные подсказки инструмента приводят к чрезмерному срабатыванию.

5️⃣ «О худшей производительности подсказок больших языковых моделей» (NeurIPS 2024)
— Разница в 45% между худшей и лучшей подсказкой для одной и той же задачи.

6️⃣ «Что не говорится в подсказках» (2025)
— Недостаточно конкретизированные подсказки в 2 раза чаще приводят к сбоям, снижение точности более чем на 20%.

————

Документация Anthropic по промптам для Claude AI:

7️⃣ Документация по промпт-инжинирингу (главное руководство)
8️⃣ Best Practices для Claude 4.x моделей (Sonnet 4.5, Haiku 4.5, Opus 4.5)
9️⃣ 5 интерактивных образовательных курсов по промптингу
1️⃣0️⃣ Коллекция готовых примеров кода и руководств для разработчиков
1️⃣1️⃣ Библиотека готовых промптов
1️⃣2️⃣ Эффективная разработка контекста для ИИ-агентов
1️⃣3️⃣ 6 методов эффективного промптинга

————

Руководства Google по промптам и Gemini API (2025):

1️⃣4️⃣ API Gemini
1️⃣5️⃣ Оперативные стратегии проектирования
1️⃣6️⃣ Промпт-инжиниринг (68 страниц)
1️⃣7️⃣ Примеры промптов

————

Некоторые вещи, которые долго добавлял в промпты, теперь бесполезны.

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

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

Расскажу в серии постов самое важное из оптимизации:

— Алгоритмов обработки данных в Power Query.
— Промптов для создания быстрого кода.
— Параметризации кода переменными.


Эти приёмы можно натянуть на другие языки программирования, логика от этого не изменится.

Тема бесконечная, но надо с чего-то начать.

В следующем посте — о выборе нейронок.

via @ppc_bigbrain
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥126👍4
О выборе нейронок для BI-разработки.

Предыдущие посты серии:

1. Документация по промптам.


Перепробовал разные нейросети, платные тарифы, разные подходы к промптам, но пока не нашёл ничего лучше Claude (Anthropic) и Gemini (Google) для BI-разработки:

— На языке M в Power Query.
— На языке DAX в Power Pivot.


Главные выводы:

1️⃣ Хочешь результат сразу — покупай в нейронке платный тариф.

2️⃣ Хочешь бесплатно — страдай неделями бесплатно, переделывая сотни раз одно и то же.

3️⃣ Генерируй код сразу в нескольких нейронках одновременно и сравнивай результаты:

— Корректность обработки первых 50–100 строк массива:

а) Каждого шага запроса (модуля кода) по отдельности.
б) Всего запроса целиком.

— Корректность обработки нужного столбца, отфильтрованного по условиям (символам, словам, фразам), которые данный код:

а) Должен был обработать.
б) Не должен был обработать.

— Скорость на тестовом массиве на 30–50 тысяч строк.

— Производительность на объёмах в 0,5–1 млн строк.


4️⃣ Почему сразу в нескольких нейронках — потому что неизвестно, где получите код лучше:

— Без ошибок.
— Быстрее работающий.
— Масштабируемый (применимый для обработки больших массивов данных).


Чем больше сравнений делал, тем реже стал пользоваться чем-либо ещё кроме Claude и Gemini, но даже сравнивая их ежедневно, фаворита так и не выявил. Для биай разработки хороши оба.

Итак, общий алгоритм действий:

1️⃣ По одному и тому же промпту генерю код в нескольких нейронках сразу.

2️⃣ Проверяю на наличие ошибок.

3️⃣ Текст ошибки вместе с названием шага запроса, на котором появилась ошибка, копирую нейронке, и говорю исправить.

4️⃣ Проверяю на корректность обработки данных, отфильтровав в разных столбцах разные условия (символы, слова, фразы), которые после обработки:

🥷 Должны были там появиться.
🥷 Не должны были там появиться.

5️⃣ Выбираю корректно и безошибочно отработавший код (при наличии такового).

6️⃣ Выбираю очевидно самый быстрый вариант кода.

7️⃣ Каждую нейронку ещё по несколько раз прошу переписать корректно отработавший код, пользуясь всегда примерно одинаковым подходом к оптимизации скорости запроса.


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

Самым внимательным сверхразумам, кто заметит этот общий паттерн в промптах, приведенных в следующих постах, пирожок с полочки в подарок.

Этот подход уже много раз подтверждал свою пригодность, т.к. общий объём кода всё растёт, данных обрабатывается всё больше, функционал автоматизации всё сложнее, но несмотря на общее усложнение алгоритма, весь пайплайн со временем продолжаю только ускорять, детальнее разбираясь в особенностях алгоритмов в целом и Power Query в частности.

Некоторые модули кода я уже просто сбился со счёта, сколько раз переделывал.

Но не смотря на это, потом в рандомный момент или на Ютубе, или в статье, или в комментариях нейронки к очередному модулю кода я внезапно вижу некую абстрактную идею, в голову приходит мысль потестить её в другой части комбайна, И ХОБА — ускорение отработки переделанного запроса с 5 минут до 5 секунд.

А всё почему? А всё потому, что продолжаем список главных выводов:

5️⃣ Графический интерфейс Power Query — зло.

Да, он упрощает визуальное восприятие того, как происходит обработка данных, но это никак не способствует увеличению производительности.

Чем больше привыкаешь к GUI Power Query:

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

Про GUI поговорим в отдельной серии постов

6️⃣ Нужно учить матчасть вычислений.

Это и рассмотрим дальше.

В следующем посте — о подготовке к созданию какого-либо кода.

via @ppc_bigbrain
Please open Telegram to view this post
VIEW IN TELEGRAM
35👍2👌1
Подготовка к созданию какого-либо кода.

Предыдущие посты серии:

1. Документация по промптам.
2. Выбор нейронок.


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

Логику обработки данных придумываю я сам. Вы исключением вряд ли станете. Никакие нейросети здесь не помогут.

Нейронки понятия не имеют:

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

————

🔣 В этом посте подробно разбирал пример с разбором:

— Проблемы.
— Последствий.
— Решения.
— Итогов.
— Новых возможностей.

————

Шаг номер минус два — осознание проблематики:

⚫️ К чему приводят последствия нерешённой задачи.
⚫️ Как и почему от этого страдаю я и мой клиент.
⚫️ Как и почему я страдаю от этого на каждом последующем проекте.
⚫️ Как и почему от этого страдают другие люди, у кого всё ещё нет на руках готового автоматизированного решения этой проблемы.
⚫️ Как и почему я страдаю в процессе объяснения любому собеседнику (клиентам, коллегам) всех перечисленных выше 4 пунктов.


Шаг номер минус один — зарабатываем насмотренность:

⚫️ Ищем на ютубе плейлисты по самой базовой базе интересующего языка программирования и смотрим хотя бы базу для чайников.
⚫️ Понимаем, на что он вообще способен, какие есть типы объектов, операций, библиотеки и проч.
⚫️ На каждом рассмотренном примере включаем образное мышление и сразу пытаемся придумать десятки способов применения увиденного для обработки ваших данных.
⚫️ Делаем скриншоты и заметки, сохраняем ссылки в разные плейлисты избранного, чтобы потом легко найти всё сохраненное.
⚫️ При сохранении ссылок сразу пишем комментарий, что нашли в видео, какая идея появилась, как и где хотели это применить.
⚫️ По каждой новой появившейся идее ищем на ютубе ролики, читаем статьи, спрашиваем у нейронок, как это работает, как это применить в ваших задачах, смотрим на конкретные примеры реализации, расширяем понимание возможностей данного языка.


Шаг номер ноль — бизнес-задачи:

😶 В каком виде нужно получить результат обработки данных, чтобы они стали полезными для принятия бизнес-решений:

⚫️ Для кого строится эта визуализация данных.
⚫️ На какие основные и дополнительные вопросы она должна отвечать.
⚫️ Как должен выглядеть результат.
⚫️ Как его нужно отфильтровать, отсортировать, сегментировать.
⚫️ Какие данные должны обновляться, как часто.


😶 Потенциальные способы решения, используя заработанную насмотренность на Ютубе, в статьях, в ответах нейронок.

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

😶 Потенциальные формулировки для нейросетей.

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

😶 Если уже есть какие-либо данные в ваших готовых модулях кода — потенциальные способы манипуляций с теми или иными объектами (таблицами, полями, записями, списками, функциями, типами данных).

😶 Потенциальные способы параметризации всех обрабатываемых объектов — во избежание хардкода любых объектов текстовыми значениями прямо в коде.

Промпт для оптимизации кода под производительность на объёмах и масштабируемость — в следующем посте.

via @ppc_bigbrain
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍107🗿2❤‍🔥1🔥1
Оптимизация кода под производительность на объёмах

Предыдущие посты серии:

1. Документация по промптам.
2. Выбор нейронок.
3. Подготовка к разработке.


Памятка:

В Power Query последовательно выполняются все связанные запросы в цепочке.
Если в последнем запросе 5 строк кода, но перед ним в пайплайне их — 5000, то выполнятся все 5005 строк.
Код начинаем оптимизировать с первого же запроса.
Оптимизация последнего запроса не спасёт, если перед ним 50 медленных с вычислениями O(n × m), O(n²), O(nᵏ) и лишними операциями.

«Big O» нотация.


Пишем промпт в несколько нейросетей и повторяем:
— С дебагами ошибок.
— С оптимизацией.
Пишем промпт «сэндвичем»:
— Внимание в начале.
— Основная часть.
— Внимание в конце.

————

Старт промпта — кратко (attention в начале):

— Язык и версия.
— Среда разработки и версия.
— Об исходных данных.
— Проблема.
— Задача.
— Что где находится.
— Названия всех объектов.
— Что нужно получить в результате.


Кусок кода, который нужно оптимизировать (если он есть).

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

Списочное иерархичное явное перечисление всех операций по точным шагам, как в конспекте из вуза при подготовке к экзамену.

Точные примеры "было–стало", чтобы нейронка явно поняла, что делать:

1. Исходные данные (было).
2. Итоговый результат (стало).
3. Явное пояснение, чем отличается результат от исходных данных.


Для чего это нужно — чтобы нейронка не гадала за вас, что вам нужно. Чем более явными будут инструкции, тем быстрее вы получите правильно и быстро работающий код.

Завершаем «сэндвич» промпта финальным блоком внимания (attention в конце):

1. Внимательно проанализируй задачу и приложенный код, если он предоставлен.

2. Если тебе не хватает явных инструкций — задай мне точные вопросы.

3. Найди все узкие горлышки.

4. Оптимизируй код под производительность.

5. Ускорь отработку.

6. Обрабатывай только уникальные значения.

7. Используй операции с количеством вычислений O(1), O(log n), O(n), O(n + m), но как можно меньшее из них — для быстрой обработки сотен тысяч строк.

8. Не используй операции с количеством вычислений: O(n log n), O(n × m), O(n²), O(nᵏ), O(2ⁿ), O(n!).

9. Используй аналоги векторной обработки всего массива целиком.

10. Используй самые современные методы оптимизации M-кода в Power Query, которые советуют известные и уважаемые профессионалы BI-индустрии, эксперты со статусом MVP от Microsoft, авторы книг, курсов, блогов, статей, Ютуб-каналов по Power BI и Power Query.

11. Используй функции только из справки Microsoft по Power Query.

12. Используй самые прогрессивные способы оптимизации производительности M-кода в Power Query на сотнях тысяч и миллионах строк данных.

13. Оптимизируй код без потери функционала.

14. Пиши код понятно по шагам.

15. Назови шаги понятным образом.

16. Убедись в том, что ты:
а) Ничего не потерял и не забыл из исходного кода.
б) Учёл все перечисленные условия.


Не используем CAPS LOCK и слов "ВАЖНО" во избежание смещения внимания.

Независимо от того, насколько быстро отработал тестовый код, всё равно говорим нейронке:

Код работает очень медленно.

1. Проанализируй все узкие горлышки.

2. Проанализируй код на количество вычислений из «Big O» нотации.

3. Определи места для уменьшения количества вычислений.

4. Используй функции с наименьшим из возможного количества вычислений: O(1), O(log n), O(n), O(n + m), но как можно меньшим из них.

5. Ускорь код для быстрой обработки сотен тысяч строк данных.

6. Ничего не забудь из поставленных задач и исходного функционала.


Так повторяем с разными нейронками, замеряя время выполнения и корректность результатов кода каждой из них.

Через несколько таких итераций получаем высокопроизводительный код, который буквально летает.

Что делать, если код всё ещё не летает — идти на завод в следующем посте.

via @ppc_bigbrain
Please open Telegram to view this post
VIEW IN TELEGRAM
3🔥5❤‍🔥22
Что делать, если код всё ещё не "летает".

Предыдущие посты серии:

1. Документация по промптам.
2. Выбор нейронок.
3. Подготовка к разработке.
4. Оптимизация кода.


Вы часто забываете, что:

1. Нейронки врут.
2. Они уверенны в своей лжи, потому что всего лишь предсказывают следующий символ, не более того.
3. Они запрограммированы ублажать и хвалить вас, если не дано иных инструкций.
4. Они будут врать вам, пока вы не попросите вас унизить.


Поэтому пишем в любой промпт:

— Не соглашайся со мной.
— Мне не нужно, чтобы ты ублажал меня лестью.
— Критикуй меня.
— Подвергай сомнению всё сказанное мной.
— Процеди все мои слова через сито здравого смысла.
— Укажи мне на явные ошибки.
— Укажи явно, почему это ошибки.
— Перечисли более оптимальные решения.
— Укажи явно, почему они оптимальнее.
— Используй наилучшее из них.


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

Если перечислить только названия списков, таблиц и прочих объектов, нейронка может не понять, что за чем следует, и что делать с каждым из них.

Описываем нейронке:

— Сколько строк в источнике (лучше сразу говорите — сотни тысяч, и нужно оптимизировать код под производительность на больших объёмах данных).

— Если в источнике таблица — сколько в ней столбцов. Прочитать 2 столбца не то же самое, что прочитать 100. Передать 2 столбца дальше по пайплайну из 100 шагов кода не то же самое, что передать 100.

— Какие поля нужно обработать и как.

— Какие поля нужно передать дальше по пайплайну.

— Зачем они вам нужны, что вы с ними собираетесь делать дальше.

— Какие поля удалить.

— Что отфильтровать и как.

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

— Как параметризировать условия фильтрации, группировки, сортировки.


В несколько итераций в нескольких нейронках одновременно:

— Вставляем каждый модуль кода и просим проанализировать и переписать его точно таким же промптом, как в предыдущем посте («Big O» нотация).

— Добиваемся корректно работающего кода.

— Замеряем скорость обработки данных:
а) До — старым кодом.
б) После — новым.


Описываем нейронке, в каком виде находятся данные в предыдущих модулях:

— Что делает предыдущий модуль.

— Его код.

— Пишете:

1. Проанализируй оба модуля.

2. Найди узкие горлышки, замедляющие общую обработку.

3. Найди места, где можно добавить буферизацию.

4. Используй функции с наименьшим из возможного количества вычислений из «Big O» нотации.

5. Объедини запросы и ускорь выполнение.


Если в исходных данных находится таблица (что для специалистов по контекстной рекламе наиболее вероятно), которую нужно отфильтровать большим списком условий, добавляем в промпт:

1. Перепиши часть кода с фильтрацией данных самым быстрым из возможных способов.

2. Буферизуй список, который нужно отфильтровать.

3. Не используй функции, которые вызывают создание множества промежуточных таблиц в памяти.

4. Не используй функции, которые копируют из итерации в итерацию исходную таблицу или исходный столбец множество раз.

5. По возможности используй функции, которые вызывают количество вычислений O(1), O(log n), O(n), O(n + m), но как можно меньшее из них на сотнях тысяч строк данных, а не квадратичные или экспоненциальные вычисления.


После генерации кода по выше указанному промпту переспрашиваем:

1. Является ли это самым быстрым из возможных решений?

2. А что, если строк в массиве будет миллион?

3. Убедись в том, что ты написал алгоритм, использующий наименьшее из возможного количества вычислений O(1), O(log n), O(n), O(n + m) под производительность на больших объёмах данных.

4. Оцени теоретически возможный минимум количества вычислений для максимально быстрого выполнения задачи в этом коде.

5. Оптимизируй код самым производительным из возможных способов.


О минимизации количества вычислений — в следующем посте.

via @ppc_bigbrain
3👍43
Минимизируем количество вычислений и чтений данных

Предыдущие посты серии:

1. Документация по промптам.
2. Выбор нейронок.
3. Подготовка к разработке.
4. Оптимизация кода.
5. Если код не "летает".


При неоднократном обращении к таблицам и спискам:

⚫️ Буферизуем их (кешируем) в начале запроса.

⚫️ Используем при фильтрации буферизованные списки и таблицы, но с таблицами нужно быть очень аккуратными, об этом — ниже.

————

Буферизуем в Power Query:

⚫️ Списки для фильтрации и проверки наличия.

Если список используется многократно в List.Select, List.Contains или для создания HashSet — оборачиваем в List.Buffer. Это гарантирует, что список будет вычислен один раз и сохранён в памяти.

⚫️ Списки перед созданием Record (HashMap).

Перед вызовом Record.FromList буферизуем исходный список ключей. Сам Record после создания буферизовать не нужно — он уже в памяти.

⚫️ Таблицы-справочники.

Небольшие таблицы, которые используются для поиска значений (lookup), лемматизации, замен и подобных операций. Буферизуем через Table.Buffer перед созданием из них Record-словаря.

⚫️ Объединение таблиц.

При Table.NestedJoin или Table.Join таблицы читаются многократно. Буферизация предотвращает повторное вычисление. Но первую таблицу буферизовать опасно, если она большая.

Table.Join гораздо быстрее, чем Table.NestedJoin

⚫️ Небольшие внешние источники данных.

Таблицы из Excel-файлов, CSV, API и других внешних источников буферизуем для исключения повторного их чтения ТОЛЬКО ЕСЛИ:

а) они небольшие.

б) вы обращаетесь к ним более одного раза.


————

Не буферизуем в Power Query:

⚫️ Большие таблицы (например, выгрузка статистики рекламного кабинета).

Таблицы свыше 100–200 тысяч строк буферизовать опасно — это может привести к ошибке Out of Memory или сильному замедлению. Для больших данных используем потоковую обработку.

⚫️ Широкие таблицы.

Даже если строк немного, таблица с 20+ столбцами занимает много памяти. Перед буферизацией лучше оставить только нужные столбцы через Table.SelectColumns.

⚫️ Промежуточные шаги в цепочке преобразований.

Power Query использует ленивые вычисления — данные обрабатываются потоково, без материализации промежуточных результатов. Буферизация каждого шага убивает это преимущество.

⚫️ Результат Table.Group.

Группировка уже материализует результат. Дополнительная буферизация не даёт выигрыша.

⚫️ Record (HashMap).

После создания через Record.FromList словарь уже находится в памяти. Буферизовать его не нужно и невозможно — функции List.Buffer и Table.Buffer к нему не применимы.

————

Ориентиры по размерам, буферизовать ли данные:

Списки до 100 тысяч строк — буферизовать безопасно.

— Таблицы до 50 тысяч строк и шириной до 10 столбцов — буферизовать безопасно.

— Таблицы от 50 до 200 тысяч строк — буферизуем только если это действительно необходимо и есть запас оперативной памяти.

— Таблицы свыше 200 тысяч строк не буферизуем, а используем потоковую обработку с фильтрацией до объединения.

Точные пороги необходимости буферизации зависят от:

а) Доступной оперативной памяти на ПК.

б) Высоты и ширины исходных таблиц.

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


————

Если не понимаете, почему фильтрация или сортировка выполняются долго, скажите нейронке:

1. Проанализируй код на предмет сложности вычислений из «Big O» нотации:

От самых быстрых:

O(1) — константное время.
O(log n) — логарифмическое.
O(n) — линейное.
O(n + m) — линейное время от двух входов.

К самым медленным:

O(n log n) — линейно-логарифмическое время.
O(n × m) — бинейное.
O(n²) — квадратичное.
O(nᵏ) — степенное.
O(2ⁿ) — экспоненциальное.
O(n!) — факториальное.

2. Перепиши код с использованием самых быстрых из возможных вычислений: O(1), O(log n), O(n), O(n + m).

3. Не используй функции с медленными вычислениями: O(n log n), O(n × m), O(n²), O(nᵏ), O(2ⁿ), O(n!).


В следующем посте — пример, не понимая матчасть которого, ждать обработку придется вечность.

via @ppc_bigbrain
Please open Telegram to view this post
VIEW IN TELEGRAM
3🔥43🤝3
Фатальный пример, который будет вычисляться вечность

Предыдущие посты серии:

1. Документация по промптам.
2. Выбор нейронок.
3. Подготовка к разработке.
4. Оптимизация кода.
5. Если код не "летает".
6. Минимизируем вычисления.


Это не придуманный пример. Это кулстори о том, как началось моё знакомство с обработкой данных 6 лет назад.

Задача: взять данные из одной таблицы и отфильтровать в ней данные из другой таблицы.

Решение от сверхразума (НЕ НАДО ТАК ДЕЛАТЬ):

1️⃣ К текущей Таблице 1небольшой выгрузке данных из рекламного кабинета со всеми возможными атрибутами и метриками и детализацией до дат:

500.000 строк * 30 столбцов = 15.000.000 ячеек


Присоединяем Таблицу 2:

10.000 строк * 10 столбцов = 100.000 ячеек


2️⃣ Потом отсортируем строки.
3️⃣ Потом отфильтруем строки по ряду условий.
4️⃣ Потом создаем новые столбцы, что инициирует создание копии целой таблицы.

Но из-за незнания матчасти к чему приводит именно такой порядок действий:

1️⃣ Сначала в Таблице 1 создаем новый столбец. Тем сам записывая в память всю таблицу целиком, т.к. каждая операция Table.AddColumn создаёт в памяти копию всей исходной таблицы.

2️⃣ В новом столбце Таблицы 1 ссылаемся в каждой ячейке на целиком всю Таблицу 2. Тем самым создав столько же копий Таблицы 2, сколько строк в Таблице 1.

Только за сам факт того, что объединение таблиц выполняется таким зверским садистским для процессора способом, уже нужно отрубать руки и публично пинать ссаными тряпками.

3️⃣ Разворачиваем Таблицу 2 целиком, тем самым умножив друг на друга количество строк из Таблицы 1 на количество строк из Таблицы 2:

500.000 строк * 10.000 строк = 5 млрд строк


А также расширили объединённую таблицу на количество столбцов из Таблицы 2:

5 млрд строк * (30 + 10 столбцов) = 200 млрд ячеек


Теперь в объединённой таблице 200 миллиардов ячеек.

4️⃣ И этот массив мы еще дальше собираемся:

Сортировать.
Фильтровать.
Добавлять несколько новых столбцов — каждая вызванная функция Table.AddColumn создает в памяти копию целиком всей объединённой таблицы из 200 млрд ячеек с каждого предыдущего шага.

Нетрудно догадаться, что после перемножения таблиц каждая из последующих операций вызовет во столько же раз больше вычислений, во сколько раз выше стала Таблица 1, будучи умноженной по вертикали на количество строк из Таблицы 2.

Накинем сюда ещё и то, что чем больше столбцов в любом обрабатываемом массиве, тем дольше отрабатывает каждый шаг.

При присоединении и разворачивании целиком всех столбцов из Таблицы 2, в которой было 10 столбцов, ради того, чтобы, например, оставить в итоге 1–2 столбца, общее количество вычислений при дальнейших сортировках и фильтрациях будет рассчитываться не только умножением строк из Таблицы 1 на количество строк из Таблицы 2, а ещё теперь и на общее количество столбцов в объединённой таблице.

Вот откуда берутся долго работающие запросы.

Вот откуда растут ноги у проблемы.

Надо ли добавить очевидное, что спустя сутки ожидания я так и не дождался обработки этого запроса 6 лет назад? А ждал бы до сих пор.


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

via @ppc_bigbrain
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍32🔥2💩1
В каком порядке оптимальнее обрабатывать данные.

Предыдущие посты серии:

1. Документация по промптам.
2. Выбор нейронок.
3. Подготовка к разработке.
4. Оптимизация кода.
5. Если код не "летает".
6. Минимизируем вычисления.
7. Фатальный пример вычислений.


1️⃣ Удаляем ненужные столбцы.

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

3️⃣ Обрабатываем уникальные значения в новом столбце.

4️⃣ Если эти данные нужны на следующих этапах — объединяем исходный массив с этим запросом по общему полю.

5️⃣ Если эти данные нужны в таком виде в конечной визуализации данных:
а) Выгружаем второй запрос в модель данных.
б) Объединяем две таблицы по ключевому полю в модели данных, т.к. это работает быстрее.

Нет необходимости понимать код. Достаточно понимать, как попросить нейронку:

1. Обратиться к нужным таблицам и столбцам.
2. Какие операции нужно сделать.
3. Что должно получиться в результате.
4. Какие вычисления безопасны: O(1), O(log n), O(n), O(n + m).
5. А какие — смерть для производительности: O(n log n), O(n × m), O(n²), O(nᵏ), O(2ⁿ), O(n!).


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

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

😶 Либо вычленив общие текстовые паттерны в заголовках этих полей и отфильтровав:
1. Значение: {"Текст"}.
2. Хардкод списка (так делать не нужно): {"Текст1", "Текст2", "Текст3"}.
3. Имя списка, который динамически получает список текстовых значений.

Примеры, как их отфильтровать (список неполный, ибо способов — уйма) по:

— Содержанию: List.Contains
— Отсутствию: not List.Contains
— Началу: Text.StartsWith
— Не началу: not Text.StartsWith
— Окончанию: Text.EndsWith
— Не окончанию: not Text.EndsWith

😶 Либо обратив внимание на расположение в таблице самих полей и если они находятся:

— Или всегда в начале;
— Или всегда в конце;
— Или идут подряд;
— Или стоят до, после или между полями с заведомо известными значениями;

То получить функцией Table.ColumnNames список полей таблицы, а дальше отфильтровать их:

— Взяв N элементов с начала списка: List.FirstN
— Взяв N элементов с конца списка: List.LastN
— Удалив N элементов в конце списка: List.RemoveLastN
— Получив диапазон значений между N и M позициями списка: List.Range
— Пропустив N элементов с начала списка: List.Skip

Преобразуем список уникальных значений:

😶 Удаляем дубликаты, пустоты, null.

😶 В начале следующего запроса буферизуем его: List.Buffer.

В следующем посте — о смерти производительности кода в Power Query.

via @ppc_bigbrain
Please open Telegram to view this post
VIEW IN TELEGRAM
👀2🔥1