Regresní modelování pro seznamy publika

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:

  1. Vygenerování dat
  2. Trénování modelu
  3. Zjištění vah a konstanty
  4. Simulace předpovědi
  5. 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;