ניתוח של מודל למידת מכונה פיננסי שנפרס ב-Cloud AI Platform באמצעות הכלי What-if

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

בשיעור ה-Lab הזה תשתמשו בכלי What-if כדי לנתח מודל XGBoost שאומן על נתונים פיננסיים ונפרס ב-Cloud AI Platform.

מה לומדים

נסביר לכם איך:

  • מאמנים מודל XGBoost על מערך נתונים ציבורי של משכנתאות ב-AI Platform Notebooks
  • פריסת מודל XGBoost ל-AI Platform
  • נתחו את המודל באמצעות הכלי What-if

העלות הכוללת של הפעלת שיעור ה-Lab הזה ב-Google Cloud היא כ-$1.

2. פריימר XGBoost מהיר

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

בתרשים הבא אפשר לראות הצגה חזותית של מודל פשוט של עץ החלטות, שמעריך אם צריך לשחק במשחק ספורט על סמך תחזית מזג האוויר:

308a0bfc70733abf.png

למה אנחנו משתמשים ב-XGBoost במודל הזה? אומנם הוכיחו שרשתות נוירונים מסורתיות מניבות את הביצועים הטובים ביותר בנתונים לא מובנים כמו תמונות וטקסט, אבל עצי החלטות בדרך כלל מניבים ביצועים טובים מאוד בנתונים מובְנים כמו מערך נתוני המשכנתה שבו נשתמש ב-Codelab הזה.

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

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

שלב 1: הפעלת Cloud AI Platform Models API

עוברים לקטע 'מודלים של AI Platform במסוף Cloud ולוחצים על 'הפעלה' אם הוא עדיין לא מופעל.

d0d38662851c6af3.png

שלב 2: מפעילים את Compute Engine API

עוברים אל Compute Engine ובוחרים באפשרות Enable (הפעלה) אם היא לא מופעלת עדיין. תצטרכו את הקישור הזה כדי ליצור מכונה של ה-notebook.

שלב 3: יצירת מכונה של AI Platform Notebooks

עוברים אל הקטע 'notebooks של AI Platform' במסוף Cloud ולוחצים על New Instance. לאחר מכן בוחרים במכונה העדכנית ביותר של TF Enterprise 2.x ללא מעבדי GPU:

7d16190440ab2e9c.png

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

772f8868d3841ba0.png

שלב 4: מתקינים את XGBoost

אחרי שמכונת JupyterLab נפתחת, צריך להוסיף את חבילת XGBoost.

כדי לעשות זאת, בוחרים באפשרות Terminal במרכז האפליקציות:

28dcf2790ce77c96.png

לאחר מכן מריצים את הפקודה הבאה כדי להתקין את הגרסה האחרונה של XGBoost שנתמכת על ידי Cloud AI Platform:

pip3 install xgboost==0.90

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

שלב 5: מייבאים חבילות Python

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

import pandas as pd
import xgboost as xgb
import numpy as np
import collections
import witwidget

from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix
from sklearn.utils import shuffle
from witwidget.notebook.visualization import WitWidget, WitConfigBuilder

4. הורדה ועיבוד של נתונים

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

שלב 1: מורידים את מערך הנתונים שעבר עיבוד מראש

הכנו בשבילך גרסה של מערך הנתונים ב-Google Cloud Storage. כדי להוריד אותו, אפשר להריץ את הפקודה gsutil הבאה ב-notebook של Jupyter:

!gsutil cp 'gs://mortgage_dataset_files/mortgage-small.csv' .

שלב 2: קריאת מערך הנתונים עם Pandas

לפני שניצור את Pandas DataFrame, ניצור הכתבה של סוג הנתונים של כל עמודה כדי ש-Pandas יקרא את מערך הנתונים שלנו נכון:

COLUMN_NAMES = collections.OrderedDict({
 'as_of_year': np.int16,
 'agency_code': 'category',
 'loan_type': 'category',
 'property_type': 'category',
 'loan_purpose': 'category',
 'occupancy': np.int8,
 'loan_amt_thousands': np.float64,
 'preapproval': 'category',
 'county_code': np.float64,
 'applicant_income_thousands': np.float64,
 'purchaser_type': 'category',
 'hoepa_status': 'category',
 'lien_status': 'category',
 'population': np.float64,
 'ffiec_median_fam_income': np.float64,
 'tract_to_msa_income_pct': np.float64,
 'num_owner_occupied_units': np.float64,
 'num_1_to_4_family_units': np.float64,
 'approved': np.int8
})

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

data = pd.read_csv(
 'mortgage-small.csv',
 index_col=False,
 dtype=COLUMN_NAMES
)
data = data.dropna()
data = shuffle(data, random_state=2)
data.head()

באמצעות data.head() אפשר לראות תצוגה מקדימה של חמש השורות הראשונות של מערך הנתונים ב-Pandas. אחרי הרצת התא שלמעלה אתם אמורים לראות משהו כזה:

29106b71103235a6.png

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

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

# Class labels - 0: denied, 1: approved
print(data['approved'].value_counts())

labels = data['approved'].values
data = data.drop(columns=['approved'])

כ-66% ממערך הנתונים מכילים אפליקציות שאושרו.

שלב 3: יצירת עמודת דמה לערכים שמחולקים לקטגוריות

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

הפונקציה get_dummies לוקחת עמודה עם כמה ערכים אפשריים וממירה אותה לסדרה של עמודות שמכילות רק 0 ו-1. לדוגמה, אם הייתה לנו העמודה 'צבע' עם הערכים האפשריים 'כחול' ו'אדום', הפונקציה get_dummies ממירה את הערך לשתי עמודות בשם 'color_blue' ו-"color_red" שכולל את כל הערכים הבוליאניים 0 ו-1.

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

dummy_columns = list(data.dtypes[data.dtypes == 'category'].index)
data = pd.get_dummies(data, columns=dummy_columns)

data.head()

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

83aacfaad626e538.png

שלב 4: פיצול הנתונים לקבוצות אימון ובדיקה

אחד מהעקרונות החשובים בלמידת מכונה הוא 'אימון' / 'חלוקת בדיקה'. אנחנו ניקח את רוב הנתונים שלנו ונשתמש בהם כדי לאמן את המודל, ונשאיר את השאר כדי לבדוק את המודל על נתונים שלא נראו בעבר.

מוסיפים את הקוד הבא ל-notebook, שמשתמש בפונקציה 'Scikit Learning' train_test_split כדי לפצל את הנתונים שלנו:

x,y = data,labels
x_train,x_test,y_train,y_test = train_test_split(x,y)

עכשיו אתם מוכנים לבנות ולאמן את המודל שלכם!

5. תיצרו, תאמנו ותעריכו מודל XGBoost

שלב 1: הגדרה ואימון של מודל XGBoost

קל ליצור מודל ב-XGBoost. אנחנו נשתמש במחלקה XGBClassifier כדי ליצור את המודל, ונצטרך רק להעביר את הפרמטר objective המתאים למשימת הסיווג הספציפית שלנו. במקרה הזה משתמשים ב-reg:logistic מכיוון שיש לנו בעיית סיווג בינארית, ואנחנו רוצים שהמודל יפיק ערך יחיד בטווח של (0,1): 0 עבור לא אושר ו-1 עבור מאושר.

הקוד הבא ייצור מודל XGBoost:

model = xgb.XGBClassifier(
    objective='reg:logistic'
)

אפשר לאמן את המודל באמצעות שורת קוד אחת, להפעיל את השיטה fit() ולהעביר לה את נתוני האימון והתוויות.

model.fit(x_train, y_train)

שלב 2: הערכת הדיוק של המודל

עכשיו אפשר להשתמש במודל האימון שלנו כדי ליצור תחזיות על נתוני הבדיקות שלנו באמצעות הפונקציה predict().

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

y_pred = model.predict(x_test)
acc = accuracy_score(y_test, y_pred.round())
print(acc, '\n')

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

שלב 3: שמירת המודל

כדי לפרוס את המודל, מריצים את הקוד הבא כדי לשמור אותו בקובץ מקומי:

model.save_model('model.bst')

6. פריסת מודל ב-Cloud AI Platform

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

שלב 1: יצירת קטגוריה של Cloud Storage למודל שלנו

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

# Update these to your own GCP project, model, and version names
GCP_PROJECT = 'your-gcp-project'
MODEL_BUCKET = 'gs://storage_bucket_name'
VERSION_NAME = 'v1'
MODEL_NAME = 'xgb_mortgage'

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

מריצים את פקודת gsutil הבאה מתוך ה-notebook כדי ליצור קטגוריה:

!gsutil mb $MODEL_BUCKET

שלב 2: מעתיקים את קובץ המודל ל-Cloud Storage

בשלב הבא נעתיק ל-Cloud Storage את קובץ המודל השמור של XGBoost. מריצים את פקודת gsutil הבאה:

!gsutil cp ./model.bst $MODEL_BUCKET

נכנסים לדפדפן האחסון במסוף Cloud כדי לוודא שהקובץ הועתק:

31e2567fa0117214.png

שלב 3: יצירה ופריסה של המודל

אנחנו כמעט מוכנים לפרוס את המודל! הפקודה הבאה ב-gcloud של ai-platform תיצור מודל חדש בפרויקט שלכם. נתקשר לדף הזה בשם xgb_mortgage:

!gcloud ai-platform models create $MODEL_NAME --region='global'

עכשיו הגיע הזמן לפרוס את המודל. אפשר לעשות זאת באמצעות הפקודה הבאה של gcloud:

!gcloud ai-platform versions create $VERSION_NAME \
--model=$MODEL_NAME \
--framework='XGBOOST' \
--runtime-version=2.1 \
--origin=$MODEL_BUCKET \
--python-version=3.7 \
--project=$GCP_PROJECT \
--region='global'

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

342875ba92becad1.png

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

שלב 4: בודקים את המודל שנפרס

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

%%writefile predictions.json
[2016.0, 1.0, 346.0, 27.0, 211.0, 4530.0, 86700.0, 132.13, 1289.0, 1408.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0]

כדי לבדוק את המודל, מריצים את הקוד הבא:

prediction = !gcloud ai-platform predict --model=xgb_mortgage --region='global' --json-instances=predictions.json --version=$VERSION_NAME --verbosity=none

print(prediction)

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

7. שימוש בכלי What-if כדי לפרש את המודל שלך

שלב 1: יוצרים תצוגה חזותית של הכלי What-if

כדי לקשר את הכלי What-if למודלים של AI Platform, צריך להעביר אליו קבוצת משנה של דוגמאות לבדיקה עם ערכי האמת (root) של הדוגמאות האלה. בואו ניצור מערך Numpy של 500 מהדוגמאות לבדיקה, יחד עם תוויות עקרונות הבסיס שלהן:

num_wit_examples = 500
test_examples = np.hstack((x_test[:num_wit_examples].values,y_test[:num_wit_examples].reshape(-1,1)))

כדי ליצור אובייקט של What-if, פשוט יוצרים אובייקט WitConfigBuilder ומעבירים אותו למודל ה-AI Platform שאנחנו רוצים לנתח.

כאן אנחנו משתמשים בפרמטר האופציונלי adjust_prediction כי הכלי What-if מצפה לרשימת ציונים לכל כיתה במודל שלנו (במקרה הזה 2). מכיוון שהמודל שלנו מחזיר ערך יחיד רק מ-0 עד 1, נשנה אותו לפורמט הנכון בפונקציה הבאה:

def adjust_prediction(pred):
  return [1 - pred, pred]

config_builder = (WitConfigBuilder(test_examples.tolist(), data.columns.tolist() + ['mortgage_status'])
  .set_ai_platform_model(GCP_PROJECT, MODEL_NAME, VERSION_NAME, adjust_prediction=adjust_prediction)
  .set_target_feature('mortgage_status')
  .set_label_vocab(['denied', 'approved']))
WitWidget(config_builder, height=800)

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

4c0b00e6afcdbe01.png

ציר ה-Y מציג לנו את החיזוי של המודל, כאשר 1 מייצג חיזוי approved ברמת מהימנות גבוהה ו-0 מייצג חיזוי denied ברמת ודאות גבוהה. ציר ה-X הוא רק הפיזור של כל נקודות הנתונים שנטענו.

שלב 2: סקירת נקודות ספציפיות על הגרף

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

בדוגמה הבאה בחרנו נקודת נתונים שקרובה לסף של 0 .5. הבקשה למשכנתה שמשויכת לנקודת הנתונים הספציפית הזו הגיעה מה-CFPB. שינינו את התכונה ל-0 ושינינו גם את הערך של agency_code_Department of Housing and Urban Development (HUD) ל-1 כדי לראות מה יקרה לחיזוי של המודל אם ההלוואה הזו תיווצר מ-HUD:

717620d6a1330479.png

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

בחלק הימני התחתון של ממשק המשתמש, ניתן גם לראות את הערך האמיתי של כל נקודת נתונים ולהשוות אותו לחיזוי של המודל:

60ff20ae80ed5e27.png

שלב 3: ניתוח נגדי

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

ae64fd7abefe5449.png

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

שלב 4: בדיקת תרשימים של תלות חלקית

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

72117b5ceb683841.png

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

applicant_income_thousands היא תכונה מספרית, ובתרשים התלות החלקית אפשר לראות שהכנסה גבוהה יותר מגדילה מעט את הסבירות שבקשה תאושר, אבל רק עד כ-200,000$. אחרי 200,000$, התכונה הזו לא משפיעה על החיזוי של המודל.

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

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

בוחרים את mortgage_status בתור התכונה Ground Truth כדי לראות מטריצת בלבול:

fe1384ee47699498.png

מטריצת הבלבול הזו מציגה את החיזויים הנכונים והשגויים של המודל שלנו, כאחוז מהסך הכולל. אם מחברים את הריבועים Actual / Predicted Yes (כן בפועל / חזוי כן) וActual No / Predicted No (לא בפועל / לא חזויה), הנתונים האלה אמורים להיות זהים לרמת הדיוק של המודל (בערך 87%).

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

לאחר מכן, בתפריט הנפתח פרוסה לפי, בוחרים באפשרות loan_purpose_Home_purchase:

f3f1858d627d57ab.png

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

אם מרחיבים את השורות כדי לבחון את מטריצות הבלבול, אפשר לראות שהמודל חוזים את הערך 'אושר'. עבור כ-70% בקשות להלוואות לרכישת בית ורק 46% מההלוואות שאינן לרכישת בית (האחוזים המדויקים משתנים בהתאם למודל):

318a8d5a8ffc6bea.png

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

שלב 6: בדיקה של הפצת התכונות

לבסוף, עוברים לכרטיסייה Features (תכונות) בכלי What-if. זוהי התפלגות הערכים של כל תכונה במערך הנתונים:

48ab3c4879793324.png

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

תיארנו כאן רק כמה רעיונות לבדיקת הכלי What-if. אתם מוזמנים להמשיך לשחק עם הכלי – יש עוד המון תחומים שאפשר לחקור.

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

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

879147427150b6c7.png

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

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