وأشجار القرار هي واحدة من أكثر الخوارزميات إلهائية استخداما على نطاق واسع بالنسبة للتصنيف والتراجع، وهي تعمل عن طريق تقسيم البيانات إلى فروع قائمة على قيم خاصة، مما يخفف من شأن البشر في اتخاذ القرارات، وفي حين أن المكتبات مثل الكيسية التي تتعلم صنع أشجار القرار، فإن تنفيذ واحد من الخدش هو طريقة ممتازة للبدء في فهم دليل العمل غير الشرعي.

ما هو القرار تري؟

وتشكل شجرة القرار هيكلاً شبيهاً بالهيكل الداخلي حيث يمثل كل عقد داخلي اختباراً على سمة (مثل " عمر 30 عاماً " )، يمثل كل فرع نتيجة ذلك الاختبار، ويحمل كل عقدة أوراق علامة حرفية أو قيمة مستمرة، والهدف هو وضع نموذج يتوقّع متغيراً مستهدفاً من خلال تعلم قواعد قرار بسيطة مستمدة من سمات البيانات، وأشجار القرار شعبية لأنها سهلة التجهيز وتتطلب.

وتبنى الشجرة بصورة علاجية: فمنطلقاً من الجذر، تختار الخوارزمية أفضل سمة ونقطة انقسام تفصل بين البيانات بشكل أنظف، وتُكرر هذه العملية على كل مجموعة فرعية إلى أن يتم الوفاء بشرط التوقف، وتقدم معلومات أساسية أكثر عن دخول ويكبيديا ] إلى تعلم شجرة القرار استعراضاً عاماً متيناً.

المفاهيم الأساسية يجب أن تفهم

Nodes, Branches, and leaves

وتحتوي هذه المجموعة على مجموعة بيانات التدريب بأكملها، وتختبر المعاهد الداخلية سمة وتقسم البيانات إلى مصفوفين أو أكثر من الأطفال، والفروع هي الروابط التي تمثل نتيجة الاختبار، وتنتج عوارض الليف (العقد) التنبؤ النهائي - وهو أكثر الطبقات شيوعا في التصنيف أو القيمة الدنيوية في التراجع.

المعايير المفصلية

لبناء شجرة تحتاج إلى طريقة لقياس نوعية الإنقسام المحتمل

  • Gini impurity] - المستخدم في التصنيف لقياس مدى احتمال أن يكون العنصر المختار عشوائياً ملصقاً بشكل غير صحيح إذا كان قد وُصف بشكل عشوائي وفقاً لتوزيع الفصول في المجموعة الفرعية.
  • Entropy] - تدبّر كمية الاضطراب أو عدم اليقين في مجموعة ما، والهدف هو التقليل إلى أدنى حد من الانقسام بعد الانقسام (كسب المعلومات).
  • تخفيض الفرق - المستخدم في أشجار التراجع، وهو يحسب الانخفاض في الفرق (أو الخطأ المربع المتوسط) الذي تحقق من جراء التجزئة.

ويقيِّم الخوارزمية كل انقسام ممكن على كل سمة ويختار المميز الذي يُحدث أكبر انخفاض في الشدة (أو يكسب المعلومات).

جيم - معدل جني المعلومات وغازها

أما زيادة المعلومات فهي الفرق بين شدة العشب الأبوي وكمية شدة الأطفال، وفي حين أنها بسيطة، فإنها تميل إلى تفضيل الملامح التي تنطوي على قيم عديدة، ونسبة الأرباح (المستخدمة في الفئة جيم-4-5) تطبيعها، ولهذا التعليم سنلتزم بمكسب المعلومات الموحد باستخدام امتصاص جيني، وهو التخلف في CART (التكرير والاتجاهات التراجعية).

بناء خطى القرار خطوة بخطوة

1 - إعداد بياناتكم

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

  • Features:] Age, income
  • Target:] Approved (1) or Not Approved (0)

نظف البيانات: معالجة القيم المفقودة، وإزالة الازدواج، وضمان الأنواع العددية، ويمكن لأشجار القرار أن تعالج أنواع البيانات المختلطة، ولكننا سنلتزم بالأرقام اللازمة للتنفيذ.

2 - تحديد وظيفة الارتداد

سننفذ شدة (جيني) فهرس (جيني) لمجموعة من البنود هو:

حيث تكون نسبة المواد في الصف الأول. بالنسبة للقسم الثنائي، فإن متوسط وزن الجنين هو المتوسط المرجح لقطعة الأطفال.

3- تنفيذ التقييم المنفصل

وبالنسبة لكل سمة، تصنف القيم الفريدة، وتختبر كل عتبة ممكنة (بين القيم المتتالية المصنَّفة)، وتقسم البيانات لكل عتبة مرشح إلى مجموعات اليسار واليمين، وتحسب جيني، وتتتبع أفضل تقسيم.

4 - بناء شجرة التكرار

إنشاء وظيفة تأخذ مجموعة فرعية من البيانات وعمق حالي، وتتحقق من ظروف التوقف (مثلاً، أقصى عمق تم الوصول إليه، أو الحد الأدنى من العينات لكل عقدة، أو عدم الحصول على معلومات)، وإذا ما تم استيفاء شرط، تخلق عقدة أوراق مع فئة الأغلبية، وإلا، تجد أفضل انقسام وتخلق عقداً داخلياً، ثم تُسترجع الوظيفة على اليسار والانقسامات اليمنى.

5- صنع الفرضيات

بمجرد بناء الشجرة، التنبؤات مباشرة: البدء من الجذر، تتبع الفروع من خلال تقييم اختبارات السمة على العينة الجديدة، وإعادة قيمة الورقة التي تهبط عليها.

التنفيذ الكامل في بيتسون

وفيما يلي تنفيذ كامل وبسيط لشجرة اتخاذ القرارات للتصنيف باستخدام شدة جيني، وهذا الرمز مقصود بالتعلم - لا يُستحسن أن تكون بيانات كبيرة.

import numpy as np
from collections import Counter

class DecisionTree:
 def __init__(self, max_depth=None, min_samples_split=2):
 self.max_depth = max_depth
 self.min_samples_split = min_samples_split
 self.tree = None

 def fit(self, X, y):
 dataset = np.column_stack((X, y))
 self.tree = self._grow_tree(dataset)

 def _grow_tree(self, dataset, depth=0):
 X, y = dataset[:, :-1], dataset[:, -1]
 n_samples, n_features = X.shape
 n_labels = len(np.unique(y))

 # Stopping conditions
 if (n_labels == 1 or depth == self.max_depth or n_samples < self.min_samples_split):
 leaf_value = Counter(y).most_common(1)[0][0]
 return {'leaf': True, 'value': leaf_value}

 best_feature, best_threshold = self._best_split(dataset, n_features)
 if best_feature is None:
 leaf_value = Counter(y).most_common(1)[0][0]
 return {'leaf': True, 'value': leaf_value}

 left_idx, right_idx = self._split(dataset[:, best_feature], best_threshold)
 left_subtree = self._grow_tree(dataset[left_idx], depth+1)
 right_subtree = self._grow_tree(dataset[right_idx], depth+1)
 return {'leaf': False,
 'feature': best_feature,
 'threshold': best_threshold,
 'left': left_subtree,
 'right': right_subtree}

 def _best_split(self, dataset, n_features):
 best_gini = float('inf')
 best_feature, best_threshold = None, None
 for feature in range(n_features):
 thresholds = np.unique(dataset[:, feature])
 for i in range(len(thresholds)-1):
 thresh = (thresholds[i] + thresholds[i+1]) / 2
 left_idx, right_idx = self._split(dataset[:, feature], thresh)
 if len(left_idx) == 0 or len(right_idx) == 0:
 continue
 gini = self._gini_gain(dataset, left_idx, right_idx)
 if gini < best_gini:
 best_gini = gini
 best_feature = feature
 best_threshold = thresh
 return best_feature, best_threshold

 def _split(self, values, threshold):
 left_idx = np.where(values <= threshold)[0]
 right_idx = np.where(values > threshold)[0]
 return left_idx, right_idx

 def _gini_gain(self, dataset, left_idx, right_idx):
 total = len(left_idx) + len(right_idx)
 gini_left = self._gini(dataset[left_idx, -1])
 gini_right = self._gini(dataset[right_idx, -1])
 return (len(left_idx)/total) * gini_left + (len(right_idx)/total) * gini_right

 def _gini(self, labels):
 _, counts = np.unique(labels, return_counts=True)
 p = counts / np.sum(counts)
 return 1 - np.sum(p**2)

 def predict(self, X):
 return np.array([self._predict_row(x, self.tree) for x in X])

 def _predict_row(self, x, node):
 if node['leaf']:
 return node['value']
 if x[node['feature']] <= node['threshold']:
 return self._predict_row(x, node['left'])
 else:
 return self._predict_row(x, node['right'])

اختبار شجرة

Use a simple dataset like the Class iris dataset (two features for binary classification). The scikit —learn Iris dataset] works well. Compare your tree’s accuracy with scikit —learn’s to verify correctness.

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

data = load_iris()
X = data.data[:100] # take only first two classes (binary)
y = data.target[:100]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

tree = DecisionTree(max_depth=3)
tree.fit(X_train, y_train)
preds = tree.predict(X_test)
accuracy = np.mean(preds == y_test)
print(f'Accuracy: {accuracy:.2f}')

التقنيات المتقدمة لتحسين خطتك

الهروب إلى الملاءمة الزائدة

ويمكن أن تُذكر شجرة ناضجة تماماً الضجيج في بيانات التدريب، ويزيل الركض فروعاً لا تملك سوى قدرة تنبؤية ضئيلة، والأساليب المشتركة هي الفرز الأولي (النمو المبكِّر عبر أو ]) وما بعد التكرار (تنمو الشجرة الكاملة ثم تزيل الفروع باستخدام مجموعة من المصادقة أو عملية الضبط التكاليف).

معالجة الآثار المستمرة والقاطعة

وبالنسبة للملامح المستمرة، استخدمنا نقاط الوسط بين القيم المصنَّفة كعتبات، وبالنسبة للملامح المفهرسة (مثلاً " الكلور = الأحمر/الغريني/التراكمي " )، يمكن أن تصبح كل فئة فرعاً مستقلاً (مقسماً عبر الطرق) أو أن تكونا ثنائيين، وتستخدم معظم التنفيذات الحديثة (مثل المعارف المتعلقة بالتعلم) تقسيمات الثنائية حتى في تقييم جميع العناصر الفرعية.

معالجة مسألة القيمة المفقودة

فبيانات العالم الحقيقي غالبا ما تكون قيما ناقصة، فالنهج البسيط هو تخصيص قيم مفقودة لأحدث فرع في عينات التدريب التي لها السمة، حيث أن المادة 4-5 تستخدم طريقة محتملة، وبما أن هذه الدراسة هي التعليم الابتدائي، فإننا نفترض أن البيانات كاملة.

مقارنة المكتبات والقراءة الإضافية

وفي حين أن البناء من الصفر هو التعليم، فإن نظم الإنتاج تستخدم مكتبات مثل شبكة التعلم التي توفر التنفيذ الأمثل للجيم، ويمكنك أن تتعلم المزيد من الوثائق الرسمية [(FLT:0]) المتعلقة بأشجار القرار التي تتعلم عن طريق التعلم، وهي مرجعيات ممتازة للكتاب المرجعي.

خاتمة

بناء شجرة قرار من الخدش يزيل أحد أهم الخوارزميات الأساسية في التعلم الآلاتي، وقد تعلمت كيف يمكن لعملية تقسيم بسيطة للترفيه أن تنتج نموذجا قويا، وبكتابة الرمز بنفسك، ستكسب فهما أعمق لتدابير الشوائب، واختيارا مجزأ، والمبادلات بين التحيز والفروق، وكخطوة قادمة، تحاول إضافة دعم تراجعي، أو طرق تعزيزية، أو معالجة سمات متطورة.