פיתוח מודל לזיהוי הונאות ב-Cloud AI Platform באמצעות TensorFlow Enterprise ו-BigQuery

1. סקירה כללית

בשיעור ה-Lab הזה תטמיעו ישירות מערך נתונים של BigQuery ותאמנו מודל לזיהוי הונאות באמצעות TensorFlow Enterprise ב-Google Cloud AI Platform.

מה תלמדו

במאמר הזה נסביר איך:

  • ניתוח נתונים ב-BigQuery
  • הטמעת נתונים באמצעות המחבר של BigQuery ב-TensorFlow Enterprise
  • איך בונים מודל למידה עמוקה לזיהוי הונאות עם מערך נתונים לא מאוזן

‫2. ניתוח הנתונים ב-BigQuery

כדי להפעיל את ה-codelab הזה, צריך פרויקט ב-Google Cloud Platform שמופעל בו חיוב. כדי ליצור פרויקט, פועלים לפי ההוראות האלה.

שלב 1: גישה למערך הנתונים הציבורי של BigQuery

כדי לגשת למערכי נתונים ציבוריים של BigQuery במסוף Google Cloud, לוחצים על הקישור הזה.

בעץ המשאבים בפינה הימנית התחתונה, תופיע רשימה של מערכי נתונים. עוברים בין מערכי הנתונים הזמינים עד שמגיעים אל ml-datasets, ואז בוחרים את הטבלה ulb-fraud-detection בתוכו:

d5e78261514a90ef.png

כדי לקבל מידע נוסף על מערך הנתונים, לוחצים על כל אחת מהכרטיסיות:

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

שלב 2: שליחת שאילתה לטבלה

בכרטיסייה 'פרטים' אפשר לראות את המידע הבא על הנתונים:

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

כדי לבחון את הנתונים מקרוב, לוחצים על Query Table כדי להריץ שאילתה:

581e596426a98383.png

מעדכנים את ההצהרה כדי להוסיף * כדי להציג את כל העמודות, ולוחצים על הפעלה.

SELECT * FROM `bigquery-public-data.ml_datasets.ulb_fraud_detection` LIMIT 1000

שלב 3: ניתוח הנתונים

‫BigQuery מספק מספר פונקציות סטטיסטיות. בואו נבדוק איך הנתונים קשורים למשתנה היעד Class.

SELECT CORR(Time,Class) as TimeCorr, CORR(V1,Class) as V1Corr, CORR(V2,Class) as V2Corr, CORR(Amount,Class) as AmountCorr FROM `bigquery-public-data.ml_datasets.ulb_fraud_detection`

e1e98a8315b62e9e.png

המתאם יספק טווח מ-‎-1 (מתאם שלילי) עד 1 (מתאם חיובי), כאשר 0 מייצג אי-תלות.

שימו לב שהמשתנים V1 ו-V2 קשורים קשר קל למשתנה היעד שלנו (בסביבות ‎-0.1 ו-‎0 .1 בהתאמה).

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

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

שלב 4: חישוב ערכי ממוצע להרחבת תכונות

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

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

SELECT
   AVG(Time), AVG(V1), AVG(V2), AVG(V3), AVG(V4), AVG(V5), AVG(V6), AVG(V7), AVG(V8),
   AVG(V9), AVG(V10),AVG(V11), AVG(V12), AVG(V13), AVG(V14), AVG(V15), AVG(V16),
   AVG(V17), AVG(V18), AVG(V19), AVG(V20), AVG(V21), AVG(V22), AVG(V23), AVG(V24),
   AVG(V25), AVG(V26), AVG(V27),AVG(V28), AVG(Amount)
FROM
   `bigquery-public-data.ml_datasets.ulb_fraud_detection`
WHERE
   MOD(ABS(FARM_FINGERPRINT(CONCAT(SAFE_CAST(Time AS STRING),
   SAFE_CAST(Amount AS STRING)))),10) < 8

שלב 5: פיצול הנתונים

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

  • אימון: משמש לבניית המודל על ידי התאמה חוזרת של פרמטרים
  • אימות: משמש להערכה אם המודל מבצע התאמת יתר (overfitting) על ידי אימות על נתונים עצמאיים במהלך תהליך האימון
  • בדיקה: משמש אחרי יצירת המודל כדי להעריך את רמת הדיוק

ב-codelab הזה נשתמש בפיצול של 80/10/10 לאימון, לאימות ולבדיקה.

כל מערך נתונים יוכנס לטבלה משלו ב-BigQuery. השלב הראשון הוא ליצור 'מערך נתונים' ב-BigQuery – שהוא מאגר לטבלאות קשורות. אחרי שבוחרים את הפרויקט, לוחצים על Create Dataset (יצירת מערך נתונים).

1084d9f5edbf760b.png

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

e5b8646ebdf5f272.png

עכשיו נריץ 3 שאילתות לאימון, לבדיקה ולאימות, ונשמור את הנתונים במערך הנתונים החדש tfe_codelab.

בעורך השאילתות, מריצים שאילתה כדי ליצור את נתוני האימון:

SELECT *
FROM `bigquery-public-data.ml_datasets.ulb_fraud_detection`
WHERE MOD(ABS(FARM_FINGERPRINT(CONCAT(SAFE_CAST(Time AS STRING),SAFE_CAST(Amount AS STRING)))),10) < 8

אחרי שהשאילתה מסתיימת, שומרים את התוצאות בטבלה ב-BigQuery.

49d20c9b4b62f6a7.png

במערך הנתונים tfe_codelab שיצרתם, נותנים לטבלה את השם ulb_fraud_detection_train ושומרים את הנתונים.

6d83cf113a0682e1.png

הפסוקית WHERE מפצלת את הנתונים קודם על ידי חישוב של פונקציית גיבוב (hash) על כמה עמודות. לאחר מכן, המערכת בוחרת שורות שבהן השארית של הגיבוב (hash) אחרי חלוקה ב-10 היא מתחת ל-80, וכך מתקבלים 80%.

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

אימות

SELECT *
FROM `bigquery-public-data.ml_datasets.ulb_fraud_detection`
WHERE MOD(ABS(FARM_FINGERPRINT(CONCAT(SAFE_CAST(Time AS STRING),SAFE_CAST(Amount AS STRING)))),10) = 8

שומרים את התוצאות של השאילתה הזו בטבלה בשם ulb_fraud_detection_val.

בדיקה

SELECT *
FROM `bigquery-public-data.ml_datasets.ulb_fraud_detection`
WHERE MOD(ABS(FARM_FINGERPRINT(CONCAT(SAFE_CAST(Time AS STRING),SAFE_CAST(Amount AS STRING)))),10) = 9

שומרים את התוצאות של השאילתה הזו בטבלה בשם ulb_fraud_detection_test.

‫3. הגדרת סביבת Notebook

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

שלב 1: הפעלת ממשקי API

המחבר של BigQuery משתמש ב-BigQuery Storage API. מחפשים את BigQuery Storage API במסוף ומפעילים את ה-API אם הוא מושבת.

9895a2fd3cdf8f8c.png

שלב 2: יצירת מופע של AI Platform Notebooks

עוברים אל AI Platform Notebooks section ב-Cloud Console ולוחצים על New Instance. לאחר מכן בוחרים את סוג האירוע האחרון של TensorFlow Enterprise 1.x without GPUs:

35301141e9fd3f44.png

משתמשים באפשרויות ברירת המחדל ולוחצים על יצירה. אחרי שהמופע נוצר, בוחרים באפשרות Open JupyterLab:

3b801f8ff3db0f2f.png

לאחר מכן, יוצרים קובץ notebook של Python 3 מ-JupyterLab:

58523671a252b95a.png

4. הוספת רשומות מ-BigQuery

שלב 1: ייבוא חבילות Python

בתא הראשון של ה-Notebook, מוסיפים את הייבוא הבא ומריצים את התא. כדי להפעיל אותו, לוחצים על לחצן החץ ימינה בתפריט העליון או על Command-Enter:

import tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras.layers as layers

from tensorflow_io.bigquery import BigQueryClient

import functools

tf.enable_eager_execution()

שלב 2: הגדרת קבועים

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

GCP_PROJECT_ID = '<YOUR_PROJECT_ID>'
DATASET_GCP_PROJECT_ID = GCP_PROJECT_ID # A copy of the data is saved in the user project
DATASET_ID = 'tfe_codelab'
TRAIN_TABLE_ID = 'ulb_fraud_detection_train'
VAL_TABLE_ID = 'ulb_fraud_detection_val'
TEST_TABLE_ID = 'ulb_fraud_detection_test'

FEATURES = ['Time','V1','V2','V3','V4','V5','V6','V7','V8','V9','V10','V11','V12','V13','V14','V15','V16','V17','V18','V19','V20','V21','V22','V23','V24','V25','V26','V27','V28','Amount']
LABEL='Class'
DTYPES=[tf.float64] * len(FEATURES) + [tf.int64]

שלב 3: הגדרת פונקציות עזר

עכשיו נגדיר כמה פונקציות. הפונקציה read_session() קוראת נתונים מטבלה ב-BigQuery. הפונקציה extract_labels() היא פונקציית עזר שמפרידה את עמודת התוויות מהשאר, כדי שמערך הנתונים יהיה בפורמט שנדרש על ידי keras.model_fit() בהמשך.

client = BigQueryClient()

def read_session(TABLE_ID):
    return client.read_session(
        "projects/" + GCP_PROJECT_ID, DATASET_GCP_PROJECT_ID, TABLE_ID, DATASET_ID,
        FEATURES + [LABEL], DTYPES, requested_streams=2
)

def extract_labels(input_dict):
  features = dict(input_dict)
  label = tf.cast(features.pop(LABEL), tf.float64)
  return (features, label)

שלב 4: הטמעת נתונים

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

BATCH_SIZE = 32

raw_train_data = read_session(TRAIN_TABLE_ID).parallel_read_rows().map(extract_labels).batch(BATCH_SIZE)
raw_val_data = read_session(VAL_TABLE_ID).parallel_read_rows().map(extract_labels).batch(BATCH_SIZE)
raw_test_data = read_session(TEST_TABLE_ID).parallel_read_rows().map(extract_labels).batch(BATCH_SIZE)

next(iter(raw_train_data)) # Print first batch

5. יצירת מודל

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

בואו ניצור עמודות מאפיינים לכל מאפיין במערך הנתונים. במערך הנתונים הזה, כל העמודות הן מסוג numeric_column, אבל יש עוד כמה סוגים של עמודות (למשל, categorical_column).

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

MEANS = [94816.7387536405, 0.0011219465482001268, -0.0021445914636999603, -0.002317402958335562,
         -0.002525792169927835, -0.002136576923287782, -3.7586818983702984, 8.135919975738768E-4,
         -0.0015535579268265718, 0.001436137140461279, -0.0012193712736681508, -4.5364970422902533E-4,
         -4.6175444671576083E-4, 9.92177789685366E-4, 0.002366229151475428, 6.710217226762278E-4,
         0.0010325807119864225, 2.557260815835395E-4, -2.0804190062322664E-4, -5.057391100818653E-4,
         -3.452114767842334E-6, 1.0145936326270006E-4, 3.839214074518535E-4, 2.2061197469126577E-4,
         -1.5601580596677608E-4, -8.235017846415852E-4, -7.298316615408554E-4, -6.898459943652376E-5,
         4.724125688297753E-5, 88.73235686453587]

def norm_data(mean, data):
  data = tf.cast(data, tf.float32) * 1/(2*mean)
  return tf.reshape(data, [-1, 1])

numeric_columns = []

for i, feature in enumerate(FEATURES):
  num_col = tf.feature_column.numeric_column(feature, normalizer_fn=functools.partial(norm_data, MEANS[i]))
  numeric_columns.append(num_col)

numeric_columns

שלב 2: בניית המודל

עכשיו אנחנו מוכנים ליצור מודל. נעביר את העמודות שיצרנו לרשת. אחר כך נקמפל את המודל. אנחנו כוללים את מדד ה-AUC של Precision/Recall, שהוא שימושי עבור מערכי נתונים לא מאוזנים.

model = keras.Sequential([
    tf.keras.layers.DenseFeatures(numeric_columns),
    layers.Dense(64, activation='relu'),
    layers.Dense(64, activation='relu'),
    layers.Dense(1, activation='sigmoid')
])

model.compile(loss='binary_crossentropy',
              optimizer='adam',
              metrics=['accuracy', tf.keras.metrics.AUC(curve='PR')])

שלב 3: אימון המודל

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

לצורך ה-codelab הזה, נשתמש בטכניקה שנותנת משקל יתר להפסד כשמבצעים סיווג שגוי של מחלקת המיעוט. נציין פרמטר class_weight במהלך האימון ומשקל '1' (הונאה) גבוה יותר, כי הוא נפוץ הרבה פחות.

בשיעור ה-Lab הזה נשתמש ב-3 epochs (מעברים על הנתונים) כדי שהאימון יהיה מהיר יותר. בתרחיש בעולם האמיתי, נרצה להריץ את האימון מספיק זמן עד שלא נראה יותר שיפורים ברמת הדיוק של קבוצת נתונים לתיקוף.

CLASS_WEIGHT = {
    0: 1,
    1: 100
}
EPOCHS = 3

train_data = raw_train_data.shuffle(10000)
val_data = raw_val_data
test_data = raw_test_data

model.fit(train_data, validation_data=val_data, class_weight=CLASS_WEIGHT, epochs=EPOCHS)

שלב 4: הערכת המודל

אפשר להשתמש בפונקציה evaluate()‎ כדי לבדוק נתוני בדיקה שהמודל מעולם לא ראה, וכך לקבל הערכה אובייקטיבית. למזלנו, שמרנו נתוני בדיקה בדיוק למטרה הזו.

model.evaluate(test_data)

שלב 5: ניתוח

בשיעור ה-Lab הזה הדגמנו איך להטמיע מערך נתונים גדול מ-BigQuery ישירות במודל TensorFlow Keras. הסברנו גם את כל השלבים לבניית מודל. בסוף, למדנו קצת על טיפול בבעיות סיווג לא מאוזנות.

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

6. הסרת המשאבים

אם רוצים להמשיך להשתמש ב-notebook הזה, מומלץ להשבית אותו כשלא משתמשים בו. בממשק המשתמש של Notebooks במסוף Cloud, בוחרים את מחברת ה-Notebook ואז בוחרים באפשרות Stop:

57213ef2edad9257.png

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

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