تصف هذه المقالة خوارزمية شجرة القرار التي تنفذها Java. شاركه للرجوع إليه ، على النحو التالي:
خوارزمية شجرة القرار هي طريقة لتقريب قيمة وظيفة منفصلة. إنها طريقة تصنيف نموذجية ، أولاً معالجة البيانات ، باستخدام خوارزمية الحث لإنشاء قواعد قابلة للقراءة وأشجار القرار ، ثم استخدام القرارات لتحليل البيانات الجديدة. في جوهرها ، أشجار القرار هي عملية تصنيف البيانات من خلال سلسلة من القواعد.
يمكن تنفيذ بناء شجرة القرار في خطوتين. الخطوة الأولى هي توليد شجرة القرار: عملية إنشاء شجرة القرار من مجموعة عينة التدريب. بشكل عام ، مجموعة بيانات عينة التدريب هي مجموعة بيانات لها تاريخ ودرجة معينة من الشمولية وفقًا للاحتياجات الفعلية وتستخدم لتحليل البيانات ومعالجتها. الخطوة الثانية هي تقليم شجرة القرار: التقليم من شجرة القرار هو عملية التحقق وتصحيح ومراجعة شجرة القرار التي تم إنشاؤها في المرحلة السابقة. يستخدم بشكل أساسي البيانات من مجموعة بيانات العينة الجديدة (تسمى مجموعة بيانات الاختبار) للتحقق من القواعد الأولية التي تم إنشاؤها أثناء عملية توليد شجرة القرار ، وتشذيب تلك الفروع التي تؤثر على دقة ما قبل التوازن.
رمز تنفيذ Java كما يلي:
Package Demo ؛ import java.util.hashmap ؛ import java.util.linkedList ؛ import java.util.list ؛ استيراد java.util.map ؛ استيراد java.util.map.entry نتيجة:")؛ string [] attrnames = new string [] {"Age" ، "الدخل" ، "الطالب" ، "credit_rating"} ؛ // اقرأ نموذج SET SET MAP <كائن ، قائمة <Sample >> samples = readsamples (attrnames) ؛ // إنشاء كائن شجرة القرار decentree = endrendedCisionTree (عينات ، attrnames) ؛ // إخراج Tree Tree OutputDecisionTree (القرار ، 0 ، فارغ) ؛ } / *** اقرأ مجموعة العينة التي تم تصنيفها وإرجاع الخريطة: التصنيف-> قائمة العينات التي تنتمي إلى الفئة* / خريطة ثابتة <كائن ، قائمة <sample >> readsamples (string [] attrnames) {// sample entributes و deservision (you. "عالية" ، "لا" ، "عادلة" ، "0"} ، {"<30" ، "عالية" ، "لا" ، "ممتازة" ، "0" ، {"30-40" ، "عالية" ، "لا" ، "عادل" ، "1" ، "،" ، "،" ، "،" ، "،" ، "،" ، "،" ، "،" ، "،" ، "،" ، "،" ، "،" ، "،" ، "،" ، "،" ، "،" ، "،" ، "" "" ، "" "" "" "" "" "" "" "" "" "" } ، {"> 40" ، "Low" ، "Yes" ، "Exclude" ، "0"} ، {"30-40" ، "Low" ، "Yes" ، "Exclude" ، "1"} ، {"<30" ، "medience" ، "no" ، "no" ، {"}" ، {1 "، {1" ، " "نعم" ، "عادلة" ، "1"} ، {"<30" ، "متوسطة" ، "نعم" ، "ممتاز" ، "1" ، {"30-40" ، "متوسطة" ، "لا" ، "ممتازة" ، "1"} ، {"30-40 ،" عالية "،" نعم ، "" ، "1" ، "" } ؛ // اقرأ سمات العينة وتصنيفاتها ، وقم ببناء كائن العينة الذي يمثل العينة ، وقسّم العينة التي تم تعيينها حسب خريطة التصنيف <كائن ، قائمة <sample >> ret = new hashmap <object ، list <sample >> () ؛ لـ (Object [] الصف: rawdata) {نموذج عينة = عينة جديدة () ؛ int i = 0 ؛ لـ (int n = row.length - 1 ؛ i <n ؛ i ++) sample.setattribute (attrnames [i] ، row [i]) ؛ sample.setCategory (row [i]) ؛ قائمة <sample> عينات = ret.get (الصف [i]) ؛ if (samples == null) {samples = new LinkedList <sample> () ؛ ret.put (الصف [i] ، عينات) ؛ } samples.add (عينة) ؛ } إرجاع ret ؛ } / *** إنشاء شجرة القرار* / كائن ثابت endrendedCisionTree (خريطة <كائن ، قائمة <sample >> catexorysamples ، string [] attrnames) {// إذا كانت هناك عينة واحدة فقط ، استخدم التصنيف الذي ينتمي إليه العينة (recasionset). // إذا لم يكن هناك سمة لاتخاذ القرارات ، فسيتم استخدام التصنيف مع معظم العينات في مجموعة العينة كتصنيف للعينة الجديدة ، أي ، التصويت على التصنيف إذا (attrnames.length == 0) {int max = 0 ؛ كائن maxcategory = null ؛ لـ (إدخال <كائن ، قائمة <sample >> الإدخال: categorytoSamples .entRySet ()) {int cur = entrad.getValue (). size () ؛ if (cur> max) {max = cur ؛ maxCategory = intpl.getKey () ؛ }} إرجاع maxcategory ؛ }. . // لا ينبغي تحديد سمات الاختبار المستخدمة كسمات اختبار مرة أخرى سلسلة [] suba = سلسلة جديدة [attrnames.length - 1] ؛ لـ (int i = 0 ، j = 0 ؛ i <attrnames.length ؛ i ++) if (i! = (integer) rst [0]) suba [j ++] = attrnames [i] ؛ // إنشاء فرع استنادًا إلى سمات الفرع @suppresswarnings ("غير محدد") خريطة <كائن ، خريطة <كائن ، قائمة <sample>> splits =/ * سطر جديد */(خريطة <كائن ، خريطة ، قائمة <sample>>) rst [2] ؛ لـ (إدخال <كائن ، خريطة <كائن ، قائمة <Sample >>> الإدخال: splits.EntrySet ()) {Object attrvalue = intpling.getKey () ؛ خريطة <كائن ، قائمة <Sample >> split = intply.getValue () ؛ Object child = endrendedCisionTree (split ، suba) ؛ tree.setchild (attrvalue ، طفل) ؛ } شجرة العودة ؛ } /*** حدد سمة الاختبار الأمثل. تعني الأمثل أنه إذا كان فرع سمة الاختبار المحدد يعتمد على فرع سمة الاختبار المحدد ، فسيتم تحديد مجموع المعلومات المطلوبة لتصنيف العينة الجديدة* من كل فرع ، وهو ما يعادل كسب المعلومات القصوى التي تم الحصول عليها عن طريق تحديد سمة الاختبار للعينة الجديدة*/ مختار (مختار ". خريطة <كائن ، قائمة <Sample >> cateortosamples ، string [] attrnames) {int minindex = -1 ؛ // السمة الأمثل subcript double minvalue = double.max_value ؛ // الحد الأدنى من المعلومات خريطة <كائن ، خريطة <كائن ، قائمة <sample >>> minsplits = null ؛ // مخطط الفرع الأمثل // لكل سمة ، احسب مجموع المعلومات المطلوبة لتحديد تصنيف العينة الجديدة في كل فرع عند استخدامه كسمة اختبار ، وحدد الحد الأدنى المثالي لـ (int attrindex = 0 ؛ attrindex <attrnames.length ؛ attrindex ++) {int allcount = 0 ؛ // عداد لحساب العدد الإجمالي للعينات // قم بإنشاء خريطة وفقًا للسمة الحالية: قيمة السمة-> (التصنيف-> قائمة العينة) خريطة <كائن ، خريطة <كائن ، قائمة <sample >>> corsplits =/ * سطر جديد */new hashmap <كائن ، خريطة ، قائمة <sample >>> () ؛ لـ (إدخال <كائن ، قائمة <Sample >> الإدخال: categoryToSamples .entrySet ()) {كائن الفئة = interpl.getKey () ؛ قائمة <Sample> عينات = enter.getValue () ؛ لـ (عينة عينة: العينات) {Object attrvalue = sample .getattribute (attrnames [attrindex]) ؛ خريطة <كائن ، قائمة <Sample >> split = cursplits.get (attrvalue) ؛ if (split == null) {split = new hashmap <object ، argen <sample >> () ؛ cursplits.put (attrvalue ، split) ؛ } قائمة <Sample> splitsamples = split.get (الفئة) ؛ if (splitsamples == null) {splitsamples = new LinkedList <Sample> () ؛ split.put (الفئة ، splitsamples) ؛ } splitsamples.add (عينة) ؛ } allcount += samples.size () ؛ } // احسب مجموع المعلومات المطلوبة لتحديد تصنيف العينة الجديدة في كل فرع عند استخدام السمة الحالية كسمة اختبار مزدوجة = 0.0 ؛ // Counter: تراكم كل فرع لـ (MAP <Object ، قائمة <sample >> splits: cursplits.values ()) {double perspleitCount = 0 ؛ لـ (قائمة <sample> القائمة: splits.values ()) persplitCount += list.size () ؛ // عينات الفرع الحالي التراكمي perspleitvalue = 0.0 ؛ // العداد: الفرع الحالي لـ (قائمة <sample> القائمة: splits.values ()) {double p = list.size () / perspletCount ؛ persplitvalue -= p * (Math.log (p) / math.log (2)) ؛ } curvalue += (persplitcount / allcount) * persplitvalue ؛ } // حدد الحد الأدنى إلى الأمثل if (minvalue> curvalue) {minIndex = attrindex ؛ minvalue = curvalue ؛ minsplits = cursplits ؛ }} إرجاع كائن جديد [] {minindex ، minvalue ، minsplits} ؛ } / *** إخراج شجرة القرار إلى الإخراج القياسي* / static void outputDecisionTree (Object OBJ ، int level ، كائن من) {for (int i = 0 ؛ i <level ؛ i ++) system.out.print ("| ------") ؛ إذا (من! = null) system.out.printf ("(٪ s):" ، من) ؛ if (OBJ مثيل TREE) {شجرة شجرة = (شجرة) OBJ ؛ string attrname = tree.getAttribute () ؛ system.out.printf ("[٪ s =؟]/n" ، attrname) ؛ لـ (Object attrvalue: tree.getAttributeValues ()) {Object Child = tree.getChild (attrvalue) ؛ outputDecisionTree (الطفل ، المستوى + 1 ، attrname + "=" + attrvalue) ؛ }} else {system.out.printf ("[category = ٪ s]/n" ، obj) ؛ }} / *** عينة ، تحتوي على سمات متعددة وقيمة تصنيف تحدد التصنيف الذي تنتمي إليه العينة* / static class عينة {خريطة خاصة <string ، object> attributes = new hashmap <string ، Object> () ؛ فئة الكائنات الخاصة ؛ الكائن العام getAttribute (اسم السلسلة) {return attributes.get (name) ؛ } public void setattribut (اسم السلسلة ، قيمة الكائن) {attributes.put (الاسم ، القيمة) ؛ } الكائن العام getCategory () {فئة الإرجاع ؛ } public void setCategory (فئة الكائن) {this.category = الفئة ؛ } السلسلة العامة toString () {return attributes.toString () ؛ }} /*** شجرة القرار (العقدة غير الورقية) ، كل عقدة غير أوراق في شجرة القرار تقود شجرة قرار* تحتوي كل عقدة غير أوراق على سمة فرع وفروع متعددة. كل قيمة من سمة الفرع تتوافق مع فرع. يرشد الفرع شجرة القرار الفرعية*/ شجرة الفئة الثابتة {سمة سلسلة خاصة ؛ الخريطة الخاصة <كائن ، كائن> أطفال = هاشماب جديد <كائن ، كائن> () ؛ الشجرة العامة (سمة السلسلة) {this.attribute = السمة ؛ } السلسلة العامة getAttribute () {return endribute ؛ } الكائن العام getChild (Object attrvalue) {return Kids.get (attrvalue) ؛ } public void setChild (Object attrvalue ، Object child) {knids.put (attrvalue ، child) ؛ } المجموعة العامة <Object> getAttributeValues () {return Kids.KeySet () ؛ }}}نتائج التشغيل:
لمزيد من المعلومات حول خوارزميات Java ، يمكن للقراء المهتمين بهذا الموقع عرض الموضوعات: "بنية بيانات Java وبرنامج تعليمي الخوارزمية" ، "ملخص" Tips Java ".
آمل أن يكون هذا المقال مفيدًا لبرمجة Java للجميع.