Předpovědi lze pomocí existujícího modelu na bázi lineární nebo logistické regrese se známými vahami provádět bez použití příkazu ML.PREDICT
, dokonce i bez přístupu k samotnému modelu. Potřebujete k tomu použít speciální postup, abyste mohli využívat regresní modely s diferenčním soukromím v rámci dotazů pro aktivaci publik ve službě Ads Data Hub.
V tomto podrobném příkladu vám ukážeme, jak simulovat výsledky skutečných modelů lineární a binární logistické regrese. Pak porovnáním výsledků s výsledky příkazu ML.PREDICT
posoudíme přesnost simulace.
Zároveň uvedeme praktický příklad vytvoření seznamu publika pomocí modelu binární logistické regrese. Tímto způsobem lze aplikovat modelování konverzí na aktivaci publik.
Přehled příkladu:
- Vygenerování dat
- Trénování modelu
- Zjištění vah a konstanty
- Simulace předpovědi
- Porovnání výsledků
Podrobný příklad
1. Vygenerování dat
Vytvořte tabulku se simulovanými daty, která použijete ke trénování modelu. Malou část řádků označte jako ověřovací sadu.
Lineární regrese
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
Binární logistická regrese
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. Trénování modelu
Pomocí tréninkové datové sady vytrénujte regresní model.
Lineární regrese
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
Do simulovaných dat jsme přidali dost šumu na to, abychom získali model s R2 = 0,9009.
Měření | Hodnota |
---|---|
Průměr absolutní chyby | 0,7359 |
Průměr chyby umocněné na druhou | 0,8432 |
Průměr logaritmu chyby umocněného na druhou | 0,0810 |
Medián absolutní chyby | 0,6239 |
Koeficient determinace | 0,9009 |
Binární logistická regrese
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
Vzorové výsledky. Přesnost je 0,9260.
Měření | Hodnota |
---|---|
Kladná třída | 1 |
Záporná třída | 0 |
Pozitivní predikční hodnota | 0,0810 |
Citlivost | 0,9315 |
Přesnost | 0,9260 |
Skóre F1 | 0,9328 |
Zvýrazněné hodnoty v této matici záměn ukazují, jak často model klasifikoval určitý štítek správně. Nezvýrazněné hodnoty znamenají, jak často model příslušnou hodnotu klasifikoval chybně.
Skutečný štítek | Předpovězený štítek 1 | Předpovězený štítek 2 |
---|---|---|
1 | 93 % | 7 % |
0 | 8 % | 92 % |
3. Zjištění vah a konstanty
Zjistěte váhy a konstantu pro model:
Lineární regrese
SELECT
*
FROM
ML.WEIGHTS(MODEL `DATASET_NAME.LIN_REG_MODEL`)
weight (váha) | category_weights.category (váhová kategorie: kategorie) |
---|---|
feature_1 (proměnná 1) | 1,8263055528635743 |
feature_2 (proměnná 2) | 1,8143804404490813 |
feature_3 (proměnná 3) | 1,8601204874033492 |
feature_4 (proměnná 4) | 1,8507603439031859 |
feature_5 (proměnná 5) | 1,7899764387123640 |
feature_6 (proměnná 6) | 1,8645246630251291 |
feature_7 (proměnná 7) | 1,8698005281925356 |
feature_8 (proměnná 8) | 1,7904637080330201 |
feature_9 (proměnná 9) | 1,8036887855406274 |
feature_10 (proměnná 10) | 1,8117115890624449 |
INTERCEPT (konstanta) | −4,1428754911504306 |
Binární logistická regrese
SELECT
*
FROM
ML.WEIGHTS(MODEL `DATASET_NAME.BIN_LOG_REG_MODEL`)
weight (váha) | category_weights.category (váhová kategorie: kategorie) |
---|---|
feature_1 (proměnná 1) | 3,823533928 |
feature_2 (proměnná 2) | 3,734812819 |
feature_3 (proměnná 3) | 3,842239823 |
feature_4 (proměnná 4) | 3,785488823 |
feature_5 (proměnná 5) | 3,737386716 |
feature_6 (proměnná 6) | 3,567663961 |
feature_7 (proměnná 7) | 3,819643052 |
feature_8 (proměnná 8) | 3,734673763 |
feature_9 (proměnná 9) | 3,839301406 |
feature_10 (proměnná 10) | 3,787306994 |
INTERCEPT (konstanta) | −17,922169920 |
4. Simulace předpovědi
Lineární regrese
Předpověď bez použití příkazu ML.PREDICT
vypočítáte pomocí standardních příkazů jazyka SQL tak, že provedete skalární součin hodnot proměnných s vahami a přičtete konstantu. Tento dotaz porovnává předpovědi získané touto metodou s výsledky příkazu ML.PREDICT
. V tučně zvýrazněných řádcích kódu SQL provádíme skalární součin hodnot proměnných v příslušném řádku s vahami modelu a pak přičítáme konstantu.
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
Binární logistická regrese
V případě binární logistické regrese je metoda simulace předpovědí velice podobná té, kterou jsme použili u regrese lineární. Pouze je doplněná o použití sigmoidy s požadovanou prahovou hodnotou.
Předpověď bez použití příkazu ML.PREDICT
vypočítáte pomocí standardních příkazů jazyka SQL tak, že provedete skalární součin hodnot proměnných s vahami a přičtete konstantu.
Pak na výsledek použijte sigmoidní funkci s prahovou hodnotou 0,5. Tím zjistíte, zda je předpověď rovna 0, nebo 1. Tento dotaz porovnává předpovědi získané touto metodou s výsledky příkazu 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
Tučně vyznačený blok kódu ve výše uvedeném dotazu počítá předpověď pomocí lineární regrese tak, že provede skalární součin hodnot proměnných pro jednotlivé řádky s vahami modelu a přičte konstantu:
IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
Poté kód na skalární součin a konstantu použije sigmoidní funkci Y = 1 / (1+e^-z)
, opět pomocí standardních příkazů SQL:
IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
Nakonec je výsledek sigmoidní funkce porovnán s prahovou hodnotou 0,5. Tím jsme binární logistickou regresí došli k předpovědi rovné 0, pokud je výsledek menší než 0,5, nebo rovné 1, jestliže je výsledek větší. Lze použít jakoukoli prahovou hodnotu mezi 0 a 1.
IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
Tuto metodu lze rozšířit i na multinominální logistickou regresi. V tom případě budou váhy modelu představovány maticí nxn a nikoli jedním vektorem a půjde o vektory a nikoli skaláry. Vektor hodnot funkcí se pak násobí maticí vah a přičítá se vektor konstanty. Výsledný vektor obsahuje skóre pro každý štítek. Vy pak můžete jako předpověď zvolit štítek s nejvyšším skóre. Jestliže chcete, aby výsledkem bylo pole pravděpodobností, použijete na každý prvek tohoto pole sigmoidní funkci.
5. Porovnání výsledků
Lineární regrese
Vzorové výsledky jsou téměř shodné, až na drobné odchylky dané zaokrouhlováním.
actual_label (skutečný štítek) | ml_predicted_label (štítek předpovězený funkcí ML) | sql_predicted_label (štítek předpovězený pomocí SQL) | diff_is_negligible (rozdíl je zanedbatelný) |
---|---|---|---|
6 | 5,2062349420751834 | 5,2062349420751826 | pravda |
0 | 0,40318472770048075 | 0,403184727700479 | pravda |
3 | 3,0703766078249597 | 3,0703766078249597 | pravda |
7 | 7,0588171538562 | 7,0588171538562 | pravda |
6 | 6,7802375930646 | 6,7802375930646 | pravda |
6 | 5,1088569571339368 | 5,1088569571339377 | pravda |
4 | 4,051839078116874 | 4,051839078116874 | pravda |
4 | 5,1810254680219243 | 5,1810254680219234 | pravda |
6 | 6,1440349466401223 | 6,1440349466401205 | pravda |
1 | 2,0842399472783519 | 2,0842399472783519 | pravda |
2 | 2,1911209811886847 | 2,1911209811886838 | pravda |
3 | 3,0236086790006622 | 3,0236086790006613 | pravda |
2 | 2,573083132964213 | 2,5730831329642125 | pravda |
7 | 5,68662973136732 | 5,6866297313673186 | pravda |
9 | 8,1860026312677938 | 8,1860026312677938 | pravda |
Binární logistická regrese
Porovnání simulovaných výsledků se skutečnými výsledky funkce ML.PREDICT
vychází výborně. V ověřovací sadě 10 tisíc řádků nedošlo ani k jednomu rozporu. V některých řádcích skutečnému štítku neodpovídá ani funkce ML.PREDICT
ani simulovaný výsledek. To je nicméně očekávatelné, protože přesnost modelu je zhruba 93 % a v buňkách matice záměn ležících mimo úhlopříčku jsou malé, ale nenulové hodnoty.
actual_label (skutečný štítek) | ml_predicted_label (štítek předpovězený funkcí ML) | sql_predicted_label (štítek předpovězený pomocí SQL) | simulation_is_accurate (simulace je přesná) |
---|---|---|---|
0 | 1 | 1 | pravda |
0 | 0 | 0 | pravda |
0 | 0 | 0 | pravda |
0 | 0 | 0 | pravda |
0 | 0 | 0 | pravda |
0 | 0 | 0 | pravda |
0 | 0 | 0 | pravda |
0 | 0 | 0 | pravda |
0 | 0 | 0 | pravda |
0 | 0 | 0 | pravda |
0 | 1 | 1 | pravda |
0 | 0 | 0 | pravda |
Vytvoření seznamu pro aktivaci publika pomocí funkce ML
Typickým případem použití je vytvoření modelu s diferenčním soukromím založeného na binární logistické regresi, který má předpovídat konverze, a poté vytvoření seznamu publika z výsledných předpovědí. Předpokládejme, že model binární logistické regrese, vytvořený ve výše uvedeném příkladu, modeluje konverze a že každý řádek ve trénovací a kontrolní sadě představuje jiného uživatele.
Níže uvedený dotaz ukazuje, jak vytvořit seznam publika z těch uživatelů, u nichž model předpovídá uskutečnění konverze.
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;