É possível fazer previsões usando um modelo de regressão linear ou logística atual, com pesos conhecidos, sem usar ML.PREDICT
, mesmo sem acesso ao próprio modelo. Para isso, você precisa de uma solução alternativa para usar modelos de regressão de privacidade diferencial (DP, na sigla em inglês) nas consultas de ativação de público-alvo do Ads Data Hub.
Neste exemplo detalhado, você vai aprender a realizar a inferência simulada de modelos reais de regressão logística binária e linear e, em seguida, comparar os resultados com os de ML.PREDICT
para mostrar a precisão dos resultados simulados.
Você também vai conferir um exemplo prático de como criar uma lista de público-alvo com um modelo de logística binária, que seria usado para aplicar um modelo de conversão à ativação de público-alvo.
Panorama do exemplo:
- Gerar dados
- Treinar o modelo
- Consultar pesos e interceptação
- Simular a previsão
- Comparar resultados
Exemplo detalhado
1. Gerar dados
Crie uma tabela com dados simulados para treinar o modelo. Marque uma fração das linhas do conjunto de restrições.
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. Treinar o modelo
Treine um modelo de regressão do conjunto de treinamento.
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
Adicionamos ruído suficiente aos dados simulados para conseguir um modelo com R2 = 0,9009.
Medição | Valor |
---|---|
Erro médio absoluto | 0,7359 |
Erro quadrático médio | 0,8432 |
Erro de registro 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. Observe a precisão de 0,9260.
Medição | Valor |
---|---|
Classe positiva | 1 |
Classe negativa | 0 |
Precisão | 0,0810 |
Recall | 0,9315 |
Acurácia | 0,9260 |
Pontuação F1 | 0,9328 |
Os valores em negrito nesta matriz de confusão mostram com que frequência o modelo classificou cada rótulo corretamente, e os valores que não estão em negrito mostram com que frequência o modelo fez isso incorretamente.
Rótulo verdadeiro | Rótulo previsto 1 | Rótulo previsto 2 |
---|---|---|
1 | 93% | 7% |
0 | 8% | 92% |
3. Consultar pesos e interceptação
Consulte os pesos e a interceptação do modelo:
Regressão linear
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 |
INTERCEPTAÇÃO | -4,1428754911504306 |
Regressão logística binária
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 |
INTERCEPTAÇÃO | -17,922169920 |
4. Simular a previsão
Regressão linear
Use o produto escalar dos valores de atributos com os pesos e adicione a interceptação para fazer a previsão com o SQL padrão, sem o ML.PREDICT
. Essa consulta compara as previsões que usam essa técnica com aquelas que usam ML.PREDICT
. Observe como as linhas SQL em negrito executam o produto escalar dos valores de atributos para a linha com os pesos do modelo e, em seguida, adicionam a interceptaçã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 de simulação das previsões é muito semelhante à regressão linear, mas ela aplica a função sigmoide na última etapa com o limite desejado.
Use o produto escalar dos valores de atributos com os pesos e adicione a interceptação para fazer a previsão com o SQL padrão, sem o ML.PREDICT
.
Em seguida, use a função sigmoide com um limite de 0,5 no resultado para prever 0 ou 1. Essa consulta compara as previsões que usam essa técnica com aquelas 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 em negrito na consulta acima executa o produto escalar dos valores de atributos para cada linha com os pesos do modelo e adiciona a interceptação para conseguir a previsão da regressão linear:
IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
Em seguida, ele aplica a função sigmoide Y = 1 / (1+e^-z)
ao produto escalar e faz a interceptação usando o SQL padrão:
IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
Por fim, o resultado da função é comparado ao valor limite de 0,5 para chegar à previsão de regressão logística binária de 0, se for menor que 0,5, ou 1, se não for. É possível usar qualquer valor limite entre 0 e 1.
IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
Essa técnica também pode ser estendida para a regressão logística multiclasse. Nesse caso, os pesos do modelo vão ser uma matriz nxn, em vez de um vetor, e os pesos seriam um vetor e não um escalar. Multiplique o vetor de valores dos atributos pela matriz de pesos e adicione o vetor de interceptação. O vetor resultante teria uma pontuação para cada rótulo, e é possível escolher o rótulo com a pontuação mais alta para sua previsão. Se você quiser retornar uma matriz de probabilidade, aplique a função sigmoide a cada elemento da matriz.
5. Comparar resultados
Regressão linear
Os resultados da amostra são quase idênticos, exceto por um pequeno erro no arredondamento.
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 de restrições de 10 mil linhas. Há algumas linhas em que ML.PREDICT
e a inferência simulada discordam do rótulo real. Isso é esperado, porque a precisão do modelo é de cerca de 93%, além de haver valores pequenos, mas não 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 |
Criar uma lista de ativação de público-alvo com ML
Um caso de uso típico seria criar um modelo de regressão logística binária com privacidade diferenciada para prever conversões e, em seguida, aplicar a inferência nesse modelo ao gerar uma lista de público-alvo. Suponha que o modelo de logística binária criado no exemplo acima seja a estimativa de conversões e que cada linha nos conjuntos de treinamento e avaliação representa um usuário distinto.
A consulta a seguir mostra como criar uma lista de público-alvo com esses usuários que vão ser convertidos pelas previsões do modelo:
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;