בניית מודל רגרסיה לרשימות קהלים

אתם יכולים ליצור חיזויים באמצעות מודל רגרסיה לינארית או לוגיסטית קיים עם משקלים ידועים בלי להשתמש ב-ML.PREDICT, גם בלי גישה למודל עצמו. כדי לעשות את זה, צריך להשתמש בפתרון עקיף כדי להשתמש במודלים של רגרסיה עם פרטיות דיפרנציאלית (DP) בתוך שאילתות להפעלת קהלים ב-Ads Data Hub.

בדוגמה הבאה נסביר איך לבצע את ההסקה המדומה עבור מודלים של רגרסיה לוגיסטית לינארית ובינארית, ואז להשוות את התוצאות עם התוצאות של ML.PREDICT כדי להראות את הדיוק של התוצאות המדומות. בנוסף, נדגים דוגמה מעשית ליצירת רשימת חברים בקהל באמצעות מודל רגרסיה לוגיסטית בינארית, שמשמש להחלת מודל המרות על הפעלת קהל.

סקירה כללית של הדוגמה:

  1. יצירת נתונים
  2. אימון המודל
  3. קבלת המשקלים והקבוע
  4. סימולציה של החיזוי
  5. השוואת תוצאות

דוגמה מפורטת

1. יצירת נתונים

יוצרים טבלה עם נתונים מסימולציה לאימון המודל. מסמנים חלק מהשורות כקבוצת ההחזקה.

רגרסיה לינארית

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

רגרסיה לוגיסטית בינארית

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. אימון המודל

מאמנים מודל רגרסיה מתוך קבוצת נתונים לאימון.

רגרסיה לינארית

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

שימו לב שהוספנו מספיק רעש לנתונים המדומים כדי לקבל מודל עם R2 = 0.9009.

מדידה ערך
שגיאה ממוצעת מוחלטת 0.7359
שגיאה ריבועית ממוצעת 0.8432
שגיאת יומן ריבועית ממוצעת 0.0810
שגיאה ממוצעת מוחלטת 0.6239
R בריבוע 0.9009

רגרסיה לוגיסטית בינארית

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

תוצאות לדוגמה. שימו לב לדיוק של 0.9260.

מדידה ערך
סיווג חיובי 1
סיווג שלילי 0
דיוק 0.0810
זכירות 0.9315
דיוק 0.9260
ציון F1 0.9328

הערכים המודגשים במטריצת הבלבול הזו מראים את התדירות שבה המודל סיווג כל תווית בצורה נכונה, והערכים הלא מודגשים מראים את התדירות שבה המודל סיווג כל תווית בצורה שגויה.

תווית אמיתית תווית צפויה 1 תווית חזויה 2
1 93% 7%
0 8% 92%

3. קבלת משקלים ונקודת חיתוך

קבלת המשקלים והקבוע של המודל:

רגרסיה לינארית

SELECT
  *
FROM
  ML.WEIGHTS(MODEL `DATASET_NAME.LIN_REG_MODEL`)
משקל 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

רגרסיה לוגיסטית בינארית

SELECT
  *
FROM
  ML.WEIGHTS(MODEL `DATASET_NAME.BIN_LOG_REG_MODEL`)
משקל 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. סימולציה של החיזוי

רגרסיה לינארית

כדי לבצע את החיזוי באמצעות SQL סטנדרטי בלי להשתמש ב-ML.PREDICT, צריך להשתמש במכפלה הסקלרית של ערכי התכונות עם המשקלים ולהוסיף את נקודת החיתוך עם ציר ה-y. השאילתה הזו משווה את התחזיות באמצעות הטכניקה הזו לתחזיות באמצעות ML.PREDICT. שימו לב איך השורות המודגשות של SQL מבצעות את המכפלה הסקלרית של ערכי התכונות בשורה עם משקלי המודל, ואז מוסיפות את נקודת החיתוך.

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

רגרסיה לוגיסטית בינארית

ברגרסיה לוגיסטית בינארית, הטכניקה לסימולציה של התחזיות דומה מאוד לזו של רגרסיה לינארית, עם תוספת של החלת פונקציית הסיגמואיד בשלב האחרון עם ערך הסף הרצוי.

כדי לבצע את החיזוי באמצעות SQL סטנדרטי בלי להשתמש ב-ML.PREDICT, צריך להשתמש במכפלה הסקלרית של ערכי התכונות עם המשקלים ולהוסיף את נקודת החיתוך. לאחר מכן משתמשים בפונקציית סיגמואיד עם סף של 0.5 על התוצאה כדי לחזות 0 או 1. השאילתה הזו משווה בין התחזיות שמתקבלות באמצעות הטכניקה הזו לבין התחזיות שמתקבלות באמצעות 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

בלוק קוד ה-SQL שמודגש בשאילתה שלמעלה מבצע את המכפלה הסקלרית של ערכי המאפיינים בכל שורה עם המשקלים של המודל, ומוסיף את נקודת החיתוך כדי לקבל את התחזית של הרגרסיה הליניארית:

IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)

לאחר מכן, הפונקציה מחילה את פונקציית הסיגמואיד Y = 1 / (1+e^-z) על המכפלה הסקלרית והחיתוך עם ציר ה-y, באמצעות SQL סטנדרטי:

IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)

לבסוף, התוצאה של פונקציית הסיגמואיד מושווית לערך הסף של 0.5 כדי להגיע לחיזוי של רגרסיה לוגיסטית בינארית של 0, אם היא קטנה מ-0.5, או 1, אם היא לא קטנה מ-0.5. שימו לב שאפשר להשתמש בכל ערך סף בין 0 ל-1.

IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)

אפשר להרחיב את הטכניקה הזו גם לרגרסיה לוגיסטית רב-סיווגית. במקרה כזה, המשקלים של המודל יהיו מטריצה בגודל nxn ולא וקטור, והמשקלים יהיו וקטור ולא סקלר. מכפילים את וקטור ערכי התכונות במטריצת המשקלים ומוסיפים את וקטור נקודת החיתוך. הווקטור שיתקבל יכלול ציון לכל תווית, ותוכלו לבחור את התווית עם הציון הכי גבוה לחיזוי. אם רוצים להחזיר מערך הסתברויות, צריך להחיל את פונקציית הסיגמואיד על כל רכיב במערך.

5. השוואת תוצאות

רגרסיה לינארית

התוצאות של הדוגמה כמעט זהות, למעט שגיאת עיגול קטנה.

actual_label ml_predicted_label sql_predicted_label diff_is_negligible
6 5.2062349420751834 5.2062349420751826 true
0 0.40318472770048075 0.403184727700479 true
3 3.0703766078249597 3.0703766078249597 true
7 7.0588171538562 7.0588171538562 true
6 6.7802375930646 6.7802375930646 true
6 5.1088569571339368 5.1088569571339377 true
4 4.051839078116874 4.051839078116874 true
4 5.1810254680219243 5.1810254680219234 true
6 6.1440349466401223 6.1440349466401205 true
1 2.0842399472783519 2.0842399472783519 true
2 2.1911209811886847 2.1911209811886838 true
3 3.0236086790006622 3.0236086790006613 true
2 2.573083132964213 2.5730831329642125 true
7 5.68662973136732 5.6866297313673186 true
9 8.1860026312677938 8.1860026312677938 true

רגרסיה לוגיסטית בינארית

ההשוואה בין ההסקה המדומה לבין התוצאות בפועל של ML.PREDICT מושלמת – אין אף סתירה במערך של 10,000 שורות שהוצאו מהמדגם. יש כמה שורות שבהן גם ML.PREDICT וגם ההסקה המדומה לא מסכימים עם התווית בפועל, וזה צפוי כי רמת הדיוק של המודל היא בערך 93%, ויש ערכים קטנים אבל לא אפסיים בתאים שאינם אלכסוניים במטריצת השגיאות.

actual_label ml_predicted_label sql_predicted_label simulation_is_accurate
0 1 1 true
0 0 0 true
0 0 0 true
0 0 0 true
0 0 0 true
0 0 0 true
0 0 0 true
0 0 0 true
0 0 0 true
0 0 0 true
0 1 1 true
0 0 0 true

יצירת רשימת הפעלה של קהל באמצעות ML

תרחיש שימוש אופייני הוא יצירת מודל רגרסיה לוגיסטית בינארית עם פרטיות דיפרנציאלית כדי לחזות המרות, ואז החלת הסקה על המודל הזה במהלך יצירת רשימת קהלים. נניח שהמודל הלוגיסטי הבינארי שנוצר בדוגמה שלמעלה משמש לבניית מודל של המרות, וכל שורה במערכי האימון וההערכה מייצגת משתמש נפרד.

השאילתה הבאה מראה איך ליצור רשימת קהלים עם משתמשים שהמודל חוזה שיבצעו המרה:

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;