É possível fazer previsões através de um modelo de regressão logística ou linear existente
com ponderações conhecidas sem usar ML.PREDICT, mesmo não tendo acesso ao próprio
modelo. Para tal, precisa de uma solução alternativa que permita usar modelos de regressão de privacidade diferencial (PD) em consultas de ativação de públicos-alvo no Ads Data Hub.
Este exemplo passo a passo ensina a realizar a inferência simulada de modelos reais de regressão logística binária e linear e, em seguida, a comparar os resultados com os de ML.PREDICT para mostrar a precisão dos resultados simulados.
É mostrado também um exemplo prático de como criar uma lista de públicos-alvo com um modelo logístico binário, que se usaria para aplicar um modelo de conversão à ativação de públicos-alvo.
Vista geral do exemplo:
- Gere dados
- Prepare o modelo
- Obtenha as ponderações e a interceção
- Simule a previsão
- Compare resultados
Exemplo passo a passo
1. Gere dados
Crie uma tabela com dados simulados para preparar o modelo. Marque uma fração das linhas para o conjunto do holdback.
Regressão linear
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
Regressão logística binária
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. Prepare o modelo
Prepare um modelo de regressão a partir do conjunto de preparação.
Regressão linear
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
Tenha em atenção que adicionámos ruído suficiente aos dados simulados para obter um modelo com R2 = 0,9009.
| Medição | Valor |
|---|---|
| Erro absoluto médio | 0,7359 |
| Erro quadrático médio | 0,8432 |
| Erro de registo quadrático médio | 0,0810 |
| Erro absoluto mediano | 0,6239 |
| R ao quadrado | 0,9009 |
Regressão logística binária
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 da amostra. Repare na precisão de 0,9260.
| Medição | Valor |
|---|---|
| Classe positiva | 1 |
| Classe negativa | 0 |
| Precisão | 0,0810 |
| Recordação | 0,9315 |
| Precisão | 0,9260 |
| Pontuação de F1 | 0,9328 |
Os valores a negrito nesta matriz de confusão mostram a frequência com que o modelo classificou cada etiqueta corretamente, enquanto os valores que não estão a negrito mostram a frequência com que o modelo classificou incorretamente cada etiqueta.
| Etiqueta verdadeira | Etiqueta prevista 1 | Etiqueta prevista 2 |
|---|---|---|
| 1 | 93% | 7% |
| 0 | 8% | 92% |
3. Obtenha as ponderações e a interceção
Obtenha as ponderações e a interceção do modelo:
Regressão linear
SELECT
*
FROM
ML.WEIGHTS(MODEL `DATASET_NAME.LIN_REG_MODEL`)
| ponderação | 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 |
| INTERCEÇÃO | -4,1428754911504306 |
Regressão logística binária
SELECT
*
FROM
ML.WEIGHTS(MODEL `DATASET_NAME.BIN_LOG_REG_MODEL`)
| ponderação | 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 |
| INTERCEÇÃO | -17,922169920 |
4. Simule a previsão
Regressão linear
Use o produto escalar dos valores das funcionalidades com as ponderações e adicione a interceção para fazer a previsão através da SQL (linguagem de consulta estruturada) padrão sem usar ML.PREDICT. Esta consulta compara as previsões que usam esta técnica com as que usam ML.PREDICT. Observe como as linhas SQL a negrito executam o produto escalar dos valores das funcionalidades para a linha com as ponderações do modelo e, em seguida, adicionam a interceção.
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
Regressão logística binária
Na regressão logística binária, a técnica para simular as previsões é muito semelhante à regressão linear, mas a primeira aplica adicionalmente a função sigmoide no último passo com o limite pretendido.
Use o produto escalar dos valores das funcionalidades com as ponderações e adicione a interceção para fazer a previsão através da SQL padrão sem usar ML.PREDICT.
Em seguida, use a função sigmoide com um limite de 0,5 no resultado para prever 0 ou 1. Esta consulta compara as previsões que usam esta técnica com as que usam 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
O bloco de código SQL a negrito na consulta acima executa o produto escalar dos valores das funcionalidades para cada linha com as ponderações do modelo e adiciona a interceção para obter a previsão de regressão linear:
IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
Em seguida, aplica a função sigmoide Y = 1 / (1+e^-z) ao produto escalar e à interceção através da SQL padrão:
IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
Por último, o resultado da função sigmoide é comparado com o valor do limite de 0,5 para chegar à previsão de regressão lógica binária de 0, se for inferior a 0,5, ou 1, se não for. Tenha em atenção que pode usar qualquer valor do limite entre 0 e 1.
IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
Esta técnica também pode ser alargada à regressão logística multiclasse. Nesse caso, as ponderações do modelo seriam uma matriz nxn, em vez de um vetor, e as ponderações seriam um vetor, e não um escalar. Multiplicaria o vetor de valores das funcionalidades pela matriz de ponderações e adicionaria o vetor de interceção. O vetor resultante teria uma pontuação para cada etiqueta, e poderia escolher a etiqueta com a pontuação mais alta para a previsão. Se quisesse devolver uma matriz de probabilidade, aplicaria a função sigmoide a cada elemento da matriz.
5. Compare resultados
Regressão linear
Com exceção de um pequeno erro de arredondamento, os resultados da amostra são quase idênticos.
| actual_label | ml_predicted_label | sql_predicted_label | diff_is_negligible |
|---|---|---|---|
| 6 | 5,2062349420751834 | 5,2062349420751826 | verdadeiro |
| 0 | 0,40318472770048075 | 0,403184727700479 | verdadeiro |
| 3 | 3,0703766078249597 | 3,0703766078249597 | verdadeiro |
| 7 | 7,0588171538562 | 7,0588171538562 | verdadeiro |
| 6 | 6,7802375930646 | 6,7802375930646 | verdadeiro |
| 6 | 5,1088569571339368 | 5,1088569571339377 | verdadeiro |
| 4 | 4,051839078116874 | 4,051839078116874 | verdadeiro |
| 4 | 5,1810254680219243 | 5,1810254680219234 | verdadeiro |
| 6 | 6,1440349466401223 | 6,1440349466401205 | verdadeiro |
| 1 | 2,0842399472783519 | 2,0842399472783519 | verdadeiro |
| 2 | 2,1911209811886847 | 2,1911209811886838 | verdadeiro |
| 3 | 3,0236086790006622 | 3,0236086790006613 | verdadeiro |
| 2 | 2,573083132964213 | 2,5730831329642125 | verdadeiro |
| 7 | 5,68662973136732 | 5,6866297313673186 | verdadeiro |
| 9 | 8,1860026312677938 | 8,1860026312677938 | verdadeiro |
Regressão logística binária
A comparação da inferência simulada com os resultados reais de ML.PREDICT é perfeita. Não há nenhuma contradição no conjunto do holdback de 10 mil linhas. Há algumas linhas em que ML.PREDICT e a inferência simulada não coincidem com a etiqueta real. Isto é esperado, pois a precisão do modelo ronda os 93% e há valores pequenos, mas diferentes de zero, nas células fora da diagonal da matriz de confusão.
| actual_label | ml_predicted_label | sql_predicted_label | simulation_is_accurate |
|---|---|---|---|
| 0 | 1 | 1 | verdadeiro |
| 0 | 0 | 0 | verdadeiro |
| 0 | 0 | 0 | verdadeiro |
| 0 | 0 | 0 | verdadeiro |
| 0 | 0 | 0 | verdadeiro |
| 0 | 0 | 0 | verdadeiro |
| 0 | 0 | 0 | verdadeiro |
| 0 | 0 | 0 | verdadeiro |
| 0 | 0 | 0 | verdadeiro |
| 0 | 0 | 0 | verdadeiro |
| 0 | 1 | 1 | verdadeiro |
| 0 | 0 | 0 | verdadeiro |
Crie uma lista de ativação de públicos-alvo com a aprendizagem automática
Um exemplo de utilização típico seria criar um modelo de regressão logística binária de privacidade diferencial para prever conversões e, em seguida, aplicar a inferência neste modelo durante a criação de uma lista de públicos-alvo. Suponhamos que o modelo logístico binário criado no exemplo acima está a modelar conversões e que cada linha nos conjuntos de preparação e avaliação representa um utilizador distinto.
A consulta seguinte mostra como criar uma lista de públicos-alvo com esses utilizadores que, segundo a previsão do modelo, irão fazer conversões:
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;