Исяка, или как остановить дубли в Директе

О чем не говорят на курсах по Яндекс.Директу

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

Глоссарий

РК - рекламная кампания
НЧ, СЧ, ВЧ - низкочастотные, среднечастотные, высокочастотные (запросы)
SKAG - single keyword per ad group - принцип "1 группа - 1 ключ"
4P (marketing mix) - product, price, promotion, place - маркетинговое понятие из 60-х
AIDA - attention, interest, desire, action - еще более древнее маркетинговое понятие, из 20-х

Предисловие


Представим ситуацию: у вас есть продажа сезонных и несезонных товаров (но вторые тоже иногда продаются в несезон, просто у групп появляется статус "мало показов", если они не сгруппированы.

Есть всесезонная рекламная кампания про слонов и жирафов, создавалась смешиванием этих животных и подстановкой в заголовок и/или текст объявления ключей в шаблон ##. Статуса "мало показов" у групп нет, т.к. спасает всесезонный товар "жирафы". Мы расположили ключевые слова в группах таким образом, чтобы в любой группе был ВЧ-СЧ ключ про жирафов, и спасал группу от статуса "мало показов".
Создавалась примерно вот с такой семантикой. Громоздкая РК, десятки тысяч ключевых слов, но полный охват аудитории:

А так будет выглядеть эта РК в интерфейсе Директ.Коммандера. Сотни групп, десятки тысяч ключевых слов, без статуса "мало показов", но шаблонно и CTR не очень. И все же лучше, чем ничего. Слонов тоже нужно продавать, по ним средний чек выше:

Есть сезонная РК про слонов, ее, соответственно, включаем только в сезон, в ней заголовки и тексты без шаблонов, составленные честь по чести, по принципам 4P, AIDA, с УТП, кросс-продажами и прочими премудростями, чтоб CTR и конверсия зашкаливали, в сезон никто нас не обошел, весь рынок был наш и мы заработали много денег.
Семантика подбиралась тоже точно под запросы пользователей, с учетом именно тех словоформ, которые они используют (семантика в основном из комбинаций фраз на скриншоте).

А так будет выглядеть уже сама РК, составленная по SKAG-принципу:

Ну вот, вроде все в порядке, теперь нужно обеспечить, чтобы 100% показов по тематике "слоны" в сезон достались новой кампании, для чего в старой шаблонной кампании их следует остановить.

Проблема

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

Единственная проблема тут - в Директ.Коммандер нельзя импортировать и тем самым заменить статус фраз. Зато можно залить отличную от других фраз уникальную ставку!
Далее, фильтруя по уникальной ставке, можно остановить выбранные фразы. Т.е. залить с измененными ставками нужно только выбранную РК (в нашем случае это "слоны и жирафы").
Но это не то решение, которое я хотел описать в статье, и вот дело в чем:
1. Это сложно и долго
2. Это несовершенный способ, т.к., например, сторонние морфологические библиотеки отличаются от нативной библиотеки Яндекса, поэтому могут не обнаружить некоторые дубли.
3. Это не работает на больших объемах (более 100к фраз даже на мощном компьютере) - при импорте из excel Яндекс.Коммандер не справляется - "падает" или "виснет".
4. Я не знаю ни одного стороннего решения, которое при определении дублей учитывало бы операторы Яндекс.Директа.

Решение

А решение заключается в использовании алгоритма кросс-минусовки, встроенного в сам Директ.Коммандер. И приближает к раскрытию тайны заголовка статьи.
Итак, наша задача остается прежней. Сначала найти дубли в одной РК, а затем маркировать их, чтобы остановить. Казалось бы - при чем тут кросс-минусовка? Мы же дубли удаляем. Все на самом деле удивительно просто, нужно только задать себе пару вопросов.
Чем отличаются дубликаты ключевых фраз? Ничем, на то они и дубликаты! Морфологически все слова одной фразы должны совпадать со словами другой фразы. Если слово в одной фразе закреплено оператором, в другой должно быть закреплено аналогичным.
А какое следующее наиболее близкое к дублированию состояние? Отличие на 1 слово. Фразы очень похожи, но уже не дубли. Их отличает 1 слово. И при кросс-минусовке оно будет обнаружено и проставлено в минус-слова к той фразе, которая является "дублем-минус-одно-слово". Догадываетесь?
Имея два массива дублирующихся фраз, можно в одном из них дописать к фразе слово, и во втором массиве в дублях оно отминусуется, и станет своеобразным маркером дублей. Но что нужно, чтобы маркер был достоверным, и мы были уверены, что это минус-слово уже не присутствует во фразах? Нужно, чтобы оно было
уникальным! Как ставка в предыдущем примере. Например, выдуманным! Все, что взбредет вам в голову. Я выбрал слово, которым моя маленькая дочь в возрасте около полутора лет называла жирафов. Исяка. Сейчас ей уже почти 3 и она замечательно зовет их жирафами, но вот это выдуманное слово мне очень запомнилось.

Итак, итоговый алгоритм:
1. Дописываем в одну из РК (ту, в которой дубли останавливать не будем) к фразам наше выдуманное слово:

2. Производим кросс-минусовку между двумя РК. Это хорошо оптимизированный алгоритм, работает на любых объемах в Директ.Коммандере.

3. Фильтруем в РК "Слоны и жирафы" ключевые фразы, где в минус-словах замечено слово "исяка"

4. Останавливаем!

5. В предыдущей РК отменяем изменения, скачивая ее повторно. В текущей РК можем удалить Исяку из минус-слов, если мешается, но лучше не удалять, это наш маркер, который поможет их включить обратно, когда кончится сезон.

Спасибо тем, кто дочитал до конца! Ждите новые лонгриды по аналогичным сущим пустякам :)