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:
- Generar datos
- Entrenar el modelo
- Obtener las ponderaciones y la intersección
- Simular la predicción
- 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;