Puedes realizar predicciones con un modelo de regresión lineal o logística existente con pesos conocidos sin usar ML.PREDICT, incluso sin acceso al modelo en sí. Para ello, debes usar una solución alternativa para usar modelos de regresión con privacidad diferencial (DP) dentro de las consultas de activación de públicos en Centro de Datos de Anuncios.
En este ejemplo paso a paso, aprenderás a realizar la inferencia simulada para los modelos de regresión logística lineal y binaria reales, y, luego, compararás los resultados con los de ML.PREDICT para mostrar la exactitud de los resultados simulados.
También se mostrará un ejemplo práctico de cómo crear una lista de público con un modelo logístico binario, que se usaría para aplicar un modelo de conversión a la activación del público.
Descripción general del ejemplo:
- Genera datos
- Entrena el modelo
- Obtén los pesos y la intersección
- Simula la predicción
- Comparar resultados
Ejemplo paso a paso
1. Genera datos
Crea una tabla con datos simulados para entrenar el modelo. Marca una fracción de las filas para el conjunto de datos de exclusió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. Entrena el modelo
Entrena un modelo de regresión a partir 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 agregamos 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 logarítmico cuadrático medio | 0.0810 |
| Mediana de error absoluto | 0.6239 |
| R al cuadrado | 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 muestra Observa la exactitud de 0.9260.
| Medición | Valor |
|---|---|
| Clase positiva | 1 |
| Clase negativa | 0 |
| Precisión | 0.0810 |
| Recuperación | 0.9315 |
| Exactitud | 0.9260 |
| Puntuación F1 | 0.9328 |
Los valores en negrita de esta matriz de confusión muestran la frecuencia con la que el modelo clasificó correctamente cada etiqueta, y los valores sin negrita muestran la frecuencia con la que el modelo clasificó incorrectamente cada etiqueta.
| Etiqueta de confianza | Etiqueta predicha 1 | Etiqueta predicha 2 |
|---|---|---|
| 1 | 93% | 7% |
| 0 | 8% | 92% |
3. Obtén los pesos y la intersección
Obtén los pesos y la intersección del modelo:
Regresión lineal
SELECT
*
FROM
ML.WEIGHTS(MODEL `DATASET_NAME.LIN_REG_MODEL`)
| peso | 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`)
| peso | 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. Simula la predicción
Regresión lineal
Usa el producto escalar de los valores de las características con los pesos y agrega la intersección para realizar la predicción con SQL estándar sin usar ML.PREDICT. Esta consulta compara las predicciones que se obtienen con esta técnica con las que se obtienen con ML.PREDICT. Observa cómo las líneas de SQL en negrita realizan el producto escalar de los valores de los atributos para la fila con los pesos del modelo y, luego, agregan la intersecció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 de la regresión lineal, con la adición de aplicar la función sigmoidea en el último paso con el umbral deseado.
Usa el producto escalar de los valores de las características con los pesos y agrega la intersección para realizar la predicción con SQL estándar sin usar ML.PREDICT.
Luego, usa la función sigmoidea con un umbral de 0.5 en el resultado para predecir 0 o 1. Esta consulta compara las predicciones que se obtienen con esta técnica con las que se obtienen con 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 realiza el producto escalar de los valores de los atributos para cada fila con los pesos del modelo y agrega 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)
Luego, aplica la función sigmoide Y = 1 / (1+e^-z) al producto escalar y a la intersección, con SQL estándar:
IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
Por último, el resultado de la función sigmoidea se compara con el valor de umbral de 0.5 para llegar a la predicción de regresión logística binaria de 0, si es menor que 0.5, o 1, si no lo es. Ten en cuenta que puedes usar cualquier valor de 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 extender a la regresión logística multiclase. En ese caso, los pesos del modelo serán una matriz de nxn, en lugar de un vector, y los pesos serían un vector en lugar de un escalar. Multiplicarías el vector de valores de las características por la matriz de pesos y sumarías el vector de intersección. El vector resultante tendría una puntuación para cada etiqueta, y podrías elegir la etiqueta con la puntuación más alta para tu predicción. Si quisieras devolver un array de probabilidades, aplicarías la función sigmoide a cada elemento del array.
5. Comparar resultados
Regresión lineal
Los resultados de la muestra son casi idénticos, excepto por un pequeño error de redondeo.
| actual_label | ml_predicted_label | sql_predicted_label | diff_is_negligible |
|---|---|---|---|
| 6 | 5.2062349420751834 | 5.2062349420751826 | verdadero |
| 0 | 0.40318472770048075 | 0.403184727700479 | verdadero |
| 3 | 3.0703766078249597 | 3.0703766078249597 | verdadero |
| 7 | 7.0588171538562 | 7.0588171538562 | verdadero |
| 6 | 6.7802375930646 | 6.7802375930646 | verdadero |
| 6 | 5.1088569571339368 | 5.1088569571339377 | verdadero |
| 4 | 4.051839078116874 | 4.051839078116874 | verdadero |
| 4 | 5.1810254680219243 | 5.1810254680219234 | verdadero |
| 6 | 6.1440349466401223 | 6.1440349466401205 | verdadero |
| 1 | 2.0842399472783519 | 2.0842399472783519 | verdadero |
| 2 | 2.1911209811886847 | 2.1911209811886838 | verdadero |
| 3 | 3.0236086790006622 | 3.0236086790006613 | verdadero |
| 2 | 2.573083132964213 | 2.5730831329642125 | verdadero |
| 7 | 5.68662973136732 | 5.6866297313673186 | verdadero |
| 9 | 8.1860026312677938 | 8.1860026312677938 | verdadero |
Regresión logística binaria
La comparación de la inferencia simulada con los resultados reales de ML.PREDICT es perfecta: no hay una sola contradicción en el conjunto de datos de exclusión de 10,000 filas. Hay algunas filas en las que tanto ML.PREDICT como la inferencia simulada no coinciden con la etiqueta real, y eso es lo esperado, ya que la exactitud 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 | verdadero |
| 0 | 0 | 0 | verdadero |
| 0 | 0 | 0 | verdadero |
| 0 | 0 | 0 | verdadero |
| 0 | 0 | 0 | verdadero |
| 0 | 0 | 0 | verdadero |
| 0 | 0 | 0 | verdadero |
| 0 | 0 | 0 | verdadero |
| 0 | 0 | 0 | verdadero |
| 0 | 0 | 0 | verdadero |
| 0 | 1 | 1 | verdadero |
| 0 | 0 | 0 | verdadero |
Crea una lista de activación del público con AA
Un caso de uso típico sería crear un modelo de regresión logística binaria con privacidad diferencial para predecir conversiones y, luego, aplicar la inferencia en este modelo mientras se crea una lista de público. Supongamos que el modelo de regresión logística binaria creado en el ejemplo anterior modela las conversiones y que cada fila de los conjuntos de entrenamiento y evaluación representa a un usuario distinto.
En la siguiente consulta, se muestra cómo crear una lista de público con los usuarios que, según la predicción del modelo, realizarán conversiones:
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;