Мобильный маркетинг

Яндекс.Директ. Часть 2: медиапланирование.

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

Я взял 5 слов и с помощью «Прогноза бюджета» собрал статистику по каждой позиции.

1-е спецразмещение.

2-ое спецразмещение.

Спецразмещение.

1-ое место.

Гарантированные показы.

Анар Бабаев в учебнике «Контекстная реклама» приводит такой пример.

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

Сделаем все руками.

Собираем все таблицы в единую панель. Вывел первые две позиции.

Оставляем только ставки по каждому слову для всех позиций.

Делаем все возможные комбинации ставок.

Вот здесь действительно нужен мощный сервер, hadoop или Apache Storm. Только для наших 5 слов вышло 3125 комбинаций. Это 3125 таблиц Excel, среди которых нужно выбрать лучшую!

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

Давайте пока закончим расчеты. Предположим, 3 процента из посетителей сайта приходят на пробный урок и остаются в школе. Средний срок жизни клиента — 6 месяцев, LTV — 21 000 р.

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

Низ колонки.

Как видно, варианты бюджета и прибыли могут отличаться в 20 раз. Мы можем потратить 1056 р. и заработать 39 894 р. за следующие 6 месяцев, а можем вложить 19 022 р. и получить 364 000 р. прибыли.

При миллионных бюджетах вложения в мощные сервера себя окупят.

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

Тестовая кампания покажет, что нужно скорректировать. И напоследок отмечу, что это лишь один из вариантов распределения бюджета. Есть и другие эффективные способы, не требующие дорогого оборудования.

13 февраля   Yandex

Яндекс.Директ. Часть 1: кластеризация.

Начну с интересной методики, которая позволит работать с очень большим семантическим ядром, хоть с 500 000 слов.

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

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

  • Много запросов по фильмам — «Последнее танго», «фильм», «Танго в Париже», «Четыре танго».
  • Есть одноименные магазины — «иркутск», «каталог», «сайт», «магазин».
  • Много запросов про музыку, оркестры — «ноты», «скачать», «слушать», «слова», «лунное танго».
  • Запросы про одноименное белье, брелоки, духи, мебель.
  • Локальные запросы — спб, новгород.

Мы сделали домашнюю работу и знаем, что околотематику «фильмы про танго» если и стоит тестировать, то не в первую очередь. Но очень много учеников пришло, посмотрев фильм «Запах женщины», поэтому его нужно добавить.

Мы не уверены, что любители оркестров танго также любят танцевать. Но не проходим мимо запросов про аргентинского музыканта Пьяццола и «Кумпарситы»: ими часто интересуются те, кто уже пробует танцевать либо давно танцует.

Мы нашли три интересных запроса:

  • школа танго;
  • танго для начинающих;
  • танго в Москве.

Я собрал 233 запроса по этим фразам, возьмем их пока за основу.

Дальше нам нужно разбить их на близкие по смыслу группы. В таблице первые 9 слов из списка. Второй столбец повторяет первый, пока не обращайте внимания.

Импортируем нужные библиотеки — sklearn, nltk, стеммер, стоп-слова, модуль для кластеризации по методу k-средних.

Готовим фразы к кластеризации. Разбиваем на отдельные слова, превращаем прописные в строчные.

Удаляем все предлоги и союзы — «для», «и», «в», «на».

Оставляем только корни слов.

Переводим обратно в строки.

Векторизуем.

Разбиваем все слова на 9 кластеров.

Смотрим результат.

Слова разбиты на кластеры, теперь мы можем использовать методы анализа данных. Например, как здесь.

Мы можем узнать:

  • Сколько слов в каждом кластере?
  • Какой кластер самый большой?
  • В каком кластере самые дорогие слова?
  • Где самый большой спрос?

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

13 февраля   Acquisition   Yandex

Немного data science

В этом посте я покажу небольшой пример data science, взяв за основу прекрасный курс Udacity по анализу данных.

Каролина, аналитик Udacity, писала функции на python. Я пройду те же шаги, но буду пользоваться библиотекой Pandas. Сами выборки вы можете скачать тут.

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

Первая таблица — данные о регистрации на курсы. Здесь уникальный идентификатор студента, статус (учится или закончил), даты начала и конца обучения, общий срок учебы. Цифры перед таблицами — общее количество строк и количество уникальных студентов (account_key).

Вторая — данные по engagement, вовлеченности. Снова уникальный идентификатор, дата посещения платформы, количество просмотренных курсов, общее время на платформе.

Третья — данные по сданным проектам. Идентификатор студента, успешно сдал или нет, идентификатор курса.

Чистка данных.

Для начала подправим таблицы — даты переведем в даты, «acct» переименуем в «account_key», числа сделаем целыми. Для краткости я привел лишь часть кода. Все таблицы выше показаны в обработанном виде.

Вопросы.

На этом этапе пишем вопросы, на которые хотели бы получить ответы.

  • Сколько времени требуется студентам, чтобы сдать первый проект?
  • Насколько отличаются студенты, успешно сдающие проекты, от неуспешных?
  • Сколько времени у них уходит на учебу?
  • Влияет ли время, потраченное учебу, на количество сданных проектов?
  • Изменяется ли со временем их engagement?

Выбираем второй.

Исследуем данные.

Вы уже заметили расхождение в количестве уникальных студентов. В таблице с регистрациями 1302 уникальных студента, а в второй по engagement — 1237. Они должны совпадать, с данными что-то не так.

Выведем данные любого студента из таблицы регистраций, которого нет в engagement.

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

Исследуем дальше, остался ли кто-нибудь еще помимо таких студентов? Находим еще три записи. Это тестовые аккаунты Udacity, они тоже могут отсутствовать в таблице вовлеченности.

Выводим все тестовые аккаунты.

Удаляем их из всех таблиц, смотрим на их размер.

Уточняем вопрос.

Вовлеченность студентов может меняться со временем, поэтому мы:

  • будем сравнивать студентов только по первой неделе с момента регистрации;
  • исключим всех, кто покинул программу во время 7-дневного пробного периода.

Исследуем дальше.

Сделаем выборку из таблицы регистраций — оставим студентов, которые еще учатся либо учились больше 7 дней.

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

Во всех таблицах оставим только этих «платных» студентов. Смотрим их размер.

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

Начинается самое интересное — смотрим, сколько времени в среднем они проводят на платформе, стандартное отклонение, максимальное и минимальное значение. В среднем в первую неделю студенты тратят 306 минут, минимум — 0, максимум — 3564.

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

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

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

Берем третью таблицу, оставляем студентов, которые успешно сдали проект. Выводим количество.

Смотрим вторую таблицу вовлеченности, делим данные на две части: сдавшие проект и несдавшие. Смотрим количество строк.

Сравниваем две группы по количеству минут, проведенных за занятиями в первую неделю. Студенты, успешно сдавшие проект, в среднем проводят больше времени за занятиями — 394 минуты против 143.

Сравниваем количество пройденных занятий. Оно тоже выше — 2 против 1.

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

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

Выводы.

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

И тут идет речь о корреляции. Мы не можем утверждать, что студенты будут лучше учиться, если мы будем им чаще напоминать про курсы. Это поможет выяснить эксперимент, A/B-тест.

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

13 февраля   data science

API Vkontake — автоматическое обновление креативов

CTR любых объявлений со временем снижается, их приходится обновлять для сохранения кликабельности и охвата. Система автоматизации Marin Software в своем руководстве «The Definitive Facebook Advertising Playbook» включила ротацию креативов в 4 восходящих тренда.

«...Значительно увеличилось количество рекламодателей, использующих ротацию креативов. Такие рекламодатели Marin в среднем получают CTR на 35% выше, чем остальные. Это подтверждает, что пользователи чаще обращают внимание на свежие креативы».

Как только у нас есть готовое правило (например, CTR < 0,3%), мы можем добавить его в систему мониторинга для автоматического обновления креативов. Вот пример для Vkontakte.

Получаем id объявлений с низким CTR.

(В данном конкретном примере я проверял количество показов, но суть та же.)

Получаем id кампании каждого объявления, удаляем объявления.

Делаем ресайз изображения для объявлений.

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

Создаем новые объявления.

Осталось прописать правило, чтобы приложение ежедневно проверяло и обновляло креативы. Подобные скрипты во многом удобней сторонних систем автоматизации, таких как Marin или R-broker, по нескольким причинам:

  • позволяет так же работать хоть с 1000 кампаний;
  • не нужно платить за дорогие сторонние решения;
  • приложение можно гибко настроить под любые свои задачи;
  • быстрота и легкость интеграции.
3 февраля   API   Vkontakte

Разбивка по регионам через Adwords API

У нас одна кампания в Adwords.

Ее нужно разбить на:

  • все регионы России,
  • поиск и контекстно-медийную сеть.

Смотрим документацию Adwords для разработчиков:

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

К счастью, у Google есть все местоположения в виде csv-файла. Читаем первые 5 строк:

Оставляем регионы России.

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

Проверяем в интерфейсе.

172 кампании.

26 января   Adwords   API

Daily revenue, DAU, MAU и карты Шухарта

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

Рассчитаем какую-нибудь метрику, например, доход по дням (daily revenue).

Посмотрим исторические данные, чтобы проследить общий тренд. Я построил график на основе скользящего среднего с 20-дневным окном и 3 стандартными отклонениями вверх и вниз.

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

Здесь нам помогут контрольные карты Шухарта.

  • Смотрим ГОСТ.
  • Находим контрольные карты индивидуальный значений, без заданных стандартных значений.
  • Рассчитываем верхнюю и нижнюю контрольную границу для скользящего среднего (n = 2).
  • Строим график.

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

С помощью карт Шухарта желательно анализировать все отчеты и графики из AppMetrica, Tune или Google Analytics. Они показывают, как работать с колебаниями — считать ли их допустимым, вмешиваться на уровне системных интервенций или частных случаев.

А представим, что хотим измерять:

  • DAU, WAU, MAU.
  • ARPPU.
  • Дневной доход, недельный, месячный.
  • Retention 2-го, 7-го, 21-го дня.

А также:

  • Показы.
  • Клики.
  • Установки.
  • Регистрации.
  • Покупки.
  • Расход.

Добавим еще разбивку по 10 регионам и каналам рекламы.

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

Часть кода для отправки письма.

Письмо.

Reengagement в динамике

Предположим, что сегодня 31.07.2008 г. Мы ведем рекламную кампанию на Facebook. Нам нужно создать кампанию реактивации клиентов, совершивших последнюю покупку 30 дней назад. Для этого потребуются пользовательские аудитории (custom audience).

Нужно ежедневно:

  • делать выборки клиентов из базы,
  • обновлять аудиторию рекламной кампании.

Динамически это возможно только через API. Автоматизируем процесс, пишем простое приложение.

Смотрим на базу наших покупателей (первые 5 строк).

Оставляем только тех, кто сделал последнюю покупку ровно 30 дней назад.

Создаем аудиторию для Facebook.

Добавляем идентификаторы покупателей и проверяем.

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

В итоге:

  • очень точный таргетинг на пользователей, которые только начинают «отваливаться»,
  • максимальный ROI,
  • значительная экономия времени.
2017   API   Facebook   reengagement

Acquisition, ROAS и LTV

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

Исходные данные:

  • Платформа для рекламы: Facebook.
  • Платформа аналитики: Tune.
  • Дата: 04.01.2016.
  • Таргетинг по устройствам: iOS.
  • Тестовые таргетинги: новые регионы или интересы, один на группу объявлений.

Через две недели выгружаем три отчета (модельные данные).
Отчет по расходам из Facebook (здесь и далее первые 5 строк):

Логи установок из Tune:

Логи событий из Tune.

Здесь отчеты в формате csv.

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

Я буду пользоваться библиотекой Pandas для python, а корректировать ставки через API.

Приводим отчеты к единому виду. В отчете по установкам меняем название столбца «Datetime» на «Install datetime».

В отчете по событиям оставляем только покупки.

В отчете Facebook переименовываем столбец «Date» на «Datetime», «Adset» на «Partner adgroup». Facebook показывает ставки в копейках, переводим в рубли и округляем.

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

Рассчитываем LTV для каждого клиента. Допустим, наш аналитик уже это сделал с помощью бесконечно убывающей геометрической прогрессии и построил такую кривую. (Скриншот из лекции А. Аникина.)

Мы знаем, что за две недели клиент приносит 6% от своего LTV. Рассчитываем LTV для каждого клиента:

  • делим доход на 6%,
  • добавляем значение в таблицу.

Суммируем доход по группам объявлений. Рассчитываем прибыль и ROAS (прогнозируемый доход / расходы). Его удобнее использовать для корректировки ставок: в отличие от ROI, он неотрицательный.

Мы видим, что две группы не окупаются.

Но предположим, что у нас не 7 групп, а 60. Нам поможет такой отчет.

Из него ясно, что 28% наших рекламных кампаний (2 из 7) не окупаются.

А сколько мы всего вложили и получим обратно?

Вложенный капитал окупится на 26%.

Мы увидели картину в целом и рассчитали окупаемость каждой группы объявлений. Наш целевой ROAS — 200% или 2. Максимальная ставка = (прибыль за конверсию / целевой ROAS) * (коэффициент конверсии). Корректируем ставки:

Обновляем через API.

И давайте посмотрим на воронку. Создаем новый агрегированный отчет из трех.

Смотрим на изменения в процентах.

Самые узкие места — между показами и переходами, а также переходами и установками. На этих данных они и так заметны, но в других воронках узкие места иногда расположены внизу. Именно изменения в процента позволяют их заметить.

В дальнейшем не нужно каждый раз это делать руками, особенно если у вас 1000 кампаний. Приложение может само пересчитывать LTV и корректировать ставки ежедневно или ежечасно. Подправьте код и поручите роботу:

  • собирать логи в базу данных на компьютере,
  • пересчитывать LTV на основе формулы, а не фиксированного значения,
  • корректировать ставки.
2017   Acquisition   API   Facebook