Redes neurais para otimização de landing page

Levando o teste A / B a um novo nível com aprendizado por reforço.

AI procurando a versão ideal da página de destino

Por que e como?

Eu gostaria de compartilhar alguns dos meus experimentos com redes neurais adaptadas para fazer otimização multiparamétrica de páginas de destino. Eu estive pensando sobre essa ideia por meio ano e achei extremamente interessante do ponto de vista da automação. O teste A / B exige muito tempo dos especialistas de marketing e eles exigem grandes quantidades de tráfego para um bom desempenho. Isso se torna bastante problemático quando uma equipe pequena gerencia as páginas de destino dos lotes e, para alguns projetos, também trata do “envelhecimento” das páginas de destino – elas podem se tornar obsoletas devido ao fim das promoções ou ofertas.

Há muitas maneiras de abordar esse problema. Os MVTs antigos (testes multivariativos), conforme concluídos no Google Optimize, dividirão o tráfego entre todas as versões possíveis de sua página de destino. E isso é bom se você tiver 3 variações para testar. Mas imagine sua maneira de testar 3 títulos, 3 legendas, 2 cores de botões e 2 imagens de cabeçalho, além de algumas versões do layout geral. Isso vai para 10k + combinações exclusivas. Como você tem 50k de tráfego estimado e o objetivo é encontrar a versão ideal ou próxima do ideal o mais rápido possível. Você sacrifica precisão estatística pura e tentar alcançar o máximo de conversões, como você pode jejuar.

Estou ciente de algumas abordagens possíveis. Primeiro, é pensar em diferentes recursos, pois eles são entidades independentes e imaginem que você está fazendo um teste de número A / B separado. Dessa forma, você alcançará alguns resultados bastante rápidos, mas se houver alguma correlação entre os vários itens, você sentirá falta deles e sua solução não será ideal. Em segundo lugar, usar algorytms genéticos. Existem algumas empresas fazendo isso – ? Ascendente Senciente por exemplo. De seus materiais promocionais, parece que eles usam algum tipo de algoritmo genético. Terceiro é usar a teoria de bandidos multiarmados . Uma das maneiras de resolver o problema do bandido multiarmado é usar aprendizado por reforço e redes neurais.

Vamos começar com uma breve visão geral.

Algoritmos Genéticos

Algoritmos genéticos estão imitando o processo de seleção natural. Pense em diferentes variações de páginas da Web como traços de um ser vivo – alguns ajudarão a sobreviver, alguns são neutros e outros terão impacto negativo. O fluxo de trabalho básico do algoritmo genético se parece com isso:

  • Gerar um número (digamos 100) diferentes descendentes tendo conjuntos aleatórios de características (100 páginas de destino com várias versões de recursos)
  • Deixe o tráfego fluir para eles e medir a taxa de conversão (sobrevivência em termos de evolução).
  • Calcular o chamado Fitness Score – o desempenho de cada página
  • Pegue as 20 melhores páginas de melhor desempenho, extraia seus recursos e misture-os de uma nova maneira. Em seguida, adicione à mistura alguns dos recursos das 20 páginas de pior desempenho e adicione um pouco à mixagem. Pode haver “mutações” raras escondidas por outras características, é bom para a diversidade. Gere novas 100 páginas com base nesses recursos.
  • Repita n vezes -> lucro.

Enquanto este sistema parece bom eu encontrei algumas coisas que eu não gosto sobre isso.

  • Ainda requer muito tráfego
  • É lento em mudanças quando o perfil do usuário / características mudam durante o teste (novos canais de aquisição aparecem)
  • Não está levando em conta o perfil do usuário (hora do dia, navegador, dispositivo, etc)
  • Não está usando redes neurais 😉

Então, decidi construir algo estilo 2018 com alimentação NN. Eu fiz um acordo com alguns caras suspeitos que fazem marketing CPA: eu vou construir um sistema e eles vão me dar tráfego para testá-lo. Vantajoso para as duas partes. O CPA é um caso de uso perfeito para esse tipo de sistema.

Estágio de pesquisa

O que eu precisava fazer era resolver o chamado problema dos “bandidos multiarmados” usando redes neurais. Há poucas outras grandes introduções no aprendizado de reforço, que eu estudei e você pode encontrar links na parte inferior. Eu reduzi esse projeto a alguns estágios, da mesma maneira que um problema de bandidos multiarmados evolui.

  • Estágio 0. Há um bandido de cassino com poucos braços. Um bandido multi-armado, onde cada braço (diferentes características do site) tem uma probabilidade ligeiramente diferente de pagamento (taxa de CTR). Você precisa criar um sistema que encontre o braço de melhor desempenho com o menor número de tentativas e, em seguida, mantenha sempre esse braço (mostrando essa versão do site). Tenha em mente que, devido à natureza probabilística desse problema, sempre há uma chance de que sua solução esteja errada. Mas no mundo real, é sempre bom quando ganha mais dinheiro.
  • Estágio 1. Aqui vem o usuário. Há muitos bandidos multi-armados que ficam no cassino. Usuários diferentes vão jogar bandidos diferentes, e o sistema tem que descobrir qual usuário deve tocar o bandido. A analogia da página de destino significa que diferentes usuários reagem de maneira diferente à sua página de destino, portanto, é necessário mostrar a cada usuário uma página diferente, com base nas características do usuário.
  • Estágio 2. Aí vem o momento. Há muitos quartos com muitos bandidos com muitas mãos e você tem que passar por cada quarto e um dos bandidos em cada quarto. E sua probabilidade de pagamento depende de todos os seus desempenhos em cada sala. Esta é uma versão completa de um problema, quando você tem processo de vendas em várias etapas – pré-pouso, pouso, email marketing, por exemplo.

Compartilharei minhas ideias sobre a implementação do problema do estágio 0.

Por que apenas o estágio 0?

Meus sentimentos internos eram excessivamente otimistas quanto aos volumes de tráfego necessários para resolver cada etapa. Meus caras do CPA concordaram em trafegar de 10 a 20k em uma landing page para testar minhas ideias, e achei que seria suficiente testar a otimização do Estágio 0 + Estágio 1, mas a matemática era contra mim. Isso exigiria uma ordem de magnitude mais tráfego para o Estágio 1, IMHO. Pode ser menor depois que o sistema é ajustado e estudado.

Resultados da última execução

Aqui eu descreverei os resultados da última execução do sistema em produção e algumas percepções obtidas. Abaixo, você encontrará alguns códigos e detalhes de implementação para pessoas com conhecimento de tecnologia.

Então, lançamos um teste de divisão 50/50. 50% estava indo para uma landing page estática e 50% estava indo para uma landing page dinâmica movida por um motor neural. Após os primeiros 3 a 4 dias, notei que a minha solução neural atingiu a variação (mínimos locais) de que tinha certeza e não ia mudar (com base na perda e nos pesos). Isso aconteceu depois de cerca de 3-4k no trânsito.

Fiquei curioso para ver se conseguiria a mesma variação com base na estatística pura dos dados. Calculei a CTR média para cada variação, os melhores candidatos e comparados com as variantes sugeridas por ML. Para minha grande surpresa, aqueles eram 80% diferentes! NN estava sugerindo uma versão totalmente diferente. Interessante…

OK então. A rede neural deveria ser mais inteligente do que simples álgebra linear e eu, pensei. Para comprovar minhas descobertas, parei de aprender sobre rede neural e fiz uma comparação direta de três versões:

  • 100% de variações aleatórias
  • Versão estática, que foi proposta usando comparações simples de desempenho de recursos (obtenha o melhor desempenho para cada recurso e combine-os na página de destino)
  • Versão estática sugerida pela rede neural

Como você pode ver, esperei até que a diferença se tornasse estatisticamente significativa entre escolhas aleatórias e não aleatórias. Então, aqui estão os principais tópicos:

  • Sistema baseado em rede neural executou o mesmo que estatísticas simples baseadas em P
  • As variações sugeridas pelas estatísticas e pelo sistema NN foram 80% diferentes. Isso pode significar que eu coletei dados não suficientes para separar o desempenho de ambos.
  • Há uma chance de que as páginas de destino com melhor desempenho sejam mais do que uma soma dos recursos de melhor desempenho e que haja correlações de segunda ordem.
  • Precisamos de mais dados.

Construindo o sistema

Depois de algumas escavações, decidi que o meu problema é um típico aprendizado de reforço “AI”. Novamente, há um ótimo curso, eu vou encaminhá-lo no fundo e eu usei muito. Eu queria que meu código fosse executado em produção e o Tensorflow é uma estrutura para escolher isso. No meu trabalho diário eu prefiro o MXNet, dê uma olhada nele também. Está quase pronto para produção.

Rede neural

Eu usei uma rede totalmente conectada de duas camadas simples, tendo uma variável estática como uma entrada e produzindo probabilidades para cada recurso para uma página de entrada como saída. É muito fácil modificar o sistema do Estágio 1 se uma entrada não for estática, mas é uma variável, dependendo dos recursos do usuário (tempo, geolocalização, idioma etc.).

 tamanho = [3,2,3,3] 
 self.DummyState = tf.Variable ([[0.1]]) 

 output = slim.fully_connected (self.DummyState, a_size,  
 biases_initializer = Nenhum, weights_initializer = tf.ones_initializer ()) 

 self.res = [tf.squeeze (slim.fully_connected (saída, x,  
 biases_initializer = Nenhum,  
 activation_fn = tf.nn.sigmoid, 
 weights_initializer = tf.ones_initializer (), 
 escopo = 'resultados' + str (i))) 
 para i, x em enumerar (tamanho)]

Esta é uma rede que usei. A variável tamanho representa o número de recursos que foram testados e um número de variações de cada recurso.

Produção em execução

Para executar o sistema em produção, usei o backend Sanic, o Postgres como um armazenamento SQL e o Tensorflow como um mecanismo de inferência. A aprendizagem do sistema foi realizada ao vivo no servidor.

Para cada visita ao site, pedimos ao sistema de backend por resultados de inferência e variatons da página para mostrar para este usuário, foi cerca de 30 ms de atraso. Após a conversão, foi correspondido com a versão do usuário da página.

Eu usei 15 minutos de atraso após a visita (com janela de conversão típica de 5 minutos) para decidir se a visita foi bem-sucedida ou não, então essa visita foi usada para executar uma etapa do treinamento da rede neural. Durante o período de testes, eu estava decaindo o fator exploração x exploração. Inicialmente, a página de destino era 100% gerada aleatoriamente e a proporção diária de aconselhamento aleatório versus rede neural decaiu até atingir 0 em 10 dias.

Alguns truques

Para construir o sistema, eu precisava de algum tipo de ambiente de teste virtual, então criei um script simples que emulava visitas ao site e conversões. A base deste processo era gerar probabilidades “ocultas” da taxa de conversão para cada variação da página de destino. Inicialmente, eu postulei que cada combinação única de recursos terá sua própria CTR e todos os recursos são totalmente dependentes uns dos outros. Essa foi uma abordagem fracassada e a rede muitas vezes não conseguiu encontrar a solução ideal com uma quantidade significativa de tráfego. Como eu entendi que não é um cenário real, não há muita correlação entre o texto do título e a cor dos três rolos abaixo.

 self.bandits = [np.random.random (* size)]

Então decidi simplificar o ambiente e decidi que os recursos são todos linearmente independentes. Isso é uma simplificação excessiva, mas foi o suficiente para ajustar os hiperparâmetros e garantir que o sistema encontre a solução correta.

 self.bandits = [np.random.random (x) /50+0.95 para x em tamanho]

Tornar certo o ambiente “oculto” aqui é um ótimo ajuste do sistema e requer alguns passos extras.

Algum código

Estou compartilhando com o script do playground que eu usei para encontrar hyperparameters e testar a parte do NN em geral.

Obrigado por dar uma olhada, não hesite em fazer perguntas, contacte-me em savsunenko.sasha@gmail.com

Lista de leitura

Aprendizado Simples de Reforço com Tensorflow Parte 0: Q-Learning com Tabelas e Redes Neurais
Para este tutorial da série Aprendizagem por Reforço, vamos explorar uma família de algoritmos de RL chamados… medium.com
Resolvendo o Problema do Bandido Multi-Armado
O problema do bandido multi-armado é um exemplo clássico de aprendizado de reforço, onde nos é dada uma máquina caça-níqueis com n… direçãodatascience.com
Bandidos Multi-Armado e Aprendizagem por Reforço 1 – DataHubbs
Um problema de bandidos multi-armados serve como uma ótima introdução ao aprendizado por reforço. Descubra o que eles são e… www.datahubbs.com