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

Мы в Incentro думали, что должен быть более разумный способ решения этой проблемы. Так и есть. В этом блоге я расскажу вам о нашем стремлении создать индивидуальную модель машинного обучения, которая поможет голландскому стартапу более умно перенацеливать клиентов. Если вы не разбираетесь в технических вопросах, не бойтесь! Я буду держать вас в курсе, но это поможет, если у вас есть хотя бы некоторые базовые знания о машинном обучении.

tl; dr: ретаргетинг на основе машинного обучения привел к увеличению конверсий на 100%!

обо всем по порядку: кейс.

Это было настоящей проблемой для реального клиента Incentro: vakanties.nl. Vakanties.nl - это голландский стартап, который продает динамично составленные пакетные каникулы, адаптированные к потребностям клиентов. Им было сложно понять, как точно потратить свой маркетинговый бюджет; они хотели перенацелить клиентов с наибольшей вероятностью конверсии. До этого момента их стратегия заключалась в перенацеливании клиентов, которые нажимали на определенные кнопки на веб-сайте. Хотя человеческая интуиция подсказывает, что нажатие на кнопку, вероятно, означает, что вы больше заинтересованы в продукте, это не само собой разумеющееся. Могут быть и другие вещи, которые более точно указывают на готовность человека покупать, например, время, которое кто-то провел на странице, или время суток. Проблема в том, что эти шаблоны трудно найти людям, потому что люди не умеют анализировать миллионы строк журнала веб-сайтов, чтобы найти причинно-следственные связи. Войдите в чудесный мир машинного обучения 🌞

Наша задача заключалась в том, чтобы для каждого человека, посетившего веб-сайт и не купившего отпуск, оценить вероятность того, что клиент купит отпуск, если он вернется на веб-сайт. Это нетривиальная задача (иначе я бы не стал писать об этом в блоге прямо сейчас). Как мы это сделали? Все сводится к тому, чтобы принять во внимание все шаги, которые посетитель сайта предпринял на сайте vakanties.nl. Я объясню вам, что именно мы сделали, но сначала немного о рекуррентных нейронных сетях.

интермеццо: повторяющиеся нейронные сети

Если вы не инженер по машинному обучению, скорее всего, вы никогда не слышали о повторяющихся нейронных сетях (RNN). Рекуррентные нейронные сети - это не обычная обычная нейронная сеть. Чтобы проиллюстрировать это, сделайте следующий рисунок, изображающий «обычную» глубокую нейронную сеть. Если у вас есть опыт работы с машинным обучением, это изображение, вероятно, покажется вам знакомым.

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

Начнем с выходного слоя. Есть два узла, представляющих вероятность того, что посетитель веб-сайта не совершит конверсию, и вероятность того, что посетитель веб-сайта действительно совершит конверсию. Эти вероятности, конечно, в сумме составляют 1, поскольку в этом мире конверсий веб-сайтов нет альтернативы. Все идет нормально. Однако каков наш вклад? Количество кликов? Общее количество времени, проведенного на сайте? Все допустимые особенности модели машинного обучения, но одна вещь, которую обычная нейронная сеть не может сделать, - это уловить понятие времени. Например, нет простого способа передать в эту примерную нейронную сеть, что посетитель веб-сайта сначала отфильтровал результаты поиска на vakanties.nl по датам, затем по стране, а затем отфильтровал по конкретным отелям. Но это может быть ценная информация, о которой вы хотите, чтобы нейронная сеть знала. Еще один способ, который мы могли бы попробовать, - это вводить в модель каждый этап путешествия посетителей веб-сайта, но обычная нейронная сеть не может представить эти отдельные фрагменты информации как одно путешествие клиента.

К счастью для нас, в 80-е годы несколько выдающихся людей нашли решение этой проблемы в виде повторяющихся нейронных сетей.

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

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

Здесь x представляет входной узел, синий блок, обозначенный h, - это скрытый узел, а красный кружок, обозначенный o, - выходной узел. Как вы можете видеть, вместо информации, проходящей прямо из входных-скрытых узлов-выходов, скрытый слой передает информацию обо всем, что он видел до сих пор, обратно самому себе. Это означает, что при прогнозировании RNN может учитывать всю историю пути клиента! 👏👏👏👏👏

(примечание: существует множество различных разновидностей RNN. Как бы мне ни хотелось рассказать вам о них, вероятно, сейчас не время и не место 😢. Если вы хотите узнать больше, this - отличный вариант. место для старта!)

пусть начнется программирование.

Итак, теперь, когда мы выяснили, что рекуррентные нейронные сети, вероятно, лучший способ пойти, самая легкая часть нашей работы была сделана (решить, что нам делать). Теперь нам действительно пришлось это сделать.

Это странный случай в том смысле, что у нас действительно не было никаких данных о типах клиентов, на которых следует выполнить ретаргетинг: клиенты, которые были на веб-сайте и ушли, но затем вернулись и преобразовались. Итак, мы решили подойти к этому немного иначе. В конце концов, последний шаг клиента (назовем этого клиента A), на которого мы можем захотеть перенацелить, всегда покидать веб-сайт до конверсии (потому что, если бы он совершил преобразование , нам бы не пришлось перенацеливать их). Последним шагом посетителя, который совершил конверсию (назовем этого клиента Б), всегда является конверсия. Мы не включаем этот последний шаг клиента B в обучение модели, потому что, если мы хотим спрогнозировать вероятность конверсии клиента A, путь клиента A никогда не включает последний шаг клиента B (шаг конверсии). .

Основное предположение, которое мы делаем, заключается в следующем: если покупатели X и Y покидают веб-сайт, а покупатель X имел более высокую вероятность конверсии в момент перед уходом с веб-сайта, чем покупатель Y, то покупатель X по-прежнему имеет более высокую вероятность того, что преобразование после ухода с сайта.

входные характеристики и архитектура модели.

Кажется логичным, что, вероятно, существует положительная корреляция между количеством кликов, сделанных клиентом на веб-сайте, и тем, совершил ли клиент конверсию или нет. Чтобы убедиться, что модель не позволяет слепо прогнозировать конверсию клиентов с более длинными сеансами, основываясь только на длине пути, мы воспроизводим поездки клиентов, которые совершили конверсию четыре раза. Итак, если клиент, совершивший конверсию, сделал сорок кликов, модель может увидеть одно и то же путешествие во время обучения четыре раза: один раз с десятью щелчками, один раз с первыми двадцатью щелчками, один раз с первыми тридцатью щелчками и один раз с все клики (все с пометкой "преобразовано"). Это также пригодилось, потому что у нас было гораздо больше покупательских путешествий, когда клиенты не конвертировали, чем конвертировали. Используя эту технику, мы решили часть дисбаланса между появлением меток преобразованных / не преобразованных.

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

У нас было два типа функций; функции, относящиеся к одному этапу цикла взаимодействия с клиентом (например, кнопка, на которую щелкнул клиент, время нажатия) и контекстные функции, применимые ко всему циклу взаимодействия с клиентом (например, тип устройства, которое использует клиент, и через какой канал клиент зашел на сайт). Проблема с RNN заключается в том, что они менее опытны в представлении этих контекстных функций, поэтому мы решили использовать лучшее из обоих миров: гибридную модель RNN и DNN 😎 См. Архитектуру нашей модели ниже:

построение модели.

Когда мы разрабатывали модель (начало 2019 года), не было готовых моделей, подходящих для этого варианта использования, поэтому мы решили создать собственную модель в TensorFlow 1.14 (на Python), используя tf. Estimator.estimator класс. Это было легче сказать, чем сделать, и мы провели много-много дней, глядя на экраны наших компьютеров в полном отчаянии. Извлеченный урок: вы сэкономите много времени и нервов, если найдете готовую модель машинного обучения, подходящую для вашего варианта использования.

Я собираюсь показать вам небольшой фрагмент кода (НЕ БУТЬСЯ), чтобы показать вам, насколько (относительно) просты основные строительные блоки модели. Следующий фрагмент кода обозначает нашу модель, состоящую из одного уровня GRU (определенный тип ячейки RNN) со слоем DNN:

def rnn1_model(features, mode):
    cell = tf.nn.rnn_cell.GRUCell(RNN1_SIZE)
    outputs, state = tf.nn.dynamic_rnn(cell, tf.stack(seq_features, axis=2), dtype=tf.float32)
if len(ctx_features) == 0:
        x_dnn = state
    else:
        listed = [state, tf.stack(ctx_features, axis=1)]
        x_dnn = tf.concat(values=listed, axis=1)
    probabilities = tf.layers.dense(x_dnn, 1, activation=tf.sigmoid)
return probabilities

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

модель учится !!! или это так?

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

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

  • у нас не было нужного набора гиперпараметров для РНС. Мы временно отказались от DNN и сначала выполнили настройку гиперпараметров для RNN. После этого мы добавили DNN обратно в модель.
  • мы увеличили размер пакета: мы сделали это, потому что предположили, что градиент функции потерь был очень резким из-за относительно небольшого количества «сходящихся» меток. Увеличение размера пакета до значения 2048 или 4096 запустило поведение сходимости.
  • нам нужно было запастись терпением. Одной эпохи было недостаточно, чтобы избежать исчезающих градиентов. Вместо этого нам пришлось проводить обучение для нескольких эпох.

Все это привело к сближению модели, и у нас НАКОНЕЦ-ТО была модель, готовая к работе!

полная архитектура

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

Итак, вся архитектура такова: когда клиент посещает сайт vakanties.nl, события с помощью облачного pub / sub и потока данных отправляются в BigQuery. Затем, снова через Dataflow, мы извлекли данные из BigQuery и преобразовали их в формат, который использовался в качестве входных данных для модели машинного обучения (TF-записи), и они были сохранены в облачном хранилище. Затем модель считывает данные из облачного хранилища для обучения, а обученная модель экспортируется обратно в облачное хранилище, откуда модель экспортируется в Cloud ML Engine (теперь переименованный в AI Platform). Каждый раз, когда клиент покидает веб-сайт, он отправляется в развернутую модель, и модель выводит вероятность того, что клиент совершит конверсию!

полученные результаты

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

  • благодаря ретаргетингу на основе машинного обучения количество конверсий выросло на 100% 😎
  • затраты на транзакцию снизились на 50–100% по сравнению с ситуацией без модели машинного обучения и использования умных списков ремаркетинга.
  • затраты на приобретение снизились на 50%

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

Что ж, на сегодня все! Надеюсь, вам это показалось интересным, и если у вас есть вопросы, вы знаете, где меня найти. 🙋