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

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

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

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

قبل دراسة مجموعة البيانات، عليك إجراء ما يلي:

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

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

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

  • Chinstrap
  • جنتو
  • 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)

يُعدِّل الجدول التالي الأمثلة الثلاثة الأولى في مجموعة بيانات Palmer Penguins:

الجدول 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%
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 مثالاً على مزيج من تصنيفات Adelie وChinstrap. لماذا لم تقسِّم الخوارزمية هذه الورقة بشكل أكبر؟ ‏‫يوجد سببان محتملان لذلك:

  • قد يكون قد تمّ الوصول إلى الحدّ الأدنى لعدد العيّنات لكلّ ورقة (min_examples=5 تلقائيًا).
  • قد تكون الشجرة قد تم تقسيمها ثم تقليمها لمنع التكيّف المفرط.

يمكنك تقليل الحد الأدنى لعدد الأمثلة إلى 1 والاطّلاع على النتائج:

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

شجرة قرار تم تدريبها باستخدام قيمة param=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

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

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

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

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