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

ניתן ליצור תחזיות באמצעות מודל רגרסיה ליניארי או לוגיסטי קיים עם משקולות ידועות ללא שימוש ב-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

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

תווית True תווית חזויה 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
חיתוך -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
חיתוך -17.922169920

4. סימולציה של החיזוי

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

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

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

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

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

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

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

יצירת רשימה ליצירת קהלים באמצעות למידת מכונה

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

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

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;