إنشاء شجرة قرارات

في هذه الوحدة، ستستخدم مكتبة YDF (غابة قرارات Yggdrasil) لتدريب شجرة قرارات وتفسيرها.

هذه الوحدة مستوحاة من 🧭 دليل بدء استخدام YDF التوجيهي.

الجولات التمهيدية

قبل دراسة مجموعة البيانات، اتّبِع الخطوات التالية:

  1. أنشئ ورقة ملاحظات جديدة في Colab.
  2. ثبِّت مكتبة YDF من خلال وضع سطر الرمز التالي وتنفيذه في ورقة ملاحظات Colab الجديدة:
    !pip install ydf -U
  3. استورِد المكتبات التالية:
    import ydf
    import numpy as np
    import pandas as pd

مجموعة بيانات بطاريق بالمر

يستخدم دفتر Colab هذا مجموعة بيانات طيور بطريق بالمر، والتي تحتوي على قياسات حجم لثلاثة أنواع من البطريق:

  • Chinstrap
  • Gentoo
  • Adelie

هذه مشكلة تصنيف، فالهدف هو توقُّع نوع البطريق استنادًا إلى البيانات الواردة في مجموعة بيانات "بطاريق بالمر". في ما يلي طيور البطريق:

ثلاثة أنواع مختلفة من البطاريق

الشكل 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)

تنسّق الجداول التالية الأمثلة الثلاثة الأولى في مجموعة بيانات 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 3800.0 أنثى 2007
2 Adelie Torgersen 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%
جنتو (أزرق) 58%
Chinstrap (أخضر) 36%

 

الجدول 5. احتمالية ظهور أنواع مختلفة إذا كان bill_depth_mm < 42.3

الأنواع الاحتمالية
آديلي (أحمر) 97%
جنتو (أزرق) 2%
Chinstrap (أخضر) 0%

bill_depth_mm هي ميزة رقمية. وبالتالي، تم العثور على القيمة 42.3 باستخدام خوارزمية التقسيم الدقيق للتصنيف الثنائي باستخدام الميزات الرقمية.

إذا كانت قيمة bill_depth_mm ≥ 42.3 هي True، سيتم إجراء المزيد من الاختبارات لتحديد ما إذا كان بإمكان flipper_length_mm ≥ 207.5 الفصل بين طيور البطريق جنتو وطيور البطريق جنتو+أديلي بشكل شبه مثالي.

يوفر الرمز التالي دقة التدريب والاختبار للنموذج:

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 مثالاً على مزيج من تصنيفات Adelie و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(train_dataset)
print("Test accuracy: ", model.evaluate(test_dataset).accuracy)
# >> Test accuracy: 0.986111

تكون دقة الغابة العشوائية أفضل من دقة الشجرة البسيطة. ستتعرّف في الصفحات التالية على الأسباب.

الاستخدام والقيود

كما ذكرنا سابقًا، غالبًا ما تكون جودة شجرة القرار الواحدة أقل من جودة طرق تعلُّم الآلة الحديثة، مثل الغابات العشوائية وأشجار التدرّج المعزّز والشبكات العصبية. ومع ذلك، تظل أشجار القرارات مفيدة في الحالات التالية:

  • كأساس بسيط وغير مكلف لتقييم الأساليب الأكثر تعقيدًا
  • عندما يكون هناك توازن بين جودة النموذج وقابليته للتفسير
  • وهي تمثّل تفسير نموذج "غابات القرار" الذي سنتعرّف عليه لاحقًا في الدورة التدريبية.