Como criar um sistema de recomendações de comércio eletrônico usando o BigQuery ML

Saiba como criar um sistema de recomendações usando o BigQuery ML para gerar recomendações de produtos ou serviços com base nos dados do cliente disponíveis no BigQuery. Em seguida, saiba como disponibilizar esses dados para outros sistemas de produção exportando-os para o Google Analytics 360 ou o Cloud Storage ou fazendo a leitura programática deles na tabela do BigQuery.

Essa é a abordagem recomendada quando os dados que já estiverem no BigQuery. O BigQuery ML permite criar um modelo de machine learning, treiná-lo nos dados do cliente no BigQuery e implantá-lo usando consultas SQL padrão. Com ele, você não precisa exportar os dados para outro produto nem criar um modelo de treinamento e um pipeline de implantação. O BigQuery faz escalonamento automático para lidar com quaisquer recursos de computação necessários.

O modelo de machine learning criado neste tutorial usa fatoração de matrizes, um método comum e eficaz para criar um sistema de recomendação com base nos dados de preferência do usuário. Para mais informações sobre essa abordagem, consulte fatoração de matrizes.

Este tutorial usa o conjunto de dados de amostra do Google Analytics, hospedado publicamente no BigQuery. Esse conjunto de dados fornece 12 meses (agosto de 2016 a agosto de 2017) de dados ofuscados do Google Analytics 360 da Google Merchandise Store, uma loja de comércio eletrônico real que vende mercadorias com a marca do Google.

Objetivos

  • Processe dados de amostra em um formato adequado para treinar um modelo de fatoração de matrizes.
  • Crie, treine e implante um modelo de fatoração de matrizes.
  • Receba previsões do modelo implantado sobre os produtos em que seus clientes têm mais probabilidade de se interessar.
  • Exporte dados de previsão do BigQuery para um ou mais produtos para uso em recomendações aos clientes.

Custos

Neste tutorial, usamos os seguintes componentes faturáveis do Google Cloud:

  • BigQuery
  • BigQuery ML

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem ser qualificados para uma avaliação gratuita.

Antes de começar

  1. No Console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  2. Verifique se o faturamento está ativado para seu projeto na nuvem. Saiba como confirmar se o faturamento está ativado para o projeto.

Ao concluir este tutorial, exclua os recursos criados para evitar o faturamento contínuo. Para mais informações, consulte Como fazer a limpeza.

Processar os dados de amostra

Ao usar a fatoração de matrizes, você avalia o feedback explícito ou implícito dos usuários para determinar as preferências dos clientes. Para usar o feedback explícito, é necessário que o conjunto de dados contenha dados sobre as preferências de produto dos usuários, como avaliações com estrelas entre 1 e 5. Nos casos em que não houver feedback explícito disponível, use outras métricas comportamentais para inferir as preferências dos clientes, como analisar o tempo total que um usuário gasta em uma página de detalhes de um produto. Essa é a abordagem usada neste tutorial.

Para treinar o modelo de fatoração de matrizes, você precisa de uma tabela com colunas que identifiquem o cliente, o item que está sendo avaliado e a classificação implícita. Nesta seção, você criará uma tabela dessas com as colunas userid, itemId e session_duration, em que session_duration contém a duração da sessão do usuário na página do produto do item em questão.

Siga estas etapas para criar uma tabela usando dados do conjunto de dados de amostra do Google Analytics:

  1. Abra o conjunto de dados de amostra do Google Analytics no Google Cloud Marketplace e clique em Visualizar conjunto de dados. Isso abre o console do BigQuery com o conjunto de dados de amostra do Google Analytics selecionado.
  2. Na seção Recursos, selecione o projeto em que você está fazendo este tutorial.
  3. Clique em Criar conjunto de dados.

    Mostrar local do botão "Criar conjunto de dados".

  4. Na página Criar conjunto de dados, faça o seguinte:

    • Em ID do conjunto de dados, digite bqml.
    • Em Local dos dados, escolha o local mais próximo de você.
    • Clique em Criar conjunto de dados.
  5. Siga esta etapa se você pretende exportar os dados para o Google Analytics 360. Caso contrário, pule-a.

    No painel Editor de consultas, execute a seguinte instrução SQL para copiar um subconjunto dos dados de amostra do Google Analytics em uma nova tabela e preencher o campo clientId, que você usará como chave para agregar feedback implícito do usuário na próxima etapa:

    CREATE OR REPLACE TABLE bqml.ga_clientid_sample AS (
      SELECT *
      FROM `bigquery-public-data.google_analytics_sample.ga_sessions_2017*`
      LIMIT 100000);
    
     UPDATE bqml.ga_clientid_sample
       SET clientId = fullvisitorId
       WHERE true;
    

    Use clientId como o campo chave ao importar dados de público-alvo para o Google Analytics 360. clientId normalmente é uma versão com hash de fullVisitorId, mas não é preenchido no conjunto de dados de amostra do Google Analytics. Para preencher clientId nos seus próprios dados do Analytics 360, crie uma dimensão personalizada e preencha-o.

  6. Execute a seguinte instrução SQL para criar uma tabela contendo os dados de treinamento. Execute a versão que usa o campo clientId como chave se você pretende exportar os dados para o Analytics 360. Execute a versão que usa o campo fullVisitorId como chave se você planeja usar os dados com outros sistemas de marketing.

    clientId

    CREATE OR REPLACE TABLE bqml.aggregate_web_stats AS (
      WITH
        durations AS (
          --calculate pageview durations
          SELECT
            CONCAT(clientId,'-',
                 CAST(visitNumber AS STRING),'-',
                 CAST(hitNumber AS STRING) ) AS visitorId_session_hit,
            LEAD(time, 1) OVER (
              PARTITION BY CONCAT(clientId,'-',CAST(visitNumber AS STRING))
              ORDER BY
              time ASC ) - time AS pageview_duration
          FROM
            `bqml.ga_clientid_sample`,
            UNNEST(hits) AS hit
        ),
        prodview_durations AS (
          --filter for product detail pages only
         SELECT
            CONCAT(clientId,'-',CAST(visitNumber AS STRING)) AS userId,
            productSKU AS itemId,
            IFNULL(dur.pageview_duration,
             1) AS pageview_duration,
          FROM
            `bqml.ga_clientid_sample` t,
            UNNEST(hits) AS hits,
            UNNEST(hits.product) AS hits_product
          JOIN
            durations dur
          ON
            CONCAT(clientId,'-',
                   CAST(visitNumber AS STRING),'-',
                   CAST(hitNumber AS STRING)) = dur.visitorId_session_hit
          WHERE
          eCommerceAction.action_type = "2"
        ),
        aggregate_web_stats AS(
          --sum pageview durations by userId, itemId
          SELECT
            userId,
            itemId,
            SUM(pageview_duration) AS session_duration
          FROM
            prodview_durations
          GROUP BY
            userId,
            itemId )
        SELECT
         *
       FROM
          aggregate_web_stats
    );
    

    fullVisitorId

    CREATE OR REPLACE TABLE bqml.aggregate_web_stats AS (
      WITH
        durations AS (
          --calculate pageview durations
          SELECT
            CONCAT(fullVisitorId,'-',
                 CAST(visitNumber AS STRING),'-',
                 CAST(hitNumber AS STRING) ) AS visitorId_session_hit,
            LEAD(time, 1) OVER (
              PARTITION BY CONCAT(fullVisitorId,'-',CAST(visitNumber AS STRING))
              ORDER BY
              time ASC ) - time AS pageview_duration
          FROM
            `bigquery-public-data.google_analytics_sample.ga_sessions_2017*`,
            UNNEST(hits) AS hit
        ),
        prodview_durations AS (
          --filter for product detail pages only
         SELECT
            CONCAT(fullVisitorId,'-',CAST(visitNumber AS STRING)) AS userId,
            productSKU AS itemId,
            IFNULL(dur.pageview_duration,
             1) AS pageview_duration,
          FROM
            `bigquery-public-data.google_analytics_sample.ga_sessions_2017*` t,
            UNNEST(hits) AS hits,
            UNNEST(hits.product) AS hits_product
          JOIN
            durations dur
          ON
            CONCAT(fullVisitorId,'-',
                   CAST(visitNumber AS STRING),'-',
                   CAST(hitNumber AS STRING)) = dur.visitorId_session_hit
          WHERE
          eCommerceAction.action_type = "2"
        ),
        aggregate_web_stats AS(
          --sum pageview durations by userId, itemId
          SELECT
            userId,
            itemId,
            SUM(pageview_duration) AS session_duration
          FROM
            prodview_durations
          GROUP BY
            userId,
            itemId )
        SELECT
         *
       FROM
          aggregate_web_stats
    );
    
  7. Execute a seguinte instrução SQL para ver uma amostra da data na tabela bqml.aggregate_web_stats resultante:

    SELECT
     *
    FROM
      bqml.aggregate_web_stats
    LIMIT
      10;
    

    Os resultados serão semelhantes aos exibidos abaixo:

    Primeiras 10 linhas de dados de treinamento processados.

Comprar slots flexíveis

Se você usa preços sob demanda para o BigQuery, será necessário adquirir slots flexíveis e criar reservas e atribuições para eles a fim de treinar um modelo de fatoração de matrizes. Pule esta seção se você usa preços fixos com o BigQuery.

É necessário ter a permissão bigquery.reservations.create para comprar slots flexíveis. Essa permissão é concedida ao proprietário do projeto e aos papéis predefinidos de gerenciamento de identidade e acesso bigquery.admin e bigquery.resourceAdmin.

  1. No console do BigQuery, clique em Reservas.
  2. Se você for redirecionado para a página API BigQuery Reservation para ativar a API, clique em Ativar. Do contrário, avance para a próxima etapa.
  3. Na página Reservas, clique em Comprar slots.
  4. Na página Comprar slots, defina as opções da seguinte maneira:

    1. Em Duração do compromisso, escolha Flexível.
    2. Em Local, escolha o local selecionado ao criar o conjunto de dados durante o procedimento Processar os dados de amostra.
    3. Em Número de slots, escolha 500.
    4. Clique em Próxima.
    5. Em Confirmação da compra, digite CONFIRM.

  5. Clique em Comprar.

  6. Clique em Ver compromissos de slot.

  7. Aguarde até 20 minutos para que a capacidade seja provisionada. Depois que a capacidade for provisionada, o status do compromisso de slot ficará verde e exibirá uma marca de seleção .

  8. Clique em Criar reserva.

  9. Na página Criar reserva, defina as opções da seguinte maneira:

    1. Em Nome da reserva, digite model.
    2. Em Local, escolha o local em que você comprou os slots flexíveis.
    3. Em Número de slots, digite 500.
    4. Clique em Salvar. Isso leva você de volta à página Reservas.
  10. Selecione a guia Atribuições.

  11. Em Selecionar organização, pasta ou projeto, clique em Procurar.

  12. Digite o nome do projeto em que você está fazendo este tutorial.

  13. Clique em Selecionar.

  14. Em Reserva, escolha a reserva de modelo que você criou.

  15. Clique em Criar.

  16. Clique em BigQuery para retornar ao console do BigQuery.

Criar, treinar e implantar o modelo

Execute a instrução SQL CREATE MODEL para criar, treinar e implantar o modelo de fatoração de matrizes:

      CREATE OR REPLACE MODEL bqml.retail_recommender
      OPTIONS(model_type='matrix_factorization',
            user_col='userId',
            item_col='itemId',
            rating_col='session_duration',
            feedback_type='implicit'
            )
      AS
      SELECT * FROM bqml.aggregate_web_stats;

Após a conclusão do treinamento, o modelo treinado é implantado como bqml.retail_recommender.

Usar o modelo treinado para fazer predições

Use a função SQL ML.RECOMMEND para receber previsões do modelo bqml.retail_recommender implantado.

  1. Para ver um exemplo dos dados de recomendações, execute a seguinte instrução SQL para receber previsões que das cinco principais recomendações para um userId especificado:

    DECLARE MY_USERID STRING DEFAULT "0824461277962362623-1";
    
    SELECT
      *
    FROM
      ML.RECOMMEND(MODEL `bqml.retail_recommender`,
      (SELECT MY_USERID as userID)
                  )
    ORDER BY predicted_session_duration_confidence DESC
    LIMIT 5;
    

    Os resultados serão semelhantes aos exibidos abaixo:

    Cinco principais recomendações para um determinado User ID.

  2. Execute a seguinte instrução SQL para receber as cinco principais previsões para todos os usuários. Isso gera um grande número de linhas. Portanto, essa saída é gravada em uma tabela e, em seguida, os dez primeiros registros são recuperados para que você veja um exemplo dos dados.

    -- Create output table of top 5 predictions
    CREATE OR REPLACE TABLE bqml.prod_recommendations AS (
    WITH predictions AS (
        SELECT
          userId,
          ARRAY_AGG(STRUCT(itemId,
                           predicted_session_duration_confidence)
                    ORDER BY
                      predicted_session_duration_confidence DESC
                    LIMIT 5) as recommended
        FROM ML.RECOMMEND(MODEL bqml.retail_recommender)
        GROUP BY userId
    )
    
    SELECT
      userId,
      itemId,
      predicted_session_duration_confidence
    FROM
      predictions p,
      UNNEST(recommended)
    );
    
    -- Show table
    SELECT
     *
    FROM
      bqml.prod_recommendations
    ORDER BY
      userId
    LIMIT
      10;
    

    Os resultados serão semelhantes aos exibidos abaixo:

    Primeiras 10 recomendações para todos os usuários.

Usar as recomendações previstas na produção

Depois de receber as recomendações, a maneira como você as disponibiliza para o pipeline de produção depende do seu caso de uso. Nas seções a seguir, você verá como exportar dados de previsão para o Analytics 360 ou o Cloud Storage ou com fazer a leitura programática dos dados do BigQuery em um DataFrame do Pandas.

Exportar recomendações para o Google Analytics 360

Se você quiser exportar dados para o Google Analytics 360, é recomendável fornecer uma coluna para cada produto que indique a probabilidade de o cliente comprar tal produto. Algo semelhante a:

clientId likelihoodProductA likelihoodProductB
123 0,6527238 0,3464891
456 0,8720673 0,2750274
789 0,5620734 0,9127595

Para criar uma coluna "probabilidade de comprar" por produto, crie um procedimento pivot(), conforme descrito em Easy pivot() no BigQuery, em uma etapa (em inglês).

  1. Execute a seguinte instrução SQL para criar o procedimento pivot:

    CREATE OR REPLACE FUNCTION
    `bqml.normalize_col_name`(col_name STRING) AS (
      REGEXP_REPLACE(col_name,r'[/+#|]', '_'
    ));
    
    CREATE OR REPLACE PROCEDURE `bqml.pivot`(
      table_name STRING
      , destination_table STRING
      , row_ids ARRAY<STRING>
      , pivot_col_name STRING
     , pivot_col_value STRING
      , max_columns INT64
      , aggregation STRING
      , optional_limit STRING
      )
    
    BEGIN
    
      DECLARE pivotter STRING;
    
      EXECUTE IMMEDIATE (
       "SELECT STRING_AGG(' "||aggregation
        ||"""(IF('||@pivot_col_name||'="'||x.value||'", '||@pivot_col_value||', null)) e_'||bqml.normalize_col_name(x.value))
       FROM UNNEST((
           SELECT APPROX_TOP_COUNT("""||pivot_col_name||", @max_columns) FROM `"||table_name||"`)) x"
      ) INTO pivotter
      USING pivot_col_name AS pivot_col_name, pivot_col_value AS pivot_col_value, max_columns AS max_columns;
    
      EXECUTE IMMEDIATE (
       'CREATE OR REPLACE TABLE `'||destination_table
       ||'` AS SELECT '
       ||(SELECT STRING_AGG(x) FROM UNNEST(row_ids) x)
       ||', '||pivotter
       ||' FROM `'||table_name||'` GROUP BY '
       || (SELECT STRING_AGG(''||(i+1)) FROM UNNEST(row_ids) WITH OFFSET i)||' ORDER BY '
       || (SELECT STRING_AGG(''||(i+1)) FROM UNNEST(row_ids) WITH OFFSET i)
       ||' '||optional_limit
      );
    
    END;
    
  2. Execute a seguinte instrução SQL para criar uma tabela contendo o clientId e uma coluna "probabilidade de comprar" para cada produto:

    CALL bqml.pivot(
      'bqml.prod_recommendations' # source table
      , 'bqml.prod_recommendations_export' # destination table
      , ['userId'] # row IDs
      , 'itemId' # pivot column name
      , 'predicted_session_duration_confidence' # pivot column value
      , 30 # max number of columns
      , 'AVG' # aggregation
      , '' # optional_limit
    );
    
  3. Execute a seguinte instrução SQL para ver uma amostra da data na tabela bqml.prod_recommendations_export resultante:

    SELECT
      *
    FROM
      bqml.prod_recommendations_export
    ORDER BY
      userId
    LIMIT
      10;
    

    Os resultados serão semelhantes aos exibidos abaixo:

    Primeiras 10 recomendações para todos os usuários.

Depois de ter os dados no formato correto, salve-os como um arquivo CSV e use a Importação de dados para importar os dados para o Google Analytics 360. É necessário mapear os nomes das colunas nos dados de recomendações exportados para o esquema de importação de dados do Analytics 360. Por exemplo, se o esquema de importação de dados for ga:clientId, ga:dimension1, ga:dimension2, os nomes das colunas nos dados precisarão ser ga:clientId, ga:dimension1, ga:dimension2. O BigQuery não permite o uso de dois pontos nos nomes das colunas. Portanto, é necessário atualizar os nomes das colunas no arquivo CSV exportado antes de importá-lo.

Se quiser, use a implementação de referência MoDeM (Model Deployment for Marketing) (em inglês) para modelos do BigQuery ML para facilitar o carregamento de dados no Google Analytics 360. Para começar, use as instruções interativas no notebook BQML Deployment Template (em inglês).

Exportar recomendações para o Cloud Storage

Exporte os dados das recomendações da tabela do BigQuery para o Cloud Storage seguindo as instruções em Como exportar dados da tabela.

Fazer a leitura programática das recomendações

Faça a leitura dos dados das recomendações da tabela do BigQuery em um DataFrame do Pandas usando a API BigQuery Storage seguindo as instruções em Fazer o download dos dados da tabela usando a biblioteca de cliente do BigQuery. Como alternativa, use uma das bibliotecas de cliente do BigQuery para programar sua própria solução.

Resumo

Você concluiu o tutorial e agora sabe como treinar seu sistema de recomendações usando o BigQuery ML, implantar o modelo e usar os resultados na produção.

Como fazer a limpeza

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados neste tutorial, exclua o projeto que contém os recursos ou mantenha o projeto, mas exclua apenas esses recursos.

Seja como for, remova esses recursos para que não sejam faturados no futuro. Nas seções a seguir, você verá como excluir esses recursos.

Excluir o projeto

A maneira mais fácil de eliminar o faturamento é excluir o projeto criado para o tutorial.

  1. No Console do Cloud, acesse a página Gerenciar recursos:

    Acessar "Gerenciar recursos"

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.

Excluir os componentes

Se você não quiser excluir o projeto, use as seguintes seções para excluir os componentes faturáveis deste tutorial.

Excluir o conjunto de dados do BigQuery

  1. Abra o console do BigQuery
  2. Na seção Recursos, expanda o projeto em que você fez este tutorial e selecione o conjunto de dados bqml.
  3. Clique em Excluir conjunto de dados no cabeçalho do painel do conjunto de dados.
  4. Na janela de sobreposição que aparece, digite bqml e clique em Excluir.

Excluir slots flexíveis

Se você criou slots flexíveis, siga estas etapas para excluí-los:

  1. No console do BigQuery, clique em Reservas.
  2. Selecione a guia Atribuições.
  3. Localize a linha da atribuição que você criou para a reserva do modelo, clique em Mais na coluna Ações e em Excluir.
  4. Selecione a guia Reservas.
  5. Localize a linha da reserva de modelo, clique Mais na coluna Ações e, em seguida, clique em Excluir.
  6. Selecione a guia Compromissos de slot.
  7. Localize a linha que contém os 500 slots flexíveis que você comprou, clique em Mais na coluna Ações e em Excluir.
  8. Em Confirmar remoção de compromisso de slot, digite REMOVE.
  9. Clique em Continuar.

A seguir