ביחידה הזו נשתמש בספריית YDF (Yggdrasil Decision Forest) כדי לאמן עץ החלטות ולפרש אותו.
היחידה הזו מבוססת על המדריך 🧭 YDF Getting Started.
מוקדמות
לפני שבודקים את מערך הנתונים, צריך:
- יוצרים מחברת Colab חדשה.
- כדי להתקין את ספריית YDF, מציבים ומריצים את שורת הקוד הבאה ב-notebook החדש של Colab:
!pip install ydf -U
- מייבאים את הספריות הבאות:
import ydf import numpy as np import pandas as pd
מערך הנתונים Palmer Penguins
ב-Colab הזה נעשה שימוש במערך הנתונים Palmer Penguins, שמכיל מדידות של גודל שלושה מינים של פינגווינים:
- Chinstrap
- Gentoo
- אדלי
זו בעיית סיווג – המטרה היא לחזות את מין הפינגווין על סמך נתונים במערך הנתונים Palmer's Penguins. אלה הפינגווינים:
איור 16. שלושה מינים שונים של פינגווינים. תמונה מאת @allisonhorst
הקוד הבא קורא לפונקציה של pandas כדי לטעון את מערך הנתונים של פינגוויני פאלמר לזיכרון:
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 הדוגמאות הראשונות במערך הנתונים Palmer Penguins:
טבלה 3. 3 הדוגמאות הראשונות ב-Palmer Penguins
מין | אי | bill_length_mm | bill_depth_mm | flipper_length_mm | body_mass_g | סקס | שנה | |
---|---|---|---|---|---|---|---|---|
0 | אדלי | Torgersen | 39.1 | 18.7 | 181.0 | 3750.0 | זכר | 2007 |
1 | אדלי | Torgersen | 39.5 | 17.4 | 186.0 | 3800.0 | נקבה | 2007 |
2 | אדלי | Torgersen | 40.3 | 18.0 | 195.0 | 3250.0 | נקבה | 2007 |
מערך הנתונים המלא מכיל תערובת של תכונות מספריות (לדוגמה, bill_depth_mm
), קטגוריות (לדוגמה, island
) ותכונות חסרות. בניגוד לרשתות עצביות, יערות החלטה תומכים בכל סוגי התכונות האלה באופן מובנה, כך שלא צריך לבצע קידוד one-hot, נורמליזציה או תכונת 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 (Classification and Regression Trees, עצי סיווג ורגרסיה), בלי לציין היפרפרמטרים.
הסיבה לכך היא שהאלגוריתם 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 נמצא באמצעות האלגוריתם exact splitting for binary classification with numerical features.
אם 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 דוגמאות), ולכן הערכת הדיוק רועשת.
בפועל, במערך נתונים קטן כזה, עדיף להשתמש באימות צולב כי הוא יחשב ערכים מדויקים יותר של מדדי הערכה. עם זאת, בדוגמה הזו אנחנו ממשיכים עם אימון ובדיקה כדי לפשט את הדברים.
שיפור ההיפר-פרמטרים של המודל
המודל הוא עץ החלטה יחיד שאומן עם ערכי היפרפרמטרים שמוגדרים כברירת מחדל. כדי לקבל תחזיות טובות יותר, אפשר:
שימוש במודל לומד חזק יותר, כמו random forest או gradient boosted trees. בדף הבא מוסבר על האלגוריתמים האלה ללמידה.
מבצעים אופטימיזציה של ההיפרפרמטר באמצעות התצפיות והאינטואיציה. המדריך לשיפור המודל יכול לעזור.
אפשר להשתמש בכוונון של היפר-פרמטרים כדי לבדוק באופן אוטומטי מספר גדול של היפר-פרמטרים אפשריים.
מכיוון שעדיין לא ראינו את האלגוריתם של יער אקראי ואת האלגוריתם של עצים עם שיפוע מוגבר, ומכיוון שמספר הדוגמאות קטן מדי כדי לבצע כוונון אוטומטי של היפרפרמטרים, נשפר את המודל באופן ידני.
עץ ההחלטה שמוצג למעלה הוא קטן, והעלה עם 61 הדוגמאות מכיל שילוב של תוויות Adelie ו-Chinstrap. למה האלגוריתם לא חילק את הצומת הזה עוד יותר? ישנן שתי סיבות אפשריות:
- יכול להיות שהגעתם למספר המינימלי של דגימות לכל עלה (
min_examples=5
כברירת מחדל). - יכול להיות שהעץ חולק ואז נגזם כדי למנוע התאמת יתר.
מצמצמים את מספר הדוגמאות המינימלי ל-1 ובודקים את התוצאות:
model = ydf.CartLearner(label=label, min_examples=1).train(train_dataset)
model.plot_tree()
איור 18. עץ החלטה שאומן עם min_examples=1.
צומת העלה שמכיל 61 דוגמאות חולק עוד כמה פעמים.
כדי לבדוק אם כדאי לפצל עוד יותר את הצומת, אנחנו מעריכים את האיכות של המודל החדש הזה במערך נתוני הבדיקה:
print(model.evaluate(test_dataset).accuracy)
# >> 0.97222
איכות המודל השתפרה, ורמת הדיוק של הבדיקה עלתה מ-0.9167 ל-0.97222. השינוי הזה בהיפר-פרמטר היה רעיון טוב.
תצוגה מקדימה של יערות החלטה
אם נמשיך לשפר את ההיפרפרמטרים, סביר להניח שנגיע לרמת דיוק מושלמת. עם זאת, במקום התהליך הידני הזה, אפשר לאמן מודל חזק יותר, כמו יער אקראי, ולבדוק אם הוא עובד טוב יותר.
model = ydf.RandomForestLearner(label=label).train(train_dataset)
print("Test accuracy: ", model.evaluate(test_dataset).accuracy)
# >> Test accuracy: 0.986111
הדיוק של יער אקראי טוב יותר מהדיוק של עץ פשוט. בדפים הבאים נסביר למה.
שימוש ומגבלות
כמו שציינו קודם, האיכות של עץ החלטה יחיד לרוב נמוכה יותר מזו של שיטות מודרניות של למידת מכונה, כמו יערות אקראיים, עצים עם שיפור גרדיאנט ורשתות עצביות. עם זאת, עצי החלטה עדיין שימושיים במקרים הבאים:
- כנקודת בסיס פשוטה וזולה להערכת גישות מורכבות יותר.
- כשיש פשרה בין איכות המודל לבין יכולת ההסבר שלו.
- כפרוקסי לפרשנות של מודל יערות ההחלטה, שיוסבר בהמשך הקורס.