ביחידה הזו תלמדו איך להשתמש בספרייה YDF (Yggdrasil Decision Forest) כדי לאמן ולפרש עץ החלטות.
היחידה הזו מבוססת על המדריך 🧭 YDF Getting Started.
מוקדמות
לפני שמתחילים לבחון את מערך הנתונים, צריך:
- יוצרים notebook חדש ב-Colab.
- כדי להתקין את ספריית YDF, מוסיפים את שורת הקוד הבאה ומריצים אותה ב-notebook החדש ב-Colab:
!pip install ydf -U
- מייבאים את הספריות הבאות:
import ydf import numpy as np import pandas as pd
מערך הנתונים Palmer Penguins
ב-Colab הזה נעשה שימוש במערך הנתונים Palmer Penguins, שמכיל מדידות של גודל של שלושה מינים של פינגווינים:
- רצועת סנטר
- Gentoo
- Adelie
זוהי בעיית סיווג – המטרה היא לחזות את המין של הפינגווין על סמך נתונים במערך הנתונים Palmer's Penguins. אלה הפינגווינים:
איור 16. שלושה מינים שונים של פינגווינים. תמונה מאת @allisonhorst
הקוד הבא קורא לפונקציה של pandas כדי לטעון את מערך הנתונים של Palmer Penguins לזיכרון:
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 | Adelie | Torgersen | 39.1 | 18.7 | 181.0 | 3750.0 | זכר | 2007 |
1 | Adelie | Torgersen | 39.5 | 17.4 | 186.0 | 3,800.0 | נקבה | 2007 |
2 | Adelie | 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 (עצי סיווג ורגרסיה), בלי לציין היפר-פרמטרים.
הסיבה לכך היא שהלמידה של 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
זן | סבירות |
---|---|
Adelie (אדום) | 8% |
Gentoo (כחול) | 58% |
רצועת סנטר (ירוק) | 36% |
טבלה 5. הסבירות לכך שיהיו מינים שונים אם
bill_depth_mm < 42.3
זן | סבירות |
---|---|
Adelie (אדום) | 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 דוגמאות), ולכן אומדן הדיוק לא יציב.
בפועל, במערך נתונים קטן כזה, עדיף להשתמש באימות חוצה, כי הוא מחשב ערכים מדויקים יותר של מדדי ההערכה. עם זאת, בדוגמה הזו נמשיך בתהליך של אימון ובדיקה כדי לשמור על פשטות.
שיפור ההיפר-פרמטרים של המודל
המודל הוא עץ החלטות יחיד שהודר באמצעות ערכי ברירת המחדל של הפרמטרים הסופר-היפר. כדי לקבל תחזיות טובות יותר, תוכלו:
להשתמש במודל למידה חזק יותר, כמו יער אקראי או מודל gradient boosted trees. נסביר על אלגוריתמי הלמידה האלה בדף הבא.
מבצעים אופטימיזציה של הפרמטר ההיפר-מרחב על סמך התצפיות והאינטואיציה שלכם. מומלץ לעיין במדריך לשיפור מודל.
משתמשים בכוונון של היפר-פרמטרים כדי לבדוק באופן אוטומטי מספר גדול של היפר-פרמטרים אפשריים.
מכיוון שעדיין לא ראינו את אלגוריתם היער האקראי ואת אלגוריתם ה-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
הדיוק של יער האקראי גבוה יותר מהדיוק של העץ הפשוט שלנו. בדפים הבאים נסביר למה.
שימוש ומגבלות
כפי שצוין קודם, לרוב איכותו של עץ החלטות יחיד נמוכה יותר מזו של שיטות מודרניות של למידת מכונה, כמו יערות אקראיים, עצים עם שיפור שיפוע ורשתות נוירונליות. עם זאת, עצי החלטות עדיין שימושיים במקרים הבאים:
- כבסיס פשוט וזול להערכת גישות מורכבות יותר.
- כשיש פשרה בין איכות המודל לבין יכולת הפרשנות שלו.
- כתחליף לפרשנות של מודל יערות ההחלטות, שנדון בו בהמשך הקורס.