Modelización mediante regresión para listas de remarketing

Puedes hacer predicciones usando un modelo de regresión lineal o logística con ponderaciones conocidas sin usar ML.PREDICT, incluso sin tener acceso al propio modelo. Para hacerlo, tienes que emplear una solución alternativa para usar modelos de regresión de privacidad diferencial en las consultas de activación de audiencias del Centro de Datos de Anuncios.

En este ejemplo paso a paso aprenderás a hacer la inferencia simulada para modelos de regresión logística lineal y binaria, y luego comparar los resultados con los de ML.PREDICT para mostrar la precisión de los resultados simulados. También verás un ejemplo práctico de cómo crear una lista de remarketing con un modelo logístico binario que se utilizaría para aplicar un modelo de conversión a la activación de audiencias.

Descripción general del ejemplo:

  1. Generar datos
  2. Entrenar el modelo
  3. Obtener las ponderaciones y la intersección
  4. Simular la predicción
  5. Comparar resultados

Ejemplo paso a paso

1. Generar datos

Crea una tabla con datos simulados para entrenar el modelo. Marca una fracción de las filas del conjunto de retención.

Regresión lineal

CREATE OR REPLACE TABLE DATASET_NAME.LIN_REG_TRAINING_SET AS
  WITH
  A AS (
    SELECT
      *
    FROM
      UNNEST(GENERATE_ARRAY(1, 100000)) AS row_number),
  B AS (
    SELECT
      row_number,
      RAND() AS rand_label,
      RAND() AS rand_feature_1,
      RAND() AS rand_feature_2,
      RAND() AS rand_feature_3,
      RAND() AS rand_feature_4,
      RAND() AS rand_feature_5,
      RAND() AS rand_feature_6,
      RAND() AS rand_feature_7,
      RAND() AS rand_feature_8,
      RAND() AS rand_feature_9,
      RAND() AS rand_feature_10
    FROM
      A),
  C AS (
    SELECT
      rand_label AS label,
      *
    FROM
      B),
  D AS (
    SELECT
    row_number,
    CAST(round(10 * label) AS INT64) AS label,
    (rand_label + rand_feature_1) / 2 AS feature_1,
    (rand_label + rand_feature_2) / 2 AS feature_2,
    (rand_label + rand_feature_3) / 2 AS feature_3,
    (rand_label + rand_feature_4) / 2 AS feature_4,
    (rand_label + rand_feature_5) / 2 AS feature_5,
    (rand_label + rand_feature_6) / 2 AS feature_6,
    (rand_label + rand_feature_7) / 2 AS feature_7,
    (rand_label + rand_feature_8) / 2 AS feature_8,
    (rand_label + rand_feature_9) / 2 AS feature_9,
    (rand_label + rand_feature_10) / 2 AS feature_10
    FROM
    C)

SELECT
  label,
  feature_1,
  feature_2,
  feature_3,
  feature_4,
  feature_5,
  feature_6,
  feature_7,
  feature_8,
  feature_9,
  feature_10,
  RAND() < 0.1 AS holdback -- Ten percent will be true.
FROM
  D

Regresión logística binaria

SELECT
  CASE
    WHEN label < 5 THEN 0
    WHEN label >= 5 THEN 1
  END
  AS label,
  * EXCEPT (label)
FROM
  `DATASET_NAME.BIN_LOG_REG_TRAINING_SET`

2. Entrenar el modelo

Entrena un modelo de regresión del conjunto de entrenamiento.

Regresión lineal

CREATE OR REPLACE MODEL `DATASET_NAME.LIN_REG_MODEL` OPTIONS (model_type="linear_reg") AS
  SELECT
    * except (holdback)
  FROM
    `DATASET_NAME.LIN_REG_TRAINING_SET`
  WHERE
    NOT holdback

Ten en cuenta que hemos añadido suficiente ruido a los datos simulados para obtener un modelo con R2 = 0.9009.

Medición Valor
Error absoluto medio 0.7359
Error cuadrático medio 0.8432
Error de registro cuadrático medio 0.0810
Error mediano absoluto 0.6239
R cuadrático 0.9009

Regresión logística binaria

CREATE OR REPLACE MODEL `DATASET_NAME.BIN_LOG_REG_MODEL` OPTIONS (model_type="logistic_reg") AS
  SELECT
    * EXCEPT (holdback)
  FROM
    `DATASET_NAME.BIN_LOG_REG_TRAINING_SET`
  WHERE
    NOT holdback

Resultados de ejemplo. Ten en cuenta la precisión de 0.9260.

Medición Valor
Clase positiva 1
Clase negativa 0
Precisión 0.0810
Recuerdo 0.9315
Precisión 0.9260
Puntuación F1 0.9328

Los valores en negrita de esta matriz de confusión indican con qué frecuencia el modelo ha clasificado correctamente cada etiqueta, y los valores que no están en negrita indican con qué frecuencia el modelo ha clasificado erróneamente cada etiqueta.

Etiqueta verdadera Etiqueta prevista 1 Etiqueta prevista 2
1 93 % 7 %
0 8 % 92 %

3. Obtener las ponderaciones y la intersección

Consulta las ponderaciones y la intersección del modelo:

Regresión lineal

SELECT
  *
FROM
  ML.WEIGHTS(MODEL `DATASET_NAME.LIN_REG_MODEL`)
weight category_weights.category
feature_1 1.8263055528635743
feature_2 1.8143804404490813
feature_3 1.8601204874033492
feature_4 1.8507603439031859
feature_5 1.7899764387123640
feature_6 1.8645246630251291
feature_7 1.8698005281925356
feature_8 1.7904637080330201
feature_9 1.8036887855406274
feature_10 1.8117115890624449
INTERCEPT -4.1428754911504306

Regresión logística binaria

SELECT
  *
FROM
  ML.WEIGHTS(MODEL `DATASET_NAME.BIN_LOG_REG_MODEL`)
weight category_weights.category
feature_1 3.823533928
feature_2 3.734812819
feature_3 3.842239823
feature_4 3.785488823
feature_5 3.737386716
feature_6 3.567663961
feature_7 3.819643052
feature_8 3.734673763
feature_9 3.839301406
feature_10 3.787306994
INTERCEPT -17.922169920

4. Simular la predicción

Regresión lineal

Usa el producto escalar de los valores de funciones con las ponderaciones y añade la intersección para hacer la predicción con SQL estándar sin usar ML.PREDICT. Esta consulta compara las predicciones que usan esta técnica con las que usan ML.PREDICT. Observa cómo las líneas de SQL en negrita realizan el producto escalar de los valores de la función de la fila con las ponderaciones del modelo y luego añaden la intercepción.

WITH
T AS (
SELECT
  label AS actual_label,
  predicted_label AS ml_predicted_label,
  [feature_1,
  feature_2,
  feature_3,
  feature_4,
  feature_5,
  feature_6,
  feature_7,
  feature_8,
  feature_9,
  feature_10] AS features,
  [1.8263055528635743,
  1.8143804404490813,
  1.8601204874033492,
  1.8507603439031859,
  1.789976438712364,
  1.8645246630251291,
  1.8698005281925356,
  1.7904637080330201,
  1.8036887855406274,
  1.8117115890624449] AS weights
FROM
  ML.PREDICT(MODEL `DATASET_NAME.LIN_REG_MODEL`,
    (
    SELECT
      *
    FROM
      `PROJECT_NAME.DATASET_NAME.LIN_REG_TRAINING_SET`))
WHERE
  holdback),
P AS (
SELECT
  actual_label,
  ml_predicted_label,
  (
   SELECT
    SUM(element1 * element2) - 4.1428754911504306
  FROM
    T.features element1
  WITH
  OFFSET
    pos
  JOIN
    T.weights element2
  WITH
  OFFSET
    pos
  USING
    (pos) ) sql_predicted_label,
  features,
  weights
FROM
  T)
SELECT
  actual_label,
  ml_predicted_label,
  sql_predicted_label,
  ABS(ml_predicted_label - sql_predicted_label) < 0.00000000001 AS diff_is_negligible
FROM
  P

Regresión logística binaria

En el caso de la regresión logística binaria, la técnica para simular las predicciones es muy similar a la regresión lineal, pero además se aplica la función sigmoide en el último paso con el umbral deseado.

Usa el producto escalar de los valores de funciones con las ponderaciones y añade la intersección para hacer la predicción con SQL estándar sin usar ML.PREDICT. A continuación, usa la función sigmoide con un umbral de 0,5 en el resultado para predecir 0 o 1. Esta consulta compara las predicciones que usan esta técnica con las que usan ML.PREDICT.

WITH
T AS (
SELECT
  label AS actual_label,
  predicted_label AS ml_predicted_label,
  [feature_1,
  feature_2,
  feature_3,
  feature_4,
  feature_5,
  feature_6,
  feature_7,
  feature_8,
  feature_9,
  feature_10] AS features,
  [3.8235339279050287,
  3.7348128191185244,
  3.8422398227859471,
  3.7854888232502479,
  3.7373867156553713,
  3.5676639605351026,
  3.8196430517007811,
  3.7346737628343032,
  3.8393014063170749,
  3.7873069939244743] AS weights
FROM
  ML.PREDICT(MODEL `DATASET_NAME.BIN_LOG_REG_MODEL`,
    (
    SELECT
      *
    FROM
      `PROJECT_NAME.DATASET_NAME.BIN_LOG_REG_TRAINING_SET`))
WHERE
  holdback),
P AS (
SELECT
  actual_label,
  ml_predicted_label,
  (
   SELECT
    IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
  FROM
    T.features element1
  WITH
  OFFSET
    pos
  JOIN
    T.weights element2
  WITH
  OFFSET
    pos
  USING
    (pos) ) sql_predicted_label,
  features,
  weights
FROM
  T)
SELECT
  actual_label,
  ml_predicted_label,
  sql_predicted_label,
  ml_predicted_label = sql_predicted_label AS simulation_is_accurate
FROM
  P

El bloque de código SQL en negrita de la consulta anterior hace el producto escalar de los valores de función de cada fila con las ponderaciones del modelo y añade la intersección para obtener la predicción de regresión lineal:

IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)

Después, aplica la función sigmoide Y = 1 / (1+e^-z) al producto escalar y la intersección mediante SQL estándar:

IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)

Por último, el resultado de la función sigmoide se compara con el valor del umbral de 0,5 para obtener la predicción de regresión logística binaria de 0, si el valor es inferior a 0,5, o de 1, si no lo es. Puedes usar cualquier umbral entre 0 y 1.

IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)

Esta técnica también se puede aplicar a la regresión logística multiclase. En ese caso, las ponderaciones del modelo serán una matriz nxn en lugar de un vector, y las ponderaciones serán un vector en lugar de un escalar. Multiplica el vector de valores de la función por la matriz de ponderaciones y suma el vector de intersección. El vector resultante tendrá una puntuación para cada etiqueta, y podrás elegir la etiqueta con la puntuación más alta de tu predicción. Si quieres devolver una matriz de probabilidad, aplica la función sigmoide a cada elemento de la matriz.

5. Comparar resultados

Regresión lineal

Los resultados de muestra son casi idénticos, salvo por un pequeño error de redondeo.

actual_label ml_predicted_label sql_predicted_label diff_is_negligible
6 5.2062349420751834 5.2062349420751826 true
0 0.40318472770048075 0.403184727700479 true
3 3.0703766078249597 3.0703766078249597 true
7 7.0588171538562 7.0588171538562 true
6 6.7802375930646 6.7802375930646 true
6 5.1088569571339368 5.1088569571339377 true
4 4.051839078116874 4.051839078116874 true
4 5.1810254680219243 5.1810254680219234 true
6 6.1440349466401223 6.1440349466401205 true
1 2.0842399472783519 2.0842399472783519 true
2 2.1911209811886847 2.1911209811886838 true
3 3.0236086790006622 3.0236086790006613 true
2 2.573083132964213 2.5730831329642125 true
7 5.68662973136732 5.6866297313673186 true
9 8.1860026312677938 8.1860026312677938 true

Regresión logística binaria

La comparación de la inferencia simulada con los resultados reales de ML.PREDICT es perfecta, no hay ni una contradicción en el conjunto de retención de 10.000 filas. En algunas filas, ML.PREDICT y la inferencia simulada no coinciden con la etiqueta real, lo cual es de esperar puesto que la precisión del modelo es de aproximadamente el 93 % y hay valores pequeños pero distintos de cero en las celdas fuera de la diagonal de la matriz de confusión.

actual_label ml_predicted_label sql_predicted_label simulation_is_accurate
0 1 1 true
0 0 0 true
0 0 0 true
0 0 0 true
0 0 0 true
0 0 0 true
0 0 0 true
0 0 0 true
0 0 0 true
0 0 0 true
0 1 1 true
0 0 0 true

Crear una lista de activación de audiencias con aprendizaje automático

Un caso práctico típico sería crear un modelo de regresión logística binaria de privacidad diferencial para predecir las conversiones y, después, aplicar la inferencia al modelo a la vez que se crea una lista de remarketing. Supongamos que el modelo logístico binario creado en el ejemplo anterior modeliza las conversiones y que cada fila de los conjuntos de entrenamiento y evaluación representa a un usuario único.

La siguiente consulta muestra cómo crear una lista de remarketing con los usuarios que el modelo predice que completarán una conversión:

WITH
T AS (
SELECT
  *,
  label AS actual_label,
  [feature_1,
  feature_2,
  feature_3,
  feature_4,
  feature_5,
  feature_6,
  feature_7,
  feature_8,
  feature_9,
  feature_10] AS features,
  [3.8235339279050287,
  3.7348128191185244,
  3.8422398227859471,
  3.7854888232502479,
  3.7373867156553713,
  3.5676639605351026,
  3.8196430517007811,
  3.7346737628343032,
  3.8393014063170749,
  3.7873069939244743] AS weights
FROM
  `PROJECT_NAME.DATASET_NAME.BIN_LOG_REG_TRAINING_SET`
WHERE
  holdback),
P AS (
SELECT
  *,
  (
  SELECT
  IF
    ((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
  FROM
    T.features element1
  WITH
  OFFSET
    pos
  JOIN
    T.weights element2
  WITH
  OFFSET
    pos
  USING
    (pos) ) predicted_label,
  features,
  weights
FROM
  T),
SELECT
  user_id
FROM
  P
WHERE
  predicted_label = 1;