Как с помощью Data Frame Pandas и programmatic увеличить LTV

  • Автор: Елизавета Жук

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

Фокус в том, что с постоянными покупателями работать гораздо проще и дешевле: их не нужно знакомить с продуктом и завоевывать доверие. Они уже знают о преимуществах бренда, качестве продуктов и более склонны к новым покупкам. По данным исследования, текущие покупатели купят новый товар с вероятностью 60-70%, а вероятность покупки среди новой аудитории всего 5-20%.

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

В этой статье рассказываем, как мы приблизились к повышению LTV с помощью DataFrame Pandas и данных клиентов о покупках.

С чего все началось?

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

Хотя кампании показывали хорошие результаты, мы постоянно ищем решения, которые помогут увеличить performance-показатели.  Поэтому решили протестировать гипотезу, которая может повлиять на эффективность.

Целевая аудитория клиента — родители, которым нужно часто обновлять гардероб ребенка из-за его постоянного роста и развития. Показать рекламу следующего размера через какое-то время — недостаточно. Это может быть просто не актуально — покупка новой пары обуви зависит от скорости роста стопы, а в разном возрасте она отличается. Например, детям от 4 до 8 лет обувь обновляют в среднем 2-3 раза в год, а к подростковому возрасту рост ноги замедляется и новый размер ботинок покупается реже. Команда NT задалась вопросом: “А что если узнать период между повторными покупками, сегментировать аудиторию на основе этих данных и показать персонализированный креатив с напоминаем о покупке следующего размера?”

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

1 этап: собираем данные

Основа исследования — сырые данные, записи об отдельных визитах или просмотрах. Таблица с этими записями передается через Logs API Яндекс.Метрики, при этом каждая запись дополняется полезными сведениями (информация из электронной коммерции, технические сведения о визите и не только).

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

После этого подготовили post-запрос, который создает лог — отчет, в котором будет нужная нам информация. Структура выглядит так:

  • Counter — идентификатор счетчика Яндекс.Метрики клиента;
  • date1 — дата начала отчетного периода в формате;
  • date2 — дата конца отчетного периода;
  • fields — список полей, которые надо получить; 
  • f будущий файл csv, который мы будем скачивать.

Поля — это те параметры визитов, которые Метрика выгрузит из базы данных и предоставит нам в виде файла в формате CSV. Нас интересовало получение следующей информации:

  • PurchaseID;
  • VisitID;
  • ClientID;
  • PurchaseDateTime — дата и время покупки;
  • ProductsName — название покупки;
  • ProductsCategory — какой категории покупка;
  • ProductsQuantity — количество покупок.

Следующий шаг — написать get-запрос, чтобы скачать подготовленный лог. Он выглядит так:

Параметры запроса:

  • CounterId — идентификатор счетчика;
  • partNumber — номер части подготовленных логов обработанного запроса;
  • requestId — идентификатор запроса логов;
  • part 0/1 — порядковый номер той части лога, которую нужно скачать;
  • f будущий файл csv, который мы будем скачивать.

Логи в Яндекс.Метрике состоят из двух частей. Первую часть мы сохраняем в file0, а вторую — в file1. Затем создаем пустой csv файл с помощью конструкции “with open(“part.csv”, “w”) as f”, а с помощью команд “f.write(file0)” и “f.write(file1)” записываем данные из двух частей логов в наш дата фрейм и скачиваем его.

2 этап: обработка данных

На предыдущем этапе мы получили список с нужной информацией. Чтобы привести данные в удобный для анализа вид, мы создали data frame (df). Это высокоуровневая структура данных, которые организованных в строках и столбцах. В строках дата фрейма могут быть списки. Чтобы разбить такие списки на строки, использовали функцию explode — она предназначена для преобразования столбцов со вложенными списками в отдельные строки с повторением значений в других столбцах. Это помогает упростить структуру для дальнейшего анализа. Структура кода выглядит так:

Продолжая работать с агрегированными данными мы:

  • Преобразовали столбец “Размер” в числовой формат. После конвертации одного формата в другой, могут возникать ошибки. Поэтому с помощью параметра “errors=’coerce’” нашли такие ячейки и поставили вместо некорректного значения пустое.
  • Чтобы удалить строки с пустыми значениями, использовали метод dropna. С помощью параметра “how=’any’” указали методу удалять строки, где хотя бы один элемент пустой.

В массивах и списках элементы часто упорядочены по порядковому номеру, который называется индексом. В строках также каждый элемент имеет свой индекс. После удаления строк в data frame индексы могут быть разрозненны. Чтобы этого избежать, мы сбросили индексы строк и создали новые с помощью команды  “final_data. reset_index(drop=True)”.

С помощью функции lambda в столбце “purchaseDateTime” оставили первое дату и время покупки, если было их несколько. Следующим шагом с помощью dt.date преобразовали значения в этом столбце в объекты типа date, оставив только информацию о дате покупке, исключив время. С помощью final_data = final_data[final_data[‘size’] <= 45] применили команду фильтрации и оставили в таблице только те строки, где значения размера обуви не превышают 45.

3 этап: проверка данных

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

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

С помощью функции sns.boxplot(final_data[‘size] создали “ящик с усами” для столбца с размером обуви. Чтобы отобразить диаграмму, использовали команду plt.show().Вот, что у нас получилось:

Для создания гистограммы распределения значений столбца “Размер обуви” , использовали функцию plt.hist. С помощью аргументов final_data[‘size’] и bins=20, обозначили для какого столбца нужен график и задали количество интервалов — 20. Для отображения гистограммы использовали plt.show(). Структура кода и гистограмма выглядят так:

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

4 этап: уточняем данные о покупке

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

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

В нашем коде мы сгруппировали данные по столбцам “ClientID” и “Size”. После этого с помощью “agg” применили агрегационные функции к каждой группе данных (агрегационные функции — это функции, которые выполняют вычисления на наборе данных). Для столбца “PurchaseDateTime” использовали функции минимума (‘min’) и максимума (‘max’), а для столбца PurchaseID — count, чтобы посчитать количество записей в наборе данных. Таким образом, для каждой группы (‘clientID’, ‘size’) мы узнали дату первой и последней покупки и количество покупок.

С помощью кода “last_df = groupped.reset_index(drop=False)” сбросили индексы в файле со сгруппированными данными и создали новую табличку, куда перенесли всю информацию — last_df. Параметр “drop=False” указывает, что индексы не просто удаляются, а также переносятся в новый дата фрейм.

5 этап: узнаем разницу дней между первой и последней покупкой обуви

Структура кода этого этапа выглядит следующим образом:

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

В целом алгоритм действия на этом этапе выглядит  так:

  • 1-я строка кода: с помощью команды shift сдвигает дату на одну строку;
  • 2-я строка кода: находит разницу дат, т.е. количество дней до следующей покупки;
  • 3-я строка кода: сдвигает данные о размере;
  • 4-я строка кода: находит разницу размеров;
  • 5-я строка кода: сдвигает ClientID покупателя;
  • 6-я строка кода: ставит True если клиент прошлой строки и следующей одинаковый или False если разный.

Таким образом мы узнали через сколько дней клиенты покупали следующую пару обуви, а также разницу размеров между прошлой и новой покупкой. Чтобы визуально проверить результат в таблице применили функцию last_df.head(), чтобы отобразить часть файла:

6 этап: узнаем, кто покупал несколько пар обуви

Чтобы продолжить исследование нам нужно оставить данные, которые относятся к одному и тому же клиенту — то есть ClientID с пометкой “True” в таблице. При этом оставить в таблице только тех, кто купил детскую обувь следующего размера.

Эти данные уже есть в таблице, их нужно только “достать и упорядочить”. Идея состояла в том, чтобы отфильтровать данные по true/false для ClientID, разнице между размерами купленной обуви и датой следующей покупки. После этого удалить ненужную информацию. Это сделали с помощью этого кода:

Параметры фильтрации:

  • last_df[‘size_difference’] == 1 — код выберет только те строки, где значение в столбце “Size_Difference” (Разница между размерами обуви) равна 1, т.е. пользователь купил пару обуви на один размер больше;
  • last_df[‘difference’] > ‘0 days’ — код выберет строки, где разница между покупками больше 0 дней;
  • last_df[‘is_same_clientID’] == True — выбираются те строки, где в столбце с ID клиента есть пометка “True”, то есть следующую пару обуви приобрел один и тот же клиент.

Мы объединили условия фильтрации с помощью [(…)] и значка &. Если строки соответствуют всем условиям, они попадают в новый data frame — filtered. Получилась такая таблица:

7 этап: делаем расчеты

Следующий шаг — рассчитать медиану, минимальный и максимальный промежуток до следующей покупки. Это делали с помощью функции, которая считает интервалы. Функцию определили с помощью “def” — она берет на вход список с данными, рассчитывает взвешенное среднее, определяет промежутки между покупками новых пар обуви и вносит эти данные в табличку. Описанная функция выглядит так:

В первой части кода мы рассчитывали квартили. Квартили — числовые значения признака, которые делят упорядоченные по возрастанию данные на четыре равных части. Их всего три: первый (нижний), второй (средний) и третий (верхний). Нам они нужны для расчета медианы и промежутков между покупками.

  • order_q1 = np.quantile(lists,0.25) — вычисляет первый квартиль (Q1), ниже которого располагается 25% данных. 
  • order_q3 = np.quantile(lists, 0.75) — вычисляет третий квартиль (Q3), ниже которого располагается 75% данных. 
  • order_iqr = order_q3 – order_q1 — рассчитывает межквартильный диапазон (IQR), который охватывает центральные 50% данных.

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

  • left = np.average(lists) – abs((order_iqr – np.average(lists)) / 2) — вычисляет левую границу интервала, то есть минимальный промежуток между покупкой следующей пары обуви;
  • right = np.average(lists) + abs((order_iqr – np.average(lists)) / 2) — определяет правую границу диапазона, то есть максимальный промежуток между  покупкой следующего размера.

Все полученные значения записали в int_result — словарь результатов, — с помощью этого кусочка кода:

Команду “int_result[‘count’] = len(lists)” использовали, чтобы записать количество пар размеров обуви в исследовании.

8 этап: определяем значения для каждого размера

С помощью функции “groupby” данные сгруппировали по размеру обуви и к группе применили агрегационную функцию lamda — в нашем коде она применяет функцию, которую мы описали в предыдущем этапе, к каждому размеру обуви из группы. В результате, мы рассчитали минимальный и максимальный промежутки между покупкой новой пары обуви и медиану для каждого размера. Все данные занесли в таблицу:

Структура кода выглядит так:

9 этап: приводим в порядок, контрольно проверяем и скачиваем

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

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

  • Размер – размер обуви; 
  • Левая граница – приближенное к минимальному количеству дней до покупки следующего размера; 
  • Средняя граница – приближенное к среднему количеству дней до покупки следующего размера; 
  • Правая граница – приближенное к максимальному количеству дней до покупки следующего размера.

Что мы получили в итоге?

В результате исследования мы узнали окно атрибуции, через который родители покупают пару обуви следующего размера для своего ребенка в зависимости от его текущего размера стопы. Например, после покупки 22 размера обуви следующую пару купят в среднем через 67 дней. Также, по графику распределения количества итоговых наблюдений по размерам видно, что чаще всего в магазине покупают обувь 32, 34 и 35 размера. Следовательно, родители детей от 6 до 12 лет обновляют обувь чаще.

И зачем это знать?

Чтобы улучшить рекламные стратегии. Пока компании запускают рекламу в интернете, крутят по радио и ТВ, отправляют e-mail-рассылки и push-уведомления и даже по старинке закидывают буклеты в почтовые ящики, у пользователей выработался иммунитет к рекламе. Они почти не замечают баннеры, рекламные ролики скиппают и промо-посты в соцсетях пролистывают. Находит отклик только та реклама, которая попадает в запрос пользователя здесь и сейчас.

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

Источник: Statista

Исследование помогло закрыть эти вопросы. Учитывая полученные результаты, можно разработать account-based стратегию и показывать аудитории персонализированные сообщения. Идея в том, чтобы разбить аудиторию ремаркетинга на кастомные сегменты, разработать для каждого сегмента персонализированный креатив и показать его через определенный промежуток времени. При том сегменты аудитории и окно атрибуции выбираются на основе того, какой размер обуви приобрели родители последним, а рекламное сообщение — это напоминание, что пора купить пару большего размера. Например, для сегмента аудитории родителей, которые купили обувь 32 размера, рекламные креативы будут показаны через 50-68 дней.

Придерживаясь такой стратегии, можно взаимодействовать с покупателями магазина на протяжении всей их “жизни”: установить контакт, увеличить их количество и постоянно стимулировать конверсии, вовремя напоминая о необходимости покупки новой пары обуви. Это поможет увеличить LTV и ROI для бренда.

Заключение

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

Мы в NT — фанаты данных и технологий и верим, что они определяют результат, как и экспертиза команды. Поэтому вместе развиваем NT Programmatic платформу, постоянно экспериментируем и помогаем достичь даже самых сложных целей с помощью автоматизированной рекламы и комплексных решений. Напишите нам сегодня, мы поможем увеличить ваш доход с помощью рекламы.

Другие статьи

фрод в рекламе, мошенничество в цифровой рекламе
Блог
Фрод: что это значит в цифровой рекламе, методы определения и как с этим бороться
Читать
конверсия этапов воронки продаж, как правильно считать конверсии
Блог
Работа с конверсиями: какие есть типы и как правильно оценивать
Читать
нативная реклама в интернете, что такое нативная реклама, форматы нативной рекламы
Блог
Нативная реклама: что нужно знать?
Читать
мобильный маркетинг, реклама на мобильных устройствах
Блог
Мобильный маркетинг: разбираемся что это и как работает
Читать
dsp платформы на российском рынке, dsp в россии
Блог
DSP платформа: представители на российском рынке
Читать
разница между типами данных, что такое first party data, что такое second party data, что такое third party data
Блог
Отличия между 1st, 2nd, 3rd party data
Читать
что такое некачественный трафик
Блог
Некачественный трафик: что это такое и как с ним бороться
Читать
реклама на youtube
Блог
Реклама на YouTube: что нужно знать?
Читать
Что такое brandformance, что такое брендформанс
Блог
Гайд по brandformance-подходу для брендов
Читать
тренды электронной коммерции 2023, тренды e-commerce 2023 в россии
Блог
E-commerce 2023: курс на маркетплейсы, бережливость и покупки по акциям
Читать
Блог
Лучшие стратегии для рекламных кампаний
Читать
платформа клиентских данных, что такое платформа клиентских данных, платформа клиентских данных это, cdp это
Блог
Платформа клиентских данных (CDP)
Читать
аналитика мобильных приложений
Блог
Аналитика мобильных приложений
Читать
как подготовить рекламу к праздникам
Блог
Как стать Нео в digital: краткий гайд по подготовке рекламы к праздникам
Читать
узнаваемость бренда, как повысить узнаваемость бренда
Блог
Гайд по узнаваемости брендов: что это такое, почему так важно и как повысить узнаваемость компании
Читать
RTB и programmatic, RTB и programmatic в чем разница
Блог
RTB и programmatic: в чем разница?
Читать
отключение cookies, отключение cookie и как к нему подготовиться
Блог
Мир без cookie-файлов: как брендам усилить стратегии перед cookies-апокалипсисом
Читать
карта пути пользователя, cjm в маркетинге, cjm анализ, cjm путь клиента
Блог
Customer journey analytics & Customer Journey Map: что это и зачем применять
Читать
Блог
Автоматизация маркетинга и рекламы для брендов
Читать
как изменилась электронная коммерция в россии, российский рынок e-commerce в 2023, e-commerce в россии, как продвигатьcя в e-commerce
Блог
Новый мир e-commerce: как адаптировать рекламные стратегии к изменениям за 2022
Читать
Что такое медимикс-моделирование, моделирование медиамикса
Блог
Что делать, если медиамикс не работает? Использовать моделирование медиамикса и programmatic
Читать
post-view аналитика, отслеживание post-view конверсий
Блог
Post-view аналитика и как она работает
Читать
KPI в рекламе, метрики для интернет-рекламы
Блог
Устанавливаем правильные KPI: руководство к действию
Читать
аналитика в маркетинге, маркетингова аналитика что это такое, этапы маркетинговой аналитики
Блог
Аналитика в маркетинге: что это такое и почему это так важно
Читать
эффективность рекламы в tiktok, реклама в tiktok
Блог
Эффективность рекламы в TikTok
Читать
реклама на smarttv, что такое ctv, реклама на ctv, ctv реклама
Блог
CTV+OTT против кабельного TV
Читать
реклама в телеграм каналах, реклама в telegramреклама в телеграм каналах, реклама в telegram
Блог
Реклама в Telegram: что это такое и почему ее стоит включить в медиамикс
Читать
форматы рекламы в tiktok
Блог
Форматы рекламы в TikTok
Читать
как определить целевую аудиторию бренда
Блог
Целевая аудитория: что это такое и зачем она нужна
Читать
медийная реклама в интернете, форматы медийной рекламы,эффективность медийной рекламы
Блог
Подробно о медийной digital-рекламе: форматы и преимущества
Читать
Блог
Видеореклама для брендов: что это такое, форматы и эффективность
Читать
что такое поисковая реклама, реклама на поиске что такое
Блог
Поисковая реклама: что это такое и как programmatic помогает платному поиску
Читать
цифровая наружная реклама, цифровая наружная реклама dooh, dooh реклама
Блог
Цифровая наружная реклама: разбираемся что это такое и как работает
Читать
топ ошибок в рекламной кампании, антикейсы рекламы
Блог
Антикейсы рекламных кампаний: топ популярных ошибок в рекламе
Читать
Как рекламировать доставку еды, как продвигать сервис доставки еды и продуктов, реклама e-grocery
Блог
E-grocery и доставка: все, что вам нужно знать о рекламе доставки продуктов
Читать
Реклама на промостраницах яндекса, что такое промостраницы, эффективность рекламы на промостраницах яндекса
Блог
Реклама на ПромоСтраницах Яндекса: что это такое и как сделать ее еще эффективнее
Читать
модели атрибуции, какую модель атрибуции выбрать, модели атрибуции конверсий
Блог
Сравнение моделей атрибуции. Часть первая: first-click, last-click и data-driven
Читать
Блог
Как рекламировать лекарства онлайн с учетом поведения пользователей
Читать
методы сбора данных об интернет-пользователях
Блог
Методы сбора данных об интернет-пользователях
Читать
DMP платформа, платформа данных, представители DMP в россии
Блог
Представители DMP-платформ на российском рынке
Читать
как работают программатик закупки, programmatic закупки
Блог
Пора разобраться: как осуществляются программатик закупки?
Читать
реклама в приложениях, in-app реклама для бизнеса
Блог
In-app реклама — тренд 2021
Читать
Как повысить эффективность рекламы с помощью данных, влияние данных на эффективность рекламы
Блог
Как с помощью Data Frame Pandas и programmatic увеличить LTV
Читать
форматы мобильной рекламы, реклама на смартфонах форматы рекламы
Блог
Какие размеры и форматы мобильной рекламы приносят наибольший доход?
Читать
Контакты
Мы знаем, где ваши клиенты. Хотите, покажем им вашу рекламу?

    Имя и фамилия*

    Компания или URL-адрес сайта

    Номер телефона

    Ваше сообщение

    Этот сайт защищен reCAPTCHA и Google 
    Принять политику конфиденциальности и условия использования.