برنامج تعليمي حول الغابة العشوائية في لغة R: خوارزمية مع مثال

⚡ ملخص ذكي

تُنشئ خوارزمية الغابة العشوائية في لغة البرمجة R مئات أشجار القرار باستخدام عينات مُعاد تجميعها، ثم تُحسب متوسط ​​نتائجها للحصول على تنبؤ قوي واحد. يشرح هذا الدليل كيفية ضبط دوال mtry وmaxnodes وntree باستخدام مكتبة caret، ويُقيّم النموذج النهائي على بيانات النجاة من كارثة تيتانيك.

  • 🌳 المبدأ الأساسي: تقوم عملية التجميع بتدريب كل شجرة على عينة بوتستراب ومجموعة فرعية عشوائية من المتنبئات، بحيث يتم إلغاء الأخطاء الفردية أثناء التصويت بالأغلبية.
  • 🧪 إعداد التحقق: يقوم trainControl(method = “cv”, number = 10, search = “grid”) بإصلاح عملية بحث الشبكة ذات العشرة أضعاف التي يتم إعادة استخدامها في كل خطوة ضبط.
  • 🎯 ترتيب الضبط: قم بتحسين mtry أولاً، ثم maxnodes، ثم ntree، مع نقل القيمة الفائزة إلى الأمام في كل مرحلة.
  • 📈 أفضل تكوين: mtry = 4، maxnodes = 24، و ntree = 800 أنتجت أقوى دقة تم التحقق منها بشكل متقاطع على مجموعة البيانات هذه.
  • 🧮 نتيجة الفحص: تشير دالة confusionMatrix() إلى دقة بنسبة 79.43 بالمائة، وحساسية بنسبة 0.9091، وخصوصية بنسبة 0.6364 على البيانات المحجوزة.

الغابة العشوائية في لغة R

ما هي الغابة العشوائية في R؟

تعتمد الغابات العشوائية على فكرة بسيطة: "حكمة الجمهور". يعطي إجمالي نتائج المتنبئين المتعددين تنبؤًا أفضل من أفضل متنبئ فردي. مجموعة من المتنبئين تسمى طاقم. وهكذا تسمى هذه التقنية فرقة التعلم.

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

قبل كتابة أي كود، من المفيد أن ترى بالضبط كيف يتم تجميع الغابة من تلك الأشجار الفردية.

كيف تعمل خوارزمية الغابة العشوائية في لغة البرمجة R؟

إن فهم الآليات يجعل من السهل فهم كل معلمة ضبط. يتم بناء الغابة العشوائية على أربع مراحل.

  1. Bootstrap أخذ العينات. تقوم الخوارزمية بسحب عينة عشوائية من الصفوف مع الاستبدال من مجموعة التدريب لكل شجرة. يتم استبعاد ما يقرب من ثلث الصفوف من كل عينة؛ وهذه هي الملاحظات خارج الحقيبة (OOB).
  2. اختيار الميزات عشوائياً. في كل عملية تقسيم، يتم النظر فقط في مجموعة فرعية عشوائية من المتغيرات التنبؤية. حجم هذه المجموعة الفرعية هو mtry المعيار. إن تقييد الخيارات هو ما يمنع جميع الأشجار من أن تبدو متشابهة.
  3. نمو الأشجار غير المقلمة. تنمو كل شجرة حتى تصل إلى نقطة توقفping قاعدة مثل com.maxnodes or حجم العقدةيُسمح للأشجار الفردية عمداً بالتجاوز في التخصيص، لأن أخطائها غير مترابطة.
  4. تجميع. في التصنيف، تُعيد الغابة الفئة التي حصلت على أكبر عدد من الأصوات؛ أما في الانحدار، فتُعيد متوسط ​​التنبؤ. هذه الخطوة المتوسطة هي ما يُسمى بمصطلح التعبئة (تجميع التمهيد) يصف.

يكمن سر النجاح في أخذ عينات من الصفوف والأعمدة معًا. تتميز الشجرة العميقة الواحدة بانحياز منخفض وتباين عالٍ جدًا؛ ويحافظ حساب متوسط ​​مئات الأشجار على الانحياز المنخفض مع تقليل التباين.

خطأ خارج الحقيبة. بما أن كل ملاحظة تُستبعد من حوالي ثلث الأشجار، فإن R يستطيع تقييم كل صف باستخدام الأشجار التي لم ترَه أبدًا فقط. خطأ OOB الناتج هو تقدير تحقق مدمج مجاني يُطبع بواسطة دالة randomForest().

rf_oob <- randomForest(survived~., data = data_train, ntree = 800, mtry = 4)
print(rf_oob)   # reports the OOB estimate of error rate

يُعد خطأ OOB فحصًا سريعًا ومريحًا، ولكن هذا البرنامج التعليمي يستخدم التحقق المتقاطع ذو العشرة أضعاف من خلال caret بحيث تتم مقارنة كل شبكة ضبط على طيات متطابقة.

مقارنة بين الغابة العشوائية وشجرة القرار في لغة البرمجة R

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

المعايير شجرة القرار غابة عشوائية
الهيكلية شجرة واحدة تم دمج مئات الأشجار عن طريق التصويت
التباين عالية، حساسة للغاية لعينة التدريب يؤدي انخفاض المتوسط ​​إلى إلغاء الأخطاء الفردية
مخاطر الإفراط في التخصيص مرتفع ما لم يتم تقليمه منخفضة حتى مع الأشجار غير المقلمة
التفسير يمكن قراءتها بالكامل كمخطط انسيابي لا يمكن قراءة سوى أهمية المتغيرات
تكلفة التدريب سريع جدا متناسب مع ntree
التحقق من الصحة المضمنة بدون سلوفان تقدير الخطأ خارج العينة
وظيفة R ربارت () الغابة العشوائية()

اختر شجرة واحدة عندما يتعين عليك شرح مسار القرار لجمهور غير متخصص. اختر غابة عندما تكون دقة التنبؤ أهم من سهولة قراءة الرسم البياني.

مزايا وعيوب Random Forest

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

المزايا

  • الدقة دون حذف: يؤدي حساب متوسط ​​العديد من الأشجار غير المترابطة إلى نتائج قوية مع القليل جدًا من الضبط اليدوي.
  • مقاوم للتخصيص الزائد: إضافة المزيد من الأشجار لا تزيد من خطأ التعميم، لذلك يمكن زيادة ntree بأمان.
  • يتعامل مع البيانات المختلطة: تعمل المؤشرات العددية والعوامل جنبًا إلى جنب، ولا حاجة إلى تغيير المقياس.
  • التحقق والتصنيف مجاناً: لا يترتب على خطأ OOB و varImp() أي تكلفة حسابية إضافية.

عيوب

  • تنبؤات مبهمة: لا تستطيع tracمسار قرار واحد، وهو أمر مهم في البيئات الخاضعة للتنظيم.
  • بطيء في الغابات الكبيرة: يتناسب وقت التدريب والتنبؤ خطيًا مع عدد الأشجار.
  • درجات الأهمية المتحيزة: قد تبدو المتغيرات الفئوية ذات المستويات المتعددة أكثر أهمية مما هي عليه في الواقع.
  • استقراء ضعيف: بالنسبة للانحدار، لا يمكن للغابة التنبؤ خارج النطاق الذي شوهد في التدريب.

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

الخطوة 1) استيراد البيانات

للتأكد من أن لديك نفس مجموعة البيانات كما في البرنامج التعليمي لـ أشجار القراريتم استضافة مجموعتي التدريب والاختبار عبر الإنترنت. يمكنك استيرادهما دون إجراء أي تغيير.

library(dplyr)
data_train <- read.csv("https://raw.githubusercontent.com/guru99-edu/R-Programming/master/train.csv")
glimpse(data_train)
data_test <- read.csv("https://raw.githubusercontent.com/guru99-edu/R-Programming/master/test.csv") 
glimpse(data_test)

الخطوة 2) تدريب النموذج

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

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

تختار الغابة العشوائية مجموعة فرعية عشوائية من الميزات وتبني العديد من أشجار القرار. يقوم النموذج بحساب متوسط ​​جميع تنبؤات أشجار القرارات.

تحتوي خوارزمية الغابة العشوائية على بعض المعاملات التي يمكن تغييرها لتحسين قدرة التنبؤ على التعميم. ستستخدم الدالة randomForest() لتدريب النموذج.

صيغة الدالة randomForest() هي:

randomForest(formula, ntree=n, mtry=FALSE, maxnodes = NULL)
Arguments:
- Formula: Formula of the fitted model
- ntree: number of trees in the forest
- mtry: Number of candidate variables drawn at each split. By default, it is the square root of the number of predictors for classification.
- maxnodes: Set the maximum number of terminal nodes each tree can have
- importance=TRUE: Whether independent variables importance in the random forest be assessed

ملاحظات: يمكن تدريب الغابة العشوائية على المزيد من المعلمات. يمكنك الرجوع إلى المقالة القصيرة لرؤية المعلمات المختلفة.

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

  • بحث عشوائي
  • شبكة البحث

كلا الطريقتين موضحتان أدناه، ولكن هذا البرنامج التعليمي يدرب النموذج باستخدام البحث الشبكي.

تعريف بحث الشبكة

طريقة البحث في الشبكة بسيطة، وسيتم تقييم النموذج على جميع المجموعات التي تمررها في الوظيفة، باستخدام التحقق المتبادل.

على سبيل المثال، تريد تجربة النموذج الذي يحتوي على 10، 20، 30 عددًا من الأشجار وسيتم اختبار كل شجرة على عدد من المحاولات يساوي 1، 2، 3، 4، 5. ثم سيقوم الجهاز باختبار 15 نموذجًا مختلفًا:

    .mtry ntrees
 1      1     10
 2      2     10
 3      3     10
 4      4     10
 5      5     10
 6      1     20
 7      2     20
 8      3     20
 9      4     20
 10     5     20
 11     1     30
 12     2     30
 13     3     30
 14     4     30
 15     5     30	

ستقوم الخوارزمية بتقييم:

randomForest(formula, ntree=10, mtry=1)
randomForest(formula, ntree=10, mtry=2)
randomForest(formula, ntree=10, mtry=3)
randomForest(formula, ntree=20, mtry=2)
...

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

تعريف البحث العشوائي

يكمن الفرق الرئيسي بين البحث العشوائي والبحث الشبكي في أن البحث العشوائي لا يُقيّم جميع تركيبات المعلمات الفائقة في فضاء البحث، بل يختار تركيبة عشوائية في كل تكرار. وتتمثل ميزته في انخفاض التكلفة الحسابية بشكل ملحوظ.

ضبط معلمة التحكم

سوف تتابع على النحو التالي لبناء النموذج وتقييمه:

  • قم بتقييم النموذج باستخدام الإعداد الافتراضي
  • العثور على أفضل عدد من mtry
  • العثور على أفضل عدد من maxnodes
  • العثور على أفضل عدد من الأشجار
  • تقييم النموذج في مجموعة بيانات الاختبار

قبل أن تبدأ باستكشاف المعلمات، تحتاج إلى تثبيت مكتبتين.

يمكنك استيرادها مع برنامج randomForest:

library(randomForest)
library(caret)
library(e1071)

الإعدادات الإفتراضية

يتم التحكم في التحقق من صحة K-fold بواسطة وظيفة TrainControl ().

trainControl(method = "cv", number = n, search ="grid")
arguments
- method = "cv": The method used to resample the dataset. 
- number = n: Number of folds to create
- search = "grid": Use the grid search method. For the randomized method, use "random"
Note: You can refer to the vignette to see the other arguments of the function.

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

ملاحظات: سوف تستخدم نفس عناصر التحكم خلال كل البرنامج التعليمي.

# Define the control
trControl <- trainControl(method = "cv",
    number = 10,
    search = "grid")

سوف تستخدم مكتبة علامة الإقحام لتقييم النموذج الخاص بك. تحتوي المكتبة على وظيفة واحدة تسمى Train() لتقييم جميع العناصر تقريبًا آلة التعلم الخوارزمية. بعبارة أخرى، يمكنك استخدام هذه الوظيفة لتدريب خوارزميات أخرى.

بناء الجملة الأساسي هو:

train(formula, df, method = "rf", metric= "Accuracy", trControl = trainControl(), tuneGrid = NULL)
argument
- `formula`: Define the formula of the algorithm
- `method`: Define which model to train. Note, at the end of the tutorial, there is a list of all the models that can be trained
- `metric` = "Accuracy": Define how to select the optimal model
- `trControl = trainControl()`: Define the control parameters
- `tuneGrid = NULL`: Return a data frame with all the possible combination

لنقم ببناء النموذج باستخدام القيم الافتراضية.

set.seed(1234)
# Run the model
rf_default <- train(survived~.,
    data = data_train,
    method = "rf",
    metric = "Accuracy",
    trControl = trControl)
# Print the results
print(rf_default)

Code تفسير

  • trainControl(method=”cv”, number=10, search=”grid”): تقييم النموذج باستخدام بحث شبكي على 10 طيات
  • تدريب(…): تدريب نموذج الغابة العشوائية. يتم اختيار أفضل نموذج مع مقياس الدقة.

الإخراج:

## Random Forest 
## 
## 836 samples
##   7 predictor
##   2 classes: 'No', 'Yes' 
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold) 
## Summary of sample sizes: 753, 752, 753, 752, 752, 752, ... 
## Resampling results across tuning parameters:
## 
##   mtry  Accuracy   Kappa    
##    2    0.7919248  0.5536486
##    6    0.7811245  0.5391611
##   10    0.7572002  0.4939620
## 
## Accuracy was used to select the optimal model using  the largest value.
## The final value used for the model was mtry = 2.

تستخدم الخوارزمية 500 شجرة واختبرت ثلاث قيم مختلفة لـ mtry: 2، 6، 10.

كانت القيمة النهائية المستخدمة للنموذج mtry = 2، مع دقة تحقق متقاطع بلغت 0.792. لنحاول الحصول على درجة أعلى.

ابحث عن أفضل mtry

يمكنك اختبار النموذج بقيم mtry من 1 إلى 10

set.seed(1234)
tuneGrid <- expand.grid(.mtry = c(1: 10))
rf_mtry <- train(survived~.,
    data = data_train,
    method = "rf",
    metric = "Accuracy",
    tuneGrid = tuneGrid,
    trControl = trControl,
    importance = TRUE,
    nodesize = 14,
    ntree = 300)
print(rf_mtry)

Code تفسير

  • tuneGrid <- expand.grid(.mtry = c(1:10)): إنشاء متجه بقيم من 1 إلى 10

الإخراج:

## Random Forest 
## 
## 836 samples
##   7 predictor
##   2 classes: 'No', 'Yes' 
## 
## No pre-processing
## Resampling: Cross-Validated (10 fold) 
## Summary of sample sizes: 753, 752, 753, 752, 752, 752, ... 
## Resampling results across tuning parameters:
## 
##   mtry  Accuracy   Kappa    
##    1    0.7572576  0.4647368
##    2    0.7979346  0.5662364
##    3    0.8075158  0.5884815
##    4    0.8110729  0.5970664
##    5    0.8074727  0.5900030
##    6    0.8099111  0.5949342
##    7    0.8050918  0.5866415
##    8    0.8050918  0.5855399
##    9    0.8050631  0.5855035
##   10    0.7978916  0.5707336
## 
## Accuracy was used to select the optimal model using  the largest value.
## The final value used for the model was mtry = 4.

أفضل قيمة لـ mtry هي 4. يتم تخزينها في:

rf_mtry$bestTune$mtry

يمكنك تخزينه واستخدامه عندما تحتاج إلى ضبط المعلمات الأخرى.

max(rf_mtry$results$Accuracy)

الإخراج:

## [1] 0.8110729
best_mtry <- rf_mtry$bestTune$mtry 
best_mtry

الإخراج:

## [1] 4

الخطوة 3) ابحث عن أفضل العقد القصوى

يجب عليك إنشاء حلقة لتقييم القيم المختلفة لـ maxnodes. في الكود التالي، ستقوم بما يلي:

  • انشئ قائمة
  • قم بإنشاء متغير بأفضل قيمة للمعلمة mtry؛ إلزامي
  • قم بإنشاء الحلقة
  • قم بتخزين القيمة الحالية للعقدة القصوى
  • لخص النتائج
store_maxnode <- list()
tuneGrid <- expand.grid(.mtry = best_mtry)
for (maxnodes in c(5: 15)) {
    set.seed(1234)
    rf_maxnode <- train(survived~.,
        data = data_train,
        method = "rf",
        metric = "Accuracy",
        tuneGrid = tuneGrid,
        trControl = trControl,
        importance = TRUE,
        nodesize = 14,
        maxnodes = maxnodes,
        ntree = 300)
    current_iteration <- toString(maxnodes)
    store_maxnode[[current_iteration]] <- rf_maxnode
}
results_mtry <- resamples(store_maxnode)
summary(results_mtry)

Code تفسير:

  • store_maxnode <- list(): سيتم تخزين نتائج النموذج في هذه القائمة
  • توسيع.جريد(.mtry=best_mtry): استخدم أفضل قيمة لـ mtry
  • for (maxnodes in c(5:15)) { … }: حساب النموذج بقيم maxnodes من 5 إلى 15.
  • maxnodes = maxnodes: في كل تكرار، تساوي قيمة maxnodes قيمة الحلقة الحالية، أي 5، 6، 7، ...
  • current_iteration <- toString(maxnodes): قم بتخزين قيمة maxnodes كسلسلة نصية.
  • store_maxnode[[current_iteration]] <- rf_maxnode: حفظ نتيجة النموذج في القائمة.
  • resamples(store_maxnode): ترتيب نتائج النموذج
  • ملخص (results_mtry): طباعة ملخص كل المجموعة.

الإخراج:

## 
## Call:
## summary.resamples(object = results_mtry)
## 
## Models: 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 
## Number of resamples: 10 
## 
## Accuracy 
##         Min.   1st Qu.    Median      Mean   3rd Qu.      Max. NA's
## 5  0.6785714 0.7529762 0.7903758 0.7799771 0.8168388 0.8433735    0
## 6  0.6904762 0.7648810 0.7784710 0.7811962 0.8125000 0.8313253    0
## 7  0.6904762 0.7619048 0.7738095 0.7788009 0.8102410 0.8333333    0
## 8  0.6904762 0.7627295 0.7844234 0.7847820 0.8184524 0.8433735    0
## 9  0.7261905 0.7747418 0.8083764 0.7955250 0.8258749 0.8333333    0
## 10 0.6904762 0.7837780 0.7904475 0.7895869 0.8214286 0.8433735    0
## 11 0.7023810 0.7791523 0.8024240 0.7943775 0.8184524 0.8433735    0
## 12 0.7380952 0.7910929 0.8144005 0.8051205 0.8288511 0.8452381    0
## 13 0.7142857 0.8005952 0.8192771 0.8075158 0.8403614 0.8452381    0
## 14 0.7380952 0.7941050 0.8203528 0.8098967 0.8403614 0.8452381    0
## 15 0.7142857 0.8000215 0.8203528 0.8075301 0.8378873 0.8554217    0
## 
## Kappa 
##         Min.   1st Qu.    Median      Mean   3rd Qu.      Max. NA's
## 5  0.3297872 0.4640436 0.5459706 0.5270773 0.6068751 0.6717371    0
## 6  0.3576471 0.4981484 0.5248805 0.5366310 0.6031287 0.6480921    0
## 7  0.3576471 0.4927448 0.5192771 0.5297159 0.5996437 0.6508314    0
## 8  0.3576471 0.4848320 0.5408159 0.5427127 0.6200253 0.6717371    0
## 9  0.4236277 0.5074421 0.5859472 0.5601687 0.6228626 0.6480921    0
## 10 0.3576471 0.5255698 0.5527057 0.5497490 0.6204819 0.6717371    0
## 11 0.3794326 0.5235007 0.5783191 0.5600467 0.6126720 0.6717371    0
## 12 0.4460432 0.5480930 0.5999072 0.5808134 0.6296780 0.6717371    0
## 13 0.4014252 0.5725752 0.6087279 0.5875305 0.6576219 0.6678832    0
## 14 0.4460432 0.5585005 0.6117973 0.5911995 0.6590982 0.6717371    0
## 15 0.4014252 0.5689401 0.6117973 0.5867010 0.6507194 0.6955990    0

أعلى متوسط ​​دقة في هذا النطاق (0.8099) يُسجّل عند قيمة maxnodes = 14، وهي أعلى قيمة في الفترة المختبرة. ولأن أفضل قيمة تقع على حافة الشبكة، يُنصح بتوسيع نطاق البحث صعودًا.

store_maxnode <- list()
tuneGrid <- expand.grid(.mtry = best_mtry)
for (maxnodes in c(20: 30)) {
    set.seed(1234)
    rf_maxnode <- train(survived~.,
        data = data_train,
        method = "rf",
        metric = "Accuracy",
        tuneGrid = tuneGrid,
        trControl = trControl,
        importance = TRUE,
        nodesize = 14,
        maxnodes = maxnodes,
        ntree = 300)
    key <- toString(maxnodes)
    store_maxnode[[key]] <- rf_maxnode
}
results_node <- resamples(store_maxnode)
summary(results_node)

الإخراج:

## 
## Call:
## summary.resamples(object = results_node)
## 
## Models: 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 
## Number of resamples: 10 
## 
## Accuracy 
##         Min.   1st Qu.    Median      Mean   3rd Qu.      Max. NA's
## 20 0.7142857 0.7821644 0.8144005 0.8075301 0.8447719 0.8571429    0
## 21 0.7142857 0.8000215 0.8144005 0.8075014 0.8403614 0.8571429    0
## 22 0.7023810 0.7941050 0.8263769 0.8099254 0.8328313 0.8690476    0
## 23 0.7023810 0.7941050 0.8263769 0.8111302 0.8447719 0.8571429    0
## 24 0.7142857 0.7946429 0.8313253 0.8135112 0.8417599 0.8690476    0
## 25 0.7142857 0.7916667 0.8313253 0.8099398 0.8408635 0.8690476    0
## 26 0.7142857 0.7941050 0.8203528 0.8123207 0.8528758 0.8571429    0
## 27 0.7023810 0.8060456 0.8313253 0.8135112 0.8333333 0.8690476    0
## 28 0.7261905 0.7941050 0.8203528 0.8111015 0.8328313 0.8690476    0
## 29 0.7142857 0.7910929 0.8313253 0.8087063 0.8333333 0.8571429    0
## 30 0.6785714 0.7910929 0.8263769 0.8063253 0.8403614 0.8690476    0
## 
## Kappa 
##         Min.   1st Qu.    Median      Mean   3rd Qu.      Max. NA's
## 20 0.3956835 0.5316120 0.5961830 0.5854366 0.6661120 0.6955990    0
## 21 0.3956835 0.5699332 0.5960343 0.5853247 0.6590982 0.6919315    0
## 22 0.3735084 0.5560661 0.6221836 0.5914492 0.6422128 0.7189781    0
## 23 0.3735084 0.5594228 0.6228827 0.5939786 0.6657372 0.6955990    0
## 24 0.3956835 0.5600352 0.6337821 0.5992188 0.6604703 0.7189781    0
## 25 0.3956835 0.5530760 0.6354875 0.5912239 0.6554912 0.7189781    0
## 26 0.3956835 0.5589331 0.6136074 0.5969142 0.6822128 0.6955990    0
## 27 0.3735084 0.5852459 0.6368425 0.5998148 0.6426088 0.7189781    0
## 28 0.4290780 0.5589331 0.6154905 0.5946859 0.6356141 0.7189781    0
## 29 0.4070588 0.5534173 0.6337821 0.5901173 0.6423101 0.6919315    0
## 30 0.3297872 0.5534173 0.6202632 0.5843432 0.6590982 0.7189781    0

تُحقق أعلى دقة متوسطة، وهي 0.8135، عند استخدام maxnodes = 24 (حيث أن maxnodes = 27 تُساوي المتوسط، ولكنها تُعطي قيمة أقل في الربع الثالث). لذا، ستستخدم maxnodes = 24 في الخطوات المتبقية.

الخطوة 4) ابحث عن أفضل الأشجار

الآن بعد أن حصلت على أفضل قيمة لـ mtry وmaxnode، يمكنك ضبط عدد الأشجار. الطريقة هي نفسها تمامًا مثل maxnode.

store_maxtrees <- list()
for (ntree in c(250, 300, 350, 400, 450, 500, 550, 600, 800, 1000, 2000)) {
    set.seed(5678)
    rf_maxtrees <- train(survived~.,
        data = data_train,
        method = "rf",
        metric = "Accuracy",
        tuneGrid = tuneGrid,
        trControl = trControl,
        importance = TRUE,
        nodesize = 14,
        maxnodes = 24,
        ntree = ntree)
    key <- toString(ntree)
    store_maxtrees[[key]] <- rf_maxtrees
}
results_tree <- resamples(store_maxtrees)
summary(results_tree)

الإخراج:

## 
## Call:
## summary.resamples(object = results_tree)
## 
## Models: 250, 300, 350, 400, 450, 500, 550, 600, 800, 1000, 2000 
## Number of resamples: 10 
## 
## Accuracy 
##           Min.   1st Qu.    Median      Mean   3rd Qu.      Max. NA's
## 250  0.7380952 0.7976190 0.8083764 0.8087010 0.8292683 0.8674699    0
## 300  0.7500000 0.7886905 0.8024240 0.8027199 0.8203397 0.8452381    0
## 350  0.7500000 0.7886905 0.8024240 0.8027056 0.8277623 0.8452381    0
## 400  0.7500000 0.7886905 0.8083764 0.8051009 0.8292683 0.8452381    0
## 450  0.7500000 0.7886905 0.8024240 0.8039104 0.8292683 0.8452381    0
## 500  0.7619048 0.7886905 0.8024240 0.8062914 0.8292683 0.8571429    0
## 550  0.7619048 0.7886905 0.8083764 0.8099062 0.8323171 0.8571429    0
## 600  0.7619048 0.7886905 0.8083764 0.8099205 0.8323171 0.8674699    0
## 800  0.7619048 0.7976190 0.8083764 0.8110820 0.8292683 0.8674699    0
## 1000 0.7619048 0.7976190 0.8121510 0.8086723 0.8303571 0.8452381    0
## 2000 0.7619048 0.7886905 0.8121510 0.8086723 0.8333333 0.8452381    0
## 
## Kappa 
##           Min.   1st Qu.    Median      Mean   3rd Qu.      Max. NA's
## 250  0.4061697 0.5667400 0.5836013 0.5856103 0.6335363 0.7196807    0
## 300  0.4302326 0.5449376 0.5780349 0.5723307 0.6130767 0.6710843    0
## 350  0.4302326 0.5449376 0.5780349 0.5723185 0.6291592 0.6710843    0
## 400  0.4302326 0.5482030 0.5836013 0.5774782 0.6335363 0.6710843    0
## 450  0.4302326 0.5449376 0.5780349 0.5750587 0.6335363 0.6710843    0
## 500  0.4601542 0.5449376 0.5780349 0.5804340 0.6335363 0.6949153    0
## 550  0.4601542 0.5482030 0.5857118 0.5884507 0.6396872 0.6949153    0
## 600  0.4601542 0.5482030 0.5857118 0.5884374 0.6396872 0.7196807    0
## 800  0.4601542 0.5667400 0.5836013 0.5910088 0.6335363 0.7196807    0
## 1000 0.4601542 0.5667400 0.5961590 0.5857446 0.6343666 0.6678832    0
## 2000 0.4601542 0.5482030 0.5961590 0.5862151 0.6440678 0.6656337    0

لقد حصلت على النموذج النهائي. يمكنك تدريب الغابة العشوائية بالمعلمات التالية:

  • ntree = 800: سيتم تدريب 800 شجرة
  • mtry = 4: يتم رسم 4 ميزات مرشحة عند كل تقسيم
  • maxnodes = 24: يقتصر كل شجر على 24 عقدة طرفية (أوراق).
fit_rf <- train(survived~.,
    data_train,
    method = "rf",
    metric = "Accuracy",
    tuneGrid = tuneGrid,
    trControl = trControl,
    importance = TRUE,
    nodesize = 14,
    ntree = 800,
    maxnodes = 24)

الخطوة 5) تقييم النموذج

تحتوي علامة إقحام المكتبة على وظيفة للتنبؤ.

predict(model, newdata= df)
argument
- `model`: Define the model evaluated before. 
- `newdata`: Define the dataset to make prediction
prediction <-predict(fit_rf, data_test)

يمكنك استخدام التنبؤ لحساب مصفوفة الارتباك ورؤية درجة الدقة

confusionMatrix(prediction, data_test$survived)

الإخراج:

## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  No Yes
##        No  110  32
##        Yes  11  56
##                                          
##                Accuracy : 0.7943         
##                  95% CI : (0.733, 0.8469)
##     No Information Rate : 0.5789         
##     P-Value [Acc > NIR] : 3.959e-11      
##                                          
##                   Kappa : 0.5638         
##  Mcnemar's Test P-Value : 0.002289       
##                                          
##             Sensitivity : 0.9091         
##             Specificity : 0.6364         
##          Pos Pred Value : 0.7746         
##          Neg Pred Value : 0.8358         
##              Prevalence : 0.5789         
##          Detection Rate : 0.5263         
##    Detection Prevalence : 0.6794         
##       Balanced Accuracy : 0.7727         
##                                          
##        'Positive' Class : No             
## 

يحقق النموذج دقة تبلغ 0.7943، أي 79.43%، على مجموعة الاختبار غير المرئية، وهي نسبة أعلى من الإعدادات الافتراضية. تبلغ الحساسية 0.9091 والنوعية 0.6364، مما يعني أن النموذج يتعرف على غير الناجين بموثوقية أعلى بكثير من الناجين.

الخطوة 6) تصور النتيجة

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

varImp(fit_rf)

الإخراج:

## rf variable importance
## 
##              Importance
## sexmale         100.000
## age              28.014
## pclassMiddle     27.016
## fare             21.557
## pclassUpper      16.324
## sibsp            11.246
## parch             5.522
## embarkedC         4.908
## embarkedQ         1.420
## embarkedS         0.000		

الغابة العشوائية في لغة R: مرجع سريع للوظائف

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

المكتبة الهدف الوظيفة معامل
RandomForest أنشئ غابة عشوائية الغابة العشوائية() الصيغة، ntree=n، mtry=FALSE، maxnodes = NULL
الإقحام إنشاء التحقق المتقاطع k-fold التحكم في القطار () الطريقة = "cv"، الرقم = n، البحث = "الشبكة"
الإقحام تدريب غابة عشوائية قطار() الصيغة، df، الطريقة = "rf"، المتري = "الدقة"، trControl = TrainControl()، tuneGrid = NULL
الإقحام توقع خارج العينة تنبأ النموذج، البيانات الجديدة = df
الإقحام مصفوفة الارتباك والإحصائيات الارتباك مصفوفة() نموذج، اختبار ذ
الإقحام أهمية المتغير varImp() نموذج

الملحق: النماذج المتوفرة في المربع

يمكن لدالة train() أن تُدرّب نماذج أكثر بكثير من مجرد الغابات العشوائية. شغّل الأمر أدناه لعرض جميع مُعرّفات النماذج التي يدعمها caret، ثم مرّر أيًا منها إلى وسيطة الدالة.

names(getModelInfo())

الإخراج:

##   [1] "ada"                 "AdaBag"              "AdaBoost.M1"        ##   [4] "adaboost"            "amdai"               "ANFIS"              ##   [7] "avNNet"              "awnb"                "awtan"              ##  [10] "bag"                 "bagEarth"            "bagEarthGCV"        ##  [13] "bagFDA"              "bagFDAGCV"           "bam"                ##  [16] "bartMachine"         "bayesglm"            "binda"              ##  [19] "blackboost"          "blasso"              "blassoAveraged"     ##  [22] "bridge"              "brnn"                "BstLm"              ##  [25] "bstSm"               "bstTree"             "C5.0"               ##  [28] "C5.0Cost"            "C5.0Rules"           "C5.0Tree"           ##  [31] "cforest"             "chaid"               "CSimca"             ##  [34] "ctree"               "ctree2"              "cubist"             ##  [37] "dda"                 "deepboost"           "DENFIS"             ##  [40] "dnn"                 "dwdLinear"           "dwdPoly"            ##  [43] "dwdRadial"           "earth"               "elm"                ##  [46] "enet"                "evtree"              "extraTrees"         ##  [49] "fda"                 "FH.GBML"             "FIR.DM"             ##  [52] "foba"                "FRBCS.CHI"           "FRBCS.W"            ##  [55] "FS.HGD"              "gam"                 "gamboost"           ##  [58] "gamLoess"            "gamSpline"           "gaussprLinear"      ##  [61] "gaussprPoly"         "gaussprRadial"       "gbm_h3o"            ##  [64] "gbm"                 "gcvEarth"            "GFS.FR.MOGUL"       ##  [67] "GFS.GCCL"            "GFS.LT.RS"           "GFS.THRIFT"         ##  [70] "glm.nb"              "glm"                 "glmboost"           ##  [73] "glmnet_h3o"          "glmnet"              "glmStepAIC"         ##  [76] "gpls"                "hda"                 "hdda"               ##  [79] "hdrda"               "HYFIS"               "icr"                ##  [82] "J48"                 "JRip"                "kernelpls"          ##  [85] "kknn"                "knn"                 "krlsPoly"           ##  [88] "krlsRadial"          "lars"                "lars2"              ##  [91] "lasso"               "lda"                 "lda2"               ##  [94] "leapBackward"        "leapForward"         "leapSeq"            ##  [97] "Linda"               "lm"                  "lmStepAIC"          ## [100] "LMT"                 "loclda"              "logicBag"           ## [103] "LogitBoost"          "logreg"              "lssvmLinear"        ## [106] "lssvmPoly"           "lssvmRadial"         "lvq"                ## [109] "M5"                  "M5Rules"             "manb"               ## [112] "mda"                 "Mlda"                "mlp"                ## [115] "mlpKerasDecay"       "mlpKerasDecayCost"   "mlpKerasDropout"    ## [118] "mlpKerasDropoutCost" "mlpML"               "mlpSGD"             ## [121] "mlpWeightDecay"      "mlpWeightDecayML"    "monmlp"             ## [124] "msaenet"             "multinom"            "mxnet"              ## [127] "mxnetAdam"           "naive_bayes"         "nb"                 ## [130] "nbDiscrete"          "nbSearch"            "neuralnet"          ## [133] "nnet"                "nnls"                "nodeHarvest"        ## [136] "null"                "OneR"                "ordinalNet"         ## [139] "ORFlog"              "ORFpls"              "ORFridge"           ## [142] "ORFsvm"              "ownn"                "pam"                ## [145] "parRF"               "PART"                "partDSA"            ## [148] "pcaNNet"             "pcr"                 "pda"                ## [151] "pda2"                "penalized"           "PenalizedLDA"       ## [154] "plr"                 "pls"                 "plsRglm"            ## [157] "polr"                "ppr"                 "PRIM"               ## [160] "protoclass"          "pythonKnnReg"        "qda"                ## [163] "QdaCov"              "qrf"                 "qrnn"               ## [166] "randomGLM"           "ranger"              "rbf"                ## [169] "rbfDDA"              "Rborist"             "rda"                ## [172] "regLogistic"         "relaxo"              "rf"                 ## [175] "rFerns"              "RFlda"               "rfRules"            ## [178] "ridge"               "rlda"                "rlm"                ## [181] "rmda"                "rocc"                "rotationForest"     ## [184] "rotationForestCp"    "rpart"               "rpart1SE"           ## [187] "rpart2"              "rpartCost"           "rpartScore"         ## [190] "rqlasso"             "rqnc"                "RRF"                ## [193] "RRFglobal"           "rrlda"               "RSimca"             ## [196] "rvmLinear"           "rvmPoly"             "rvmRadial"          ## [199] "SBC"                 "sda"                 "sdwd"               ## [202] "simpls"              "SLAVE"               "slda"               ## [205] "smda"                "snn"                 "sparseLDA"          ## [208] "spikeslab"           "spls"                "stepLDA"            ## [211] "stepQDA"             "superpc"             "svmBoundrangeString"## [214] "svmExpoString"       "svmLinear"           "svmLinear2"         ## [217] "svmLinear3"          "svmLinearWeights"    "svmLinearWeights2"  ## [220] "svmPoly"             "svmRadial"           "svmRadialCost"      ## [223] "svmRadialSigma"      "svmRadialWeights"    "svmSpectrumString"  ## [226] "tan"                 "tanSearch"           "treebag"            ## [229] "vbmpRadial"          "vglmAdjCat"          "vglmContRatio"      ## [232] "vglmCumulative"      "widekernelpls"       "WM"                 ## [235] "wsrf"                "xgbLinear"           "xgbTree"            ## [238] "xyf"

الأسئلة الشائعة

ابدأ بـ 500، وهي القيمة الافتراضية لدالة randomForest(). عادةً ما تستقر الدقة بين 300 و1000 شجرة. زيادة عدد الأشجار (ntree) لا تؤثر سلبًا على الدقة، بل على وقت التشغيل فقط، لذا قم بزيادته حتى يستقر منحنى الخطأ.

يُقيّم خطأ العينة الخارجية كل ملاحظة باستخدام الأشجار المدربة بدونها فقط. وهو تقدير سريع وغير متحيز، وغالبًا ما يحل محل التحقق المتقاطع، على الرغم من أن التحقق المتقاطع k-fold يبقى مفضلًا عند مقارنة شبكات الضبط على طيات متطابقة.

نعم. أدخل قيمة عددية، وسيقوم برنامج randomForest() بحساب متوسط ​​تنبؤات الشجرة بدلاً من التصويت. في مكتبة caret، احتفظ بالقيمة method = "rf" وقم بتغيير وسيط المقياس من Accuracy إلى RMSE.

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

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

تلخيص هذه التدوينة بـ: