English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

كتابة شجرة القرار المفصلة باستخدام Python

يُستخدم شجرة القرار عادةً في التعلم الآلي للتصنيف.

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

1. زيادة المعلومات

غرض تقسيم مجموعة البيانات هو: جعل البيانات غير النظامية أكثر نظامًا. طريقة واحدة لتنظيم البيانات الفوضوية هي استخدام قياسات نظرية المعلومات. عادة ما يتم استخدام زيادة المعلومات، وهي قيمة انخفاض إنتروبيا المعلومات قبل وبعد تقسيم البيانات. كلما كانت المعلومات أقل نظامًا، زادت إنتروبياها، وأفضل ميزة للحصول على أكبر زيادة في المعلومات هي الخيار الأمثل.
熵定义为信息的期望,符号xi的信息定义为:

其中p(xi)为该分类的概率。
熵,即信息的期望值为:

计算信息熵的代码如下:

def calcShannonEnt(dataSet):
  numEntries = len(dataSet)
  labelCounts = {}
  للمقادير في فيكتور الميزات في dataSet:
    currentLabel = featVec[-1]
    if currentLabel not in labelCounts:
      labelCounts[currentLabel] = 0
    labelCounts[currentLabel] += 1
  shannonEnt = 0
  for key in labelCounts:
    shannonEnt = shannonEnt - (labelCounts[key]/numEntries)*math.log2(labelCounts[key]/numEntries)
  عدد البيانات الجديدة

可以根据信息熵,按照获取最大信息增益的方法划分数据集。

2.划分数据集

划分数据集就是将所有符合要求的元素抽出来。

تعريف splitDataSet(dataSet,axis,قيمة):
  عدد البيانات الجديدة = []
  للمقادير في فيكتور الميزات في dataSet:
    إذا كان فيكتور الميزات[مستوى] == قيمة:
      الفيектор الجديد = فيكتور الميزات[:مستوى]
      newVec.extend(featVec[axis+1:])
      retDataset.append(newVec)
  عدد البيانات الجديدة

3.选择最好的数据集划分方式

信息增益是熵的减少或者是信息无序度的减少。

تعريف chooseBestFeatureToSplit(dataSet):
  عدد الميزات = طول dataSet[0] - 1
  أفضل معلوماتية = 0
  أفضل الميزات = -1
  إنتروبيا الأساس = حساب إنتروبيا شانون dataSet
  للمقادير في نطاق عدد الميزات:
    allValue = [example[i] for example in dataSet]#列表推倒,创建新的列表
    allValue = set(allValue)#最快得到列表中唯一元素值的方法
    إنتروبيا جديدة = 0
    للمقادير في جميع القيم:
      النقاط المفصلة = splitDataSet(dataSet,i,قيمة)
      إنتروبيا جديدة = إنتروبيا جديدة + طول (النقاط المفصلة) / طول dataSet * حساب إنتروبيا شانون (النقاط المفصلة)
    معلوماتية = إنتروبيا الأساس - إنتروبيا جديدة
    إذا كانت معلوماتية > أفضل معلوماتية:
      أفضل معلوماتية = معلوماتية
      أفضل الميزات = i
  عدد الأفضلية

4.递归创建决策树

结束条件为:程序遍历完所有划分数据集的属性,或每个分支下的所有实例都具有相同的分类。
当数据集已经处理了所有属性,但是类标签还不唯一时,采用多数表决的方式决定叶子节点的类型。

تعريف majorityCnt(fئات):
 عدد الفئات = {}
 للمقادير في فئات:
  إذا لم يكن قيمة في عدد الفئات: عدد الفئات[قيمة] = 0
  عدد الفئات[قيمة] += 1
 classCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
 عدد الفئات[0][0] 

生成决策树:

تعريف createTree(dataSet,labels):
 فئات = [مثال[-1] للكل مثال في dataSet]
 labelsCopy = labels[:]
 إذا كان عدد فئات.count(fئات[0]) يساوي طول فئات:
  عدد الفئات[0]
 إذا كان طول dataSet[0] يساوي 1:
  return majorityCnt(classList)
 bestFeature = chooseBestFeatureToSplit(dataSet)
 bestLabel = labelsCopy[bestFeature]
 myTree = {bestLabel:{}}
 featureValues = [example[bestFeature] for example in dataSet]
 featureValues = set(featureValues)
 del(labelsCopy[bestFeature])
 for value in featureValues:
  subLabels = labelsCopy[:]
  myTree[bestLabel][value] = createTree(splitDataSet(dataSet, bestFeature, value), subLabels)
 return myTree

5.测试算法——使用决策树分类

同样采用递归的方式得到分类结果。

def classify(inputTree, featLabels, testVec):
 currentFeat = list(inputTree.keys())[0]
 secondTree = inputTree[currentFeat]
 try:
  featureIndex = featLabels.index(currentFeat)
 except ValueError as err:
  print('yes')
 try:
  for value in secondTree.keys():
   if value == testVec[featureIndex]:
    if type(secondTree[value]).__name__ == 'dict':
     classLabel = classify(secondTree[value], featLabels, testVec)
    else:
     classLabel = secondTree[value]
  return classLabel
 except AttributeError:
  print(secondTree)

6.完整代码如下

import numpy as np
import math
import operator
def createDataSet():
 dataSet = [[1,1,'yes'],
    [1,1,'yes'],
    [1,0,'no'],
    [0,1,'no'],
    [0,1,'no'],]
 label = ['no surfacing','flippers']
 return dataSet,label
def calcShannonEnt(dataSet):
 numEntries = len(dataSet)
 labelCounts = {}
 للمقادير في فيكتور الميزات في dataSet:
  currentLabel = featVec[-1]
  if currentLabel not in labelCounts:
   labelCounts[currentLabel] = 0
  labelCounts[currentLabel] += 1
 shannonEnt = 0
 for key in labelCounts:
  shannonEnt = shannonEnt - (labelCounts[key]/numEntries)*math.log2(labelCounts[key]/numEntries)
 عدد البيانات الجديدة
تعريف splitDataSet(dataSet,axis,قيمة):
 عدد البيانات الجديدة = []
 للمقادير في فيكتور الميزات في dataSet:
  إذا كان فيكتور الميزات[مستوى] == قيمة:
   الفيектор الجديد = فيكتور الميزات[:مستوى]
   newVec.extend(featVec[axis+1:])
   retDataset.append(newVec)
 عدد البيانات الجديدة
تعريف chooseBestFeatureToSplit(dataSet):
 عدد الميزات = طول dataSet[0] - 1
 أفضل معلوماتية = 0
 أفضل الميزات = -1
 إنتروبيا الأساس = حساب إنتروبيا شانون dataSet
 للمقادير في نطاق عدد الميزات:
  allValue = [example[i] for example in dataSet]
  allValue = set(allValue)
  إنتروبيا جديدة = 0
  للمقادير في جميع القيم:
   النقاط المفصلة = splitDataSet(dataSet,i,قيمة)
   إنتروبيا جديدة = إنتروبيا جديدة + طول (النقاط المفصلة) / طول dataSet * حساب إنتروبيا شانون (النقاط المفصلة)
  معلوماتية = إنتروبيا الأساس - إنتروبيا جديدة
  إذا كانت معلوماتية > أفضل معلوماتية:
   أفضل معلوماتية = معلوماتية
   أفضل الميزات = i
 عدد الأفضلية
تعريف majorityCnt(fئات):
 عدد الفئات = {}
 للمقادير في فئات:
  إذا لم يكن قيمة في عدد الفئات: عدد الفئات[قيمة] = 0
  عدد الفئات[قيمة] += 1
 classCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
 عدد الفئات[0][0]   
تعريف createTree(dataSet,labels):
 فئات = [مثال[-1] للكل مثال في dataSet]
 labelsCopy = labels[:]
 إذا كان عدد فئات.count(fئات[0]) يساوي طول فئات:
  عدد الفئات[0]
 إذا كان طول dataSet[0] يساوي 1:
  return majorityCnt(classList)
 bestFeature = chooseBestFeatureToSplit(dataSet)
 bestLabel = labelsCopy[bestFeature]
 myTree = {bestLabel:{}}
 featureValues = [example[bestFeature] for example in dataSet]
 featureValues = set(featureValues)
 del(labelsCopy[bestFeature])
 for value in featureValues:
  subLabels = labelsCopy[:]
  myTree[bestLabel][value] = createTree(splitDataSet(dataSet, bestFeature, value), subLabels)
 return myTree
def classify(inputTree, featLabels, testVec):
 currentFeat = list(inputTree.keys())[0]
 secondTree = inputTree[currentFeat]
 try:
  featureIndex = featLabels.index(currentFeat)
 except ValueError as err:
  print('yes')
 try:
  for value in secondTree.keys():
   if value == testVec[featureIndex]:
    if type(secondTree[value]).__name__ == 'dict':
     classLabel = classify(secondTree[value], featLabels, testVec)
    else:
     classLabel = secondTree[value]
  return classLabel
 except AttributeError:
  print(secondTree)
if __name__ == "__main__":
 dataset, label = createDataSet()
 myTree = createTree(dataset,label)
 a = [1,1]
 print(classify(myTree,label,a))

7. تقنيات البرمجة

الفرق بين extend و append

 newVec.extend(featVec[axis+1:])
 retDataset.append(newVec)

extend([]) هو إضافة كل عنصر من القائمة إلى القائمة الجديدة
append() هو إضافة المحتويات الموجودة داخل الأقواس كعنصر جديد إلى القائمة الجديدة

إدخال القائمة

طريقة إنشاء قائمة جديدة

allValue = [example[i] for example in dataSet]

استخراج العناصر الفريدة من القائمة

allValue = set(allValue)

ترتيب القائمة/التركيب، دالة sorted()

classCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)

نسخ القائمة

labelsCopy = labels[:]

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

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

بيان: محتوى هذا المقال تم جمعه من الإنترنت، ويتمتع صاحب الحقوق بالملكية، ويتم جمع المحتوى من قبل المستخدمين عبر الإنترنت الذين يقدمون مساهماتهم بشكل تلقائي، ويتمتع هذا الموقع بلا ملكية، ولا يتم تعديل المحتوى بشكل يدوي، ولا يتحمل الموقع أي مسؤولية قانونية. إذا كنت قد وجدت محتوى يشتبه في انتهاك حقوق النسخ، فالرجاء إرسال بريد إلكتروني إلى: notice#oldtoolbag.com (عند إرسال البريد الإلكتروني، يرجى استبدال # بـ @) لإبلاغنا، وقدم الأدلة ذات الصلة، وسنقوم بإزالة المحتوى المزعوم عن انتهاك حقوق النسخ فور التحقق من ذلك.

أنت قد تحب