Crea un sistema de recomendación de comercio electrónico mediante BigQuery ML

Aprende a crear un sistema de recomendación mediante BigQuery ML para generar recomendaciones de productos o de servicios a partir de datos de clientes en BigQuery. Luego, para aprender a hacer que esos datos estén disponibles para otros sistemas de producción, debes exportarlos a Google Analytics 360 o Cloud Storage, o leerlos de manera programática desde la tabla de BigQuery.

Este es el enfoque recomendado cuando tienes datos que ya residen en BigQuery. BigQuery ML te permite crear un modelo de aprendizaje automático, entrenarlo con datos de clientes en BigQuery y, también, implementarlo mediante consultas de SQL estándar. Así evitas tener que exportar tus datos a otro producto o compilar una canalización de implementación y entrenamiento de modelos, y BigQuery escala de forma automática para controlar los recursos de procesamiento que necesites.

En el modelo de aprendizaje automático que creas en este instructivo, se usa la factorización de matrices, un método común y efectivo para la creación un sistema de recomendación basado en los datos de preferencias del usuario. Para obtener más información sobre este enfoque, consulta Factorización de matrices.

En este instructivo, se usa el conjunto de datos de muestra de Google Analytics, que se aloja a nivel público en BigQuery. Este conjunto de datos proporciona 12 meses (de agosto de 2016 a agosto de 2017) de datos ofuscados de Analytics 360 de Google Merchandising Store, una tienda de comercio electrónico real que vende productos de la marca Google.

Objetivos

  • Procesar datos de muestra en un formato adecuado para entrenar un modelo de factorización de matrices
  • Crear, entrenar y, además, implementar un modelo de factorización de matrices
  • Obtener predicciones del modelo implementado sobre los productos que más les puedan interesar a tus clientes
  • Exportar datos de predicción desde BigQuery a uno o más productos para ofrecer recomendaciones a los clientes

Costos

En este instructivo, se usan los siguientes componentes facturables de Google Cloud:

  • BigQuery
  • BigQuery ML

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud sean aptos para obtener una prueba gratuita.

Antes de comenzar

  1. En la página del selector de proyectos de Google Cloud Console, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  2. Comprueba que la facturación esté habilitada en tu proyecto.

    Descubre cómo puedes habilitar la facturación

Cuando finalices este instructivo, podrás borrar los recursos creados para evitar que se te siga facturando. Para obtener más información, consulta cómo hacer una limpieza.

Procesa los datos de muestra

Cuando usas la factorización de matrices, evalúas los comentarios explícitos o implícitos de los usuarios para determinar las preferencias de los clientes. Para usar comentarios explícitos, el conjunto de datos debe contener datos sobre las preferencias de productos de los usuarios, como las calificaciones por estrellas del 1 al 5. En los casos en los que no haya comentarios explícitos disponibles, debes usar otras métricas de comportamiento para inferir las preferencias del cliente, como el tiempo total que un usuario pasa en una página de detalles del producto. Este es el enfoque que se usa en este instructivo.

Para entrenar el modelo de factorización de matrices, necesitas una tabla con columnas que identifiquen al cliente, al elemento que se está calificando y la calificación implícita. En esta sección, crearás la tabla con las columnas userid, itemId y session_duration, en la que session_duration contiene la duración de la sesión del usuario en la página del elemento del producto determinado.

Sigue estos pasos para crear esta tabla mediante los datos del conjunto de datos de muestra de Google Analytics:

  1. Abre el conjunto de datos de muestra de Google Analytics en Google Cloud Marketplace y haz clic en Ver conjunto de datos (View Dataset). Esto abre la consola de BigQuery con el conjunto de datos de muestra de Google Analytics seleccionado.
  2. En la sección Recursos (Resources), selecciona el proyecto en el que completaste este instructivo.
  3. Haz clic en Crear conjunto de datos.

    Muestra la ubicación del botón Crear conjunto de datos

  4. En la página Crear conjunto de datos:

    • En ID del conjunto de datos (Dataset ID), ingresa bqml.
    • En Ubicación de los datos (Data location), elige la ubicación más cercana a ti.
    • Haz clic en Crear conjunto de datos (Create dataset).
  5. Sigue este paso si planeas exportar los datos a Analytics 360; de lo contrario, ignóralo.

    En el panel Editor de consultas (Query editor), ejecuta la siguiente instrucción de SQL para copiar un subconjunto de datos de muestra de Google Analytics en una tabla nueva y propagar el campo clientId, que usarás como la clave para agregar comentarios implícitos del usuario en el siguiente paso:

    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;
    

    Debes usar clientId como el campo clave cuando importas datos del público a Analytics 360. Por lo general, clientId es una versión con hash de fullVisitorId, pero no se propaga en el conjunto de datos de muestra de Google Analytics. Para propagar clientId en tus propios datos de Analytics 360, debes crear una dimensión personalizada y propagarla.

  6. Ejecuta la siguiente instrucción de SQL para crear una tabla que contenga los datos de entrenamiento. Ejecuta la versión que usa el campo clientId como clave si planeas exportar los datos a Analytics 360. Ejecuta la versión que usa el campo fullVisitorId como clave si planeas usar los datos con otros 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. Ejecuta la siguiente instrucción de SQL para ver una muestra de la fecha en la tabla bqml.aggregate_web_stats resultante:

    SELECT
     *
    FROM
      bqml.aggregate_web_stats
    LIMIT
      10;
    

    Deberías ver resultados similares a los siguientes:

    Primeras 10 filas de datos de entrenamiento procesados

Compra ranuras flexibles

Si usas precios a pedido para BigQuery, debes comprar ranuras flexibles y, luego, crearles reservas y asignaciones a fin de entrenar un modelo de factorización de matrices. Puedes omitir esta sección si usas precios de tasa fija con BigQuery.

Debes tener el permiso bigquery.reservations.create para poder comprar ranuras flexibles. Este permiso se otorga al propietario del proyecto y a las funciones predefinidas de la administración de identidades y accesos de bigquery.admin y bigquery.resourceAdmin.

  1. En la consola de BigQuery, haz clic en Reservas.
  2. Si se te redirecciona a la página API de reservas de BigQuery para habilitar la API, haz clic en Habilitar. De lo contrario, continúa con el paso siguiente.
  3. En la página Reservas, haz clic en Comprar ranuras.
  4. En la página Comprar ranuras, configura las opciones de la siguiente manera:

    1. En Duración de la confirmación, elige Flex.
    2. En Ubicación, elige la ubicación que seleccionaste cuando creaste el conjunto de datos durante el procedimiento Procesa los datos de muestra.
    3. En Cantidad de ranuras, elige 500.
    4. Haz clic en Siguiente.
    5. En Purchase confirmation, escribe CONFIRM.

  5. Haz clic en Comprar.

  6. Haz clic en Ver compromisos de ranuras.

  7. Espera 20 minutos para que se aprovisione la capacidad. Después de aprovisionar la capacidad, el estado del compromiso de ranuras se vuelve verde y muestra una marca de verificación .

  8. Haz clic en Crear reserva.

  9. En la página Crear reserva, configura las opciones de la siguiente manera:

    1. En Nombre de reserva, escribe model.
    2. En Ubicación, elige la ubicación en la que compraste las ranuras flexibles.
    3. En Cantidad de ranuras, escribe 500.
    4. Haz clic en Guardar. Esto te vuelve a llevar a la página Reservas.
  10. Selecciona la pestaña Assignments.

  11. En Selecciona una organización, una carpeta o un proyecto, haz clic en Explorar.

  12. Escribe el nombre del proyecto en el que completaste este instructivo.

  13. Haz clic en Seleccionar.

  14. En Reserva, elige la reserva modelo que creaste.

  15. Haz clic en Crear.

  16. Haz clic en BigQuery para volver a la consola de BigQuery.

Crea, entrena e implementa el modelo

Ejecuta la instrucción de SQL CREATE MODEL para crear, entrenar e implementar el modelo de factorización de matrices:

      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;

Una vez que finaliza el entrenamiento, el modelo entrenado se implementa como bqml.retail_recommender.

Usa el modelo entrenado para hacer predicciones

Usa la función de SQL ML.RECOMMEND para obtener predicciones del modelo de bqml.retail_recommender implementado.

  1. Para ver un ejemplo de los datos de recomendaciones, ejecuta la siguiente instrucción de SQL a fin de obtener predicciones que representen las 5 recomendaciones principales para un 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;
    

    Deberías ver resultados similares a los siguientes:

    Las 5 recomendaciones principales para un ID de usuario determinado

  2. Ejecuta la siguiente instrucción de SQL para obtener las 5 predicciones principales para todos los usuarios. Esto genera una gran cantidad de filas, por lo que este resultado se escribe en una tabla y, luego, se recuperan los primeros diez registros para que puedas ver un ejemplo de los datos.

    -- 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;
    

    Deberías ver resultados similares a los siguientes:

    Las primeras 10 recomendaciones para todos los usuarios.

Usa las recomendaciones previstas en la producción

Una vez que tengas las recomendaciones, la forma en que las pongas a disposición de tu canalización de producción dependerá de tu caso de uso. En las siguientes secciones, se describe cómo exportar datos de predicción a Analytics 360 o Cloud Storage, o leer datos de BigQuery de manera programática en un DataFrame de Pandas.

Exporta recomendaciones a Analytics 360

Si deseas exportar datos a Analytics 360, te recomendamos que proporcione una columna para cada producto que califique la probabilidad de que el cliente compre ese producto, algo similar a lo siguiente:

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

Para crear una columna de “probabilidad de compra” por producto, debes crear un procedimiento pivot(), como se describe en Easy pivot() in BigQuery, in one step (Pivot fácil en BigQuery, en un paso).

  1. Ejecuta la siguiente instrucción de SQL para crear el procedimiento de 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. Ejecuta la siguiente instrucción de SQL a fin de crear una tabla que contenga las columnas clientId y “probabilidad de compra” para cada producto:

    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. Ejecuta la siguiente instrucción de SQL para ver una muestra de la fecha en la tabla bqml.prod_recommendations_export resultante:

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

    Deberías ver resultados similares a los siguientes:

    Las primeras 10 recomendaciones para todos los usuarios.

Una vez que tengas los datos en el formato correcto, guárdalos como un archivo CSV y, luego, usa Importación de datos para importarlos a Analytics 360. Ten en cuenta que los nombres de las columnas en los datos de recomendaciones exportados deben mapearse al esquema de importación de datos de Analytics 360. Por ejemplo, si el esquema de importación de datos es ga:clientId, ga:dimension1, ga:dimension2, los nombres de columna en tus datos deben ser ga:clientId, ga:dimension1, ga:dimension2. BigQuery no permite el uso de dos puntos en los nombres de las columnas, por lo que debes actualizar los nombres de las columnas en el archivo CSV exportado antes de importarlo.

Si lo deseas, puedes usar la implementación de referencia MoDeM (Model Deployment for Marketing) [MoDeM (Implementación de modelos para marketing)] para BigQuery ML models (modelos de BigQuery ML) a fin de facilitar la carga de datos en Analytics 360. Usa las instrucciones interactivas que aparecen en BQML Deployment Template notebook (notebook de plantillas de implementación de BQML) para comenzar.

Exporta recomendaciones a Cloud Storage

Para exportar los datos de recomendaciones de la tabla de BigQuery a Cloud Storage, sigue las instrucciones que aparecen en Exporta datos de tablas.

Lee recomendaciones de manera programática

Lee los datos de recomendaciones de la tabla de BigQuery en un dataframe de Pandas mediante la API de BigQuery Storage. Para ello, sigue las instrucciones que aparecen en Descarga datos de tablas mediante la biblioteca cliente de BigQuery. Como alternativa, puedes usar una de las bibliotecas cliente de BigQuery para programar tu propia solución.

Resumen

Ya completaste el instructivo y ahora sabes cómo entrenar tu sistema recomendador con BigQuery ML, implementar tu modelo y usar los resultados en producción.

Limpia

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos que usaste en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto, pero borra solo esos recursos.

De cualquier manera, debes quitar esos recursos para que no se te cobre por ellos en el futuro. En las siguientes secciones, se describe cómo borrar estos recursos.

Borra el proyecto

La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el instructivo.

  1. En Cloud Console, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  3. En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

Borra los componentes

Si no deseas borrar el proyecto, usa las siguientes secciones para borrar los componentes facturables de este instructivo.

Borra el conjunto de datos de BigQuery

  1. Abre la consola de BigQuery
  2. En la sección Recursos, expande el proyecto en el que estás completando este instructivo y selecciona el conjunto de datos bqml.
  3. Haz clic en Borrar conjunto de datos en el encabezado del panel del conjunto de datos.
  4. En la ventana de superposición que aparece, escribe bqml y, a continuación, haz clic en Borrar.

Borra ranuras flexibles

Si creaste ranuras flexibles, sigue estos pasos para borrarlas:

  1. En la consola de BigQuery, haz clic en Reservas.
  2. Selecciona la pestaña Assignments.
  3. Busca la fila de la tarea que creaste para la reserva del modelo, haz clic en Más en la columna Acciones y, luego, en Borrar.
  4. Selecciona la pestaña Reservas.
  5. Ubica la fila de la reserva del modelo, haz clic en Más en la columna Acciones y, luego, haz clic en Borrar.
  6. Selecciona la pestaña Slot Commitments.
  7. Ubica la fila que contiene las 500 ranuras flexibles que adquiriste, haz clic en Más en la columna Acciones y, luego, haz clic en Borrar.
  8. En Confirma la eliminación del compromiso de ranura, escribe REMOVE.
  9. Haz clic en Continuar.

¿Qué sigue?