יצירת עץ החלטות

ביחידה הזו נשתמש ברכבת הספרייה YDF (Yggdrasil Decision יער) כדי לפרש עץ החלטות.

היחידה הזו מבוססת על המדריך 🧭 YDF תחילת העבודה.

מוקדמות

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

  1. יוצרים notebook חדש של Colab.
  2. מתקינים את ספריית YDF על ידי הוספה וביצוע של שורת הקוד הבאה ב-notebook החדש של Colab:
    !pip install ydf -U
    
  3. מייבאים את הספריות הבאות:
    import ydf
    import numpy as np
    import pandas as pd
    

מערך הנתונים של הפינגווינים של פאלמר

פריט Colab הזה משתמש במערך הנתונים של פינגווינים פלמר, שמכיל מדידות גודל של שלושה מיני פינגווינים:

  • רצועת סנטר
  • ג'נטו
  • אדלי

זוהי בעיית סיווג – המטרה היא לחזות את המינים של הפינגווינים על סמך נתונים במערך הנתונים של הפינגווינים של פאלמר. הנה הפינגווינים:

שלושה מינים שונים של פינגווינים.

איור 16. שלושה מינים שונים של פינגווינים. תמונה מאת @allisonhorst

 

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

path = "https://storage.googleapis.com/download.tensorflow.org/data/palmer_penguins/penguins.csv"
dataset = pd.read_csv(path)
label = "species"

# Display the first 3 examples.
dataset.head(3)

בטבלה הבאה מפורטות 3 הדוגמאות הראשונות במערך הנתונים של פינגווינים פאלמר:

טבלה 3. 3 הדוגמאות הראשונות בפינגווינים של פאלמר

מינים אי bill_length_mm bill_depth_mm flipper_length_mm body_mass_g מין שנה
0 אדלי טורגרסן 39.1 18.7 181.0 3,750.0 זכר 2007
1 אדלי טורגרסן 39.5 17.4 186.0 3,800.0 נקבה 2007
2 אדלי טורגרסן 40.3 18.0 195.0 3250.0 נקבה 2007

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

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

# Use the ~20% of the examples as the testing set
# and the remaining ~80% of the examples as the training set.
np.random.seed(1)
is_test = np.random.rand(len(dataset)) < 0.2

train_dataset = dataset[~is_test]
test_dataset = dataset[is_test]

print("Training examples: ", len(train_dataset))
# >> Training examples: 272

print("Testing examples: ", len(test_dataset))
# >> Testing examples: 72

אימון עצי החלטות באמצעות היפר-פרמטרים שמוגדרים כברירת מחדל

תוכלו לאמן את עץ ההחלטות הראשון באמצעות אלגוריתם הלמידה של CART (עצי סיווג ורגרסיה) (שנקרא גם לומד) בלי לציין היפר-פרמטרים. הסיבה לכך היא שהלומד ydf.CartLearner מספק ערכי היפר-פרמטר טובים שמוגדרים כברירת מחדל. נציג לכם מידע נוסף על האופן שבו מודל כזה פועל מאוחר יותר בקורס.

model = ydf.CartLearner(label=label).train(train_dataset)

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

קוראים לפונקציה model.plot_tree() כדי להציג את עץ ההחלטות שהתקבל:

model.plot_tree()

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

עץ החלטות שאומן באמצעות היפר-פרמטרים כברירת מחדל.

איור 17. עץ החלטות שעבר אימון באמצעות היפר-פרמטרים המוגדרים כברירת מחדל.

Colab מראה שתנאי הבסיס מכיל 243 דוגמאות. עם זאת, יכול להיות שמערך הנתונים לאימון הכיל 272 דוגמאות. 29 הדוגמאות הנותרות נשמרו אוטומטית לצורך אימות וגיזום העצים.

התנאי הראשון בודק את הערך של bill_depth_mm. בטבלאות 4 ו-5 מוצגות הסבירות לזנים שונים בהתאם לתוצאה של התנאי הראשון.

טבלה 4. הסבירות לזנים שונים אם bill_depth_mm ≥ 42.3

זן סבירות
אדלי (אדום) 8%
Gentoo (כחול) 58%
רצועת סנטר (ירוק) 36%

 

טבלה 5. הסבירות לזנים שונים אם bill_depth_mm < 42.3

זן סבירות
אדלי (אדום) 97%
Gentoo (כחול) 2%
רצועת סנטר (ירוק) 0%

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

אם הערך של bill_depth_mm ≥ 42.3 הוא True, צריך לבצע בדיקה נוספת כדי לקבוע אם flipper_length_mm ≥ 207.5 יכול להפריד באופן כמעט מושלם בין Gentoos לבין Gentoos+Adelie.

הקוד הבא מספק את רמת הדיוק של האימון והבדיקה:

train_evaluation = model.evaluate(train_dataset)
print("train accuracy:", train_evaluation.accuracy)
# >> train accuracy:  0.9338

test_evaluation = model.evaluate(test_dataset)
print("test accuracy:", test_evaluation.accuracy)
# >> test accuracy:  0.9167

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

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

שיפור ההיפר-פרמטרים של המודל

המודל הוא עץ החלטות יחיד שעבר אימון עם ערכי היפר-פרמטר שמוגדרים כברירת מחדל. כדי לקבל חיזויים טובים יותר, אפשר:

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

  2. מבצעים אופטימיזציה של ההיפר-פרמטר באמצעות התצפיות והאינטואיציה. המדריך לשיפור המודלים יכול לעזור.

  3. השתמשו בכוונון היפר-פרמטר כדי לבדוק באופן אוטומטי מספר גדול של היפר-פרמטרים אפשריים.

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

עץ ההחלטות שמופיע למעלה הוא קטן, והערוץ עם 61 דוגמאות מכיל שילוב של תוויות אדלי ו-Chinstrap. למה האלגוריתם לא חילק את העלה הזה יותר? ישנן שתי סיבות אפשריות:

  • יכול להיות שהגעתם למספר הדגימות המינימלי לכל עלה (min_examples=5 כברירת מחדל).
  • יכול להיות שהעץ חולק ואז קצר אותו כדי למנוע התאמת יתר.

מפחיתים את מספר הדוגמאות המינימלי ל-1 וצופים בתוצאות:

model = ydf.CartLearner(label=label, min_examples=1).train(train_dataset)
model.plot_tree()

עץ החלטות שעבר אימון באמצעות
min_examples=1.

איור 18. עץ החלטות שעבר אימון באמצעות min_examples=1.

 

צומת העלים שמכיל 61 דוגמאות חולק מספר פעמים.

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

print(model.evaluate(test_dataset).accuracy)
# >> 0.97222

איכות המודל עלתה מ-0.9167 ל-0.97222. השינוי הזה בהיפר-פרמטר היה רעיון טוב.

הקודם של יערות ההכרעה

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

model = ydf.RandomForestLearner(label=label).train(pandas_train_dataset)
print("Test accuracy: ", model.evaluate(pandas_test_dataset).accuracy)
# >> Test accuracy: 0.986111

הדיוק של יער אקראי טוב יותר מהעץ הפשוט שלנו. בדפים הבאים תבינו מדוע.

שימוש והגבלה

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

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