Codelab de otimização de compras no app em tempo real no dispositivo

1. Visão geral

1cbf855eda62c306.png

Este é o codelab de otimização de compras no app em tempo real no dispositivo. Neste codelab, você vai aprender a usar o TensorFlow Lite e o Firebase para treinar e implantar um modelo de personalização personalizado no seu app.

Neste tutorial, mostramos como criar um modelo de machine learning para personalização, em especial um que prevê a oferta ideal de compra no app (IAP, na sigla em inglês) de acordo com o estado do usuário atual. Este é um exemplo de um problema de bandit contextual, um tipo importante e amplamente aplicável de problema de aprendizado de máquina que você vai conhecer melhor neste codelab.

O que você vai aprender

  • Coletar dados de análise com o Firebase Analytics
  • Pré-processar dados de análise usando o BigQuery
  • Treinar um modelo de ML simples para otimização no dispositivo de compras no app (IAPs)
  • Implante modelos do TFLite no Firebase ML e acesse-os no seu app
  • Medir e testar diferentes modelos com o Teste A/B do Firebase
  • Treinar e implantar novos modelos usando os dados mais recentes em uma cadência recorrente

Pré-requisitos

  • Android Studio versão 3.4 ou mais recente
  • Um dispositivo de teste físico com Android 2.3 ou mais recente e Google Play Services 9.8 ou mais recente, ou um emulador com Google Play Services 9.8 ou mais recente
  • Se você estiver usando um dispositivo de teste físico, um cabo de conexão
  • Conhecimento básico de ML

Como você usará este tutorial?

Apenas leitura Leitura e exercícios

Como você classificaria sua experiência com a criação de apps Android?

Iniciante Intermediário Proficiente

2. Declaração do problema

Digamos que você seja um desenvolvedor de jogos que quer mostrar sugestões personalizadas de compras no app (IAP, na sigla em inglês) no final de cada nível. Você só pode mostrar um número limitado de opções de compras no app por vez, e não sabe quais delas terão a melhor conversão. Como cada usuário e cada sessão são diferentes, como podemos encontrar a oferta de IAP que oferece a maior recompensa esperada?

3. Acessar o exemplo de código

Clone o repositório do GitHub (link em inglês) na linha de comando.

git clone https://github.com/googlecodelabs/firebase-iap-optimization.git

Este repositório contém:

  1. Um notebook Jupyter (.ipynb) que treina o modelo de personalização e o empacota em um modelo do TFLite
  2. Um exemplo de app Kotlin que usa o modelo TFLite para fazer previsões no dispositivo

4. Executar o app com o Firebase

Neste codelab, vamos trabalhar na otimização das compras no app do nosso jogo fictício, o Flappy Sparky. O jogo é um side-scroller em que o jogador controla um Sparky, tentando voar entre colunas de paredes sem bater nelas. No início do nível, o usuário recebe uma oferta de compra no app que dá um power-up. Neste codelab, vamos implementar apenas a parte de otimização de IAP do app.

Você poderá aplicar o que aprender aqui ao seu próprio app conectado a um projeto do Firebase. Como alternativa, crie um novo projeto do Firebase para este codelab. Se precisar de ajuda para começar a usar o Firebase, consulte nossos tutoriais sobre o assunto ( Android e iOS).

5. Coletar eventos de análise no seu app

Os eventos do Google Analytics fornecem insights sobre o comportamento do usuário e são usados para treinar o modelo de ML. Por exemplo, o modelo pode aprender que os usuários que jogam por mais tempo têm mais chances de fazer uma compra no app para ganhar vidas extras. O modelo de ML precisa de eventos do Google Analytics como entrada para aprender essas informações.

Alguns eventos de análise que podemos querer registrar incluem:

  • Quanto tempo o usuário joga
  • Em qual nível o usuário está
  • Quantas moedas o usuário gasta
  • Quais itens o usuário compra

Baixar dados de amostra (opcional)

Nas etapas a seguir, vamos usar o Firebase Analytics para registrar eventos de análise que serão usados no nosso modelo. Se você já tiver dados de análise que quer usar, vá para a seção "Treinar o modelo de otimização" deste codelab e acompanhe com nossos dados de exemplo.

Coletar dados com o SDK do Firebase Analytics

Vamos usar o Firebase Analytics para ajudar a coletar esses eventos de análise. O SDK do Firebase Analytics captura automaticamente vários eventos e propriedades do usuário. Também é possível definir seus próprios eventos personalizados para medir os eventos exclusivos do seu app.

Instalar o SDK do Firebase Analytics

Para começar a usar o Firebase Analytics no seu app, siga a documentação "Começar a usar o Google Analytics". O repositório firebase-iap-optimization clonado no início deste codelab já inclui o SDK do Firebase Analytics.

Registrar eventos personalizados

Depois de configurar o SDK do Firebase Analytics, podemos começar a registrar os eventos necessários para treinar nosso modelo.

Antes disso, é importante definir um ID do usuário no evento do Google Analytics para associar os dados do Google Analytics desse usuário aos dados dele no app.

MainActivity.kt

firebaseAnalytics.setUserId("player1")

Em seguida, podemos registrar eventos do player. Para otimizar o IAP, queremos registrar cada oferta apresentada ao usuário e se ela foi clicada. Isso vai gerar dois eventos de análise: offer_iap e offer_accepted. Também vamos acompanhar um offer_id exclusivo para usá-lo mais tarde e combinar esses dados para saber se uma oferta foi aceita.

MainActivity.kt

predictButton?.setOnClickListener {
  predictionResult = iapOptimizer.predict()

  firebaseAnalytics.logEvent("offer_iap"){
    param("offer_type", predictionResult)
    param("offer_id", sessionId)
  }
}

acceptButton?.setOnClickListener {
  firebaseAnalytics.logEvent("offer_accepted") {
    param("offer_type", predictionResult)
    param("offer_id", sessionId)
  }
}

Para mais informações sobre como registrar eventos personalizados, acesse a documentação de registro de eventos do Firebase Analytics.

6. Pré-processar dados no BigQuery

Na última etapa, coletamos eventos sobre qual oferta de compra no app é apresentada ao usuário e em qual ele clica. Nesta etapa, vamos combinar esses dados de eventos com os dados do usuário para que nosso modelo possa aprender com uma visão completa.

Para isso, vamos começar exportando os eventos de análise para o BigQuery.

Para vincular seu projeto do Firebase e os aplicativos dele ao BigQuery, faça as seguintes ações:

  1. Faça login no Firebase.
  2. Clique em o ícone "Configurações" e selecione "Configurações do projeto".
  3. Na página "Configurações do projeto", clique na guia "Integrações".
  4. No cartão do BigQuery, clique em "Vincular".

(Opcional) Exportar coleções do Firestore para o BigQuery

Nesta etapa, você pode exportar mais dados de usuários do Firestore para o BigQuery e usá-los para treinar o modelo. Se você quiser pular esta etapa por enquanto, vá para a seção "Preparar dados no BigQuery" deste codelab e acompanhe os eventos do Firebase Analytics registrados na última etapa.

O Firestore pode ser o local em que você armazenou a data de inscrição dos usuários, as compras no app feitas, os níveis no jogo, as moedas em saldo ou qualquer outro atributo que possa ser útil para treinar o modelo.

Para exportar suas coleções do Firestore para o BigQuery, instale a extensão de exportação do BigQuery para Firestore. Em seguida, faça a junção das tabelas no BigQuery para combinar esses dados com os do Google Analytics e usar no modelo de personalização e no restante deste codelab.

Preparar dados no BigQuery

Nas próximas etapas, vamos usar o BigQuery para transformar nossos dados de análise brutos em dados que podem ser usados para treinar nosso modelo.

Para que nosso modelo aprenda qual oferta de IAP apresentar com base no usuário e no estado do jogo, precisamos organizar dados sobre o seguinte:

  • o usuário
  • o estado do jogo
  • a oferta apresentada
  • se a oferta apresentada recebe um clique ou não

Todos esses dados precisam ser organizados em uma única linha de uma tabela para que nosso modelo os processe. Felizmente, o BigQuery foi criado para ajudar você a fazer exatamente isso.

O BigQuery permite criar "visualizações" para manter sua consulta organizada. Uma visualização é uma tabela virtual definida por uma consulta SQL. Ao criar uma visualização, você a consulta da mesma forma que faz com uma tabela. Com isso, podemos primeiro limpar nossos dados de análise.

Para saber se cada oferta de compra no app é clicada, precisamos unir os eventos offer_iap e offer_accepted que registramos na etapa anterior.

all_offers_joined: visualização do BigQuery

SELECT
  iap_offers.*,
  CASE
    WHEN accepted_offers.accepted IS NULL THEN FALSE ELSE TRUE
  END
  is_clicked,
FROM
  `iap-optimization.ml_sample.accepted_offers` AS accepted_offers
RIGHT JOIN
  `iap-optimization.ml_sample.iap_offers` AS iap_offers
ON
 accepted_offers.offer_id =iap_offers.offer_id;

all_offers_with_user_data: visualização do BigQuery

SELECT
  offers.is_clicked,
  offers.presented_powerup,
  offers.last_run_end_reason,
  offers.event_timestamp,
  users.*
FROM
  `iap-optimization.ml_sample.all_offers_joined` AS offers
LEFT JOIN
  `iap-optimization.ml_sample.all_users` AS users
ON
  users.user_id = offers.user_id;

Exportar um conjunto de dados do BigQuery para o Google Cloud Storage

Por fim, podemos exportar o conjunto de dados do BigQuery para o GCS e usá-lo no treinamento do modelo.

888daa7ba4db8e44.png

14d22bf474fae455.png

7. Treinar o modelo de otimização

Dados de amostra

Use os dados da etapa anterior, "Pré-processar dados no BigQuery", ou os dados de amostra para download fornecidos aqui para acompanhar o restante deste codelab.

Definição do problema

Antes de começar a treinar o modelo, vamos definir nosso problema de bandits contextuais.

Explicação sobre os bandits contextuais

No início de cada nível do Flappy Sparky, o usuário recebe uma oferta de compra no app que dá um power-up. Só podemos mostrar uma opção de compra no app por vez, e não sabemos quais delas terão a melhor conversão. Como cada usuário e cada sessão são diferentes, como podemos encontrar a oferta de IAP que oferece a maior recompensa esperada?

Nesse caso, vamos definir a recompensa como 0 se o usuário não aceitar a oferta de IAP e o valor do IAP se ele aceitar. Para tentar maximizar a recompensa, podemos usar nossos dados históricos para treinar um modelo que prevê a recompensa esperada para cada ação de um usuário e encontrar a ação com a maior recompensa.

e7d3264141498bff.jpeg

Vamos usar o seguinte na previsão:

  • Estado: informações sobre o usuário e a sessão atual
  • Ação: ofertas de IAP que podemos escolher mostrar
  • Prêmio: valor da oferta de compra no app

Exploração x descoberta

Em todos os problemas de bandit multiarmado, o algoritmo precisa equilibrar a exploração (receber mais dados para aprender qual ação oferece o resultado ideal) e o uso (usar o resultado ideal para obter a maior recompensa).

Na nossa versão do problema, vamos simplificar isso para treinar o modelo periodicamente na nuvem e fazer previsões apenas quando o modelo for usado no dispositivo do usuário (em vez de treinar também no dispositivo do usuário). Para garantir que temos dados de treinamento suficientes depois de usar o modelo, precisamos mostrar resultados aleatórios aos usuários do app às vezes (por exemplo, 30%). Essa estratégia de equilibrar a experimentação e a exploração é chamada de Epsilon-greedy.

Como treinar o modelo

Para começar, use o script de treinamento (training.ipynb) fornecido com o codelab. Nosso objetivo é treinar um modelo que preveja as recompensas esperadas para cada ação em um determinado estado. Depois, encontramos a ação que oferece as maiores recompensas esperadas.

Treinamento local

A maneira mais fácil de começar a treinar seu próprio modelo é fazer uma cópia do notebook no exemplo de código deste codelab.

Não é necessário ter uma GPU para este codelab, mas, se você precisar de uma máquina mais potente para analisar seus próprios dados e treinar seu próprio modelo, crie uma instância do AI Platform Notebook para acelerar o treinamento.

No script de treinamento fornecido, criamos um iterador que gera dados de treinamento dos arquivos CSV exportados do BigQuery. Em seguida, usamos os dados para começar a treinar nosso modelo com o Keras. Os detalhes de como treinar o modelo podem ser encontrados nos comentários do notebook Python.

Medir a performance do modelo

Durante o treinamento, vamos comparar o modelo com um agente aleatório que seleciona ofertas de IAP de forma aleatória para verificar se o modelo está realmente aprendendo. Essa lógica fica em ValidationCallback.

Ao final do treinamento, usamos os dados em test.csv para testar nosso modelo novamente. O modelo nunca viu esses dados antes, então podemos ter certeza de que o resultado não é devido ao overfitting. Nesse caso, o modelo tem uma performance 28% melhor do que o agente aleatório.

Exportar o modelo do TFLite

Agora temos um modelo treinado pronto para uso, mas ele está em um formato do TensorFlow. Precisamos exportar o modelo no formato TFLite para que ele possa ser executado em dispositivos móveis.

train.ipynb

converter = tflite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()

with tf.io.gfile.GFile('iap-optimizer.tflite', 'wb') as f:
  f.write(tflite_model)

Nessa página, você pode baixar e agrupar o modelo com seu app.

Opcionalmente, para um app de produção, recomendamos que você implante o modelo no Firebase ML e que o Firebase hospede o modelo. Isso é útil por dois motivos principais:

  1. Podemos manter o tamanho da instalação do app pequeno e fazer o download do modelo apenas se necessário.
  2. O modelo pode ser atualizado regularmente e com um ciclo de lançamento diferente do app inteiro.

Para saber como implantar o modelo no Firebase ML, siga o codelab Adicionar o Firebase ao app Android com TFLite. É possível fazer a implantação usando o console do Firebase ou a API Python.

8. Como fazer previsões no dispositivo

A próxima etapa é fazer previsões usando o modelo no dispositivo. Você pode encontrar um app de exemplo que faz o download de um modelo do Firebase ML na pasta app do código de exemplo baixado e usá-lo para realizar inferências com alguns dados do lado do cliente.

Como aplicamos algum pré-processamento durante o treinamento do modelo, precisamos aplicar o mesmo pré-processamento à entrada do modelo ao executar no dispositivo. Uma maneira simples de fazer isso é usar um formato independente de plataforma e linguagem, como um arquivo JSON que contenha um mapa de cada recurso para metadados sobre como o pré-processamento é feito. Confira mais detalhes sobre como isso é feito no app de exemplo.

Em seguida, fornecemos uma entrada de teste ao modelo da seguinte maneira:

IapOptimzer.kt

  val testInput = mapOf(
    "coins_spent" to                       2048f,
    "distance_avg" to                      1234f,
    "device_os" to                         "ANDROID",
    "game_day" to                          10f,
    "geo_country" to                       "Canada",
    "last_run_end_reason" to               "laser"
  )

O modelo sugere que sparky_armor é o melhor power-up de compra no app para esse usuário específico.

a3381dbcdbdf811e.png

Medir a acurácia do modelo

Para medir a acurácia do nosso modelo, basta acompanhar as ofertas de IAP previstas por ele e se elas são clicadas usando o Firebase Analytics. Você pode usar isso com o Teste A/B do Firebase para medir a performance real do modelo. Além disso, você também pode realizar testes A/B em diferentes iterações do modelo. Saiba mais sobre o teste A/B com o Firebase na documentação Criar experimentos da Configuração remota do Firebase com o Teste A/B.

9. (Opcional): atualizar o modelo regularmente com novos dados

Se você precisar atualizar o modelo à medida que novos dados forem chegando, configure um pipeline para treinar novamente o modelo de forma recorrente. Para isso, primeiro verifique se você tem novos dados para usar no treinamento com a estratégia epsilon-greedy mencionada acima. Por exemplo, usar o resultado da previsão do modelo 70% das vezes e usar resultados aleatórios 30% das vezes.

A configuração de um pipeline para treinamento e implantação com novos dados está além do escopo deste codelab. Confira a AI Platform do Google Cloud e o TFX para começar.

10. Parabéns!

Neste codelab, você aprendeu a treinar e implantar um modelo do TFLite no dispositivo para otimizar as compras no app usando o Firebase. Para saber mais sobre o TFLite e o Firebase, confira outros exemplos do TFLite e os guias de primeiros passos do Firebase.

Se tiver dúvidas, deixe um comentário no Stack Overflow #firebase-machine-learning.

O que vimos

  • TensorFlow Lite
  • Firebase ML
  • Firebase Analytics
  • BigQuery

Próximas etapas

  • Treine e implante um modelo de otimizador para seu app.

Saiba mais