当前位置:   article > 正文

机器学习-决策树_决策树算法伪代码

决策树算法伪代码

目录

一、概念

二。步骤

三、决策树

四、决策树的优缺点

优点:

缺点:

五、决策树的构造

1.创建分支的伪代码 createBranch() 如下:

2.什么时候递归停止

六、如何划分数据集

1.ID3

2.C4.5

3.基尼指数

七、ID3、CART和C4.5的区别

八、代码实战


本篇参考原文链接:https://blog.csdn.net/jiaoyangwm/article/details/79525237

一、概念

决策树是一种用于分类和回归分析的机器学习算法。它通过构建一个树状结构来表示决策规则。在决策树中,每个内部节点表示一个属性或特征,每个分支表示一个可能的属性值或特征取值,而每个叶节点表示一个类别或一个预测值。决策树的构建过程涉及从根节点开始递归地划分数据集,直到满足某个停止准则。一旦构建完成,决策树可以用于分类新的未知样本或预测连续值。决策树简单易于理解和解释,同时也具有一定的容错性和鲁棒性。

二。步骤

决策树的步骤一般可以划分为特征选择、决策树的生成、决策树的修剪。

决策树分类:从根节点开始,对实例的某一特征进行测试,根据测试结果将实例分配到其子节点,此时每个子节点对应着该特征的一个取值,如此递归的对实例进行测试并分配,直到到达叶节点,最后将实例分到叶节点的类中。

下图为决策树示意图,圆点——内部节点,方框——叶节点

在这里插入图片描述

当使用决策树进行分类时,通常遵循以下步骤:

  1. 数据准备:收集并准备用于训练的数据。确保数据集包含有标记的样本,其中每个样本都有一组特征和对应的类别标签。

  2. 特征选择:根据问题的特点和数据集的性质,选择最佳的特征来构建决策树。常用的特征选择方法有信息增益、基尼指数等。

  3. 树的构建:从根节点开始,根据选定的特征进行数据集的划分。选择一个划分准则,例如信息增益最大或基尼指数最小的准则,将数据集划分为不同的子集。

  4. 递归划分:对每个子集重复步骤3,直到达到预定义的停止条件。停止条件可以是树的深度达到一定阈值、节点包含的样本数小于某个值,或者节点的不纯度低于某个阈值等。

  5. 叶节点的确定:在构建树的过程中,根据划分结果确定叶节点的类别。通常是选择子集中占比最大的类别作为叶节点的类别。

  6. 剪枝处理:为了防止过拟合,可以对构建好的决策树进行剪枝处理。通过降低树的复杂度,提高模型的泛化能力。

  7. 预测:使用构建好的决策树对新的未知样本进行分类。根据样本的特征值从根节点开始,按照树的分支规则逐步下行,直到到达叶节点,根据叶节点的类别进行分类。

三、决策树

1.决策树的目的:通过训练集构造模型,通过模型对未知的类别进行分类

2.决策树的本质:从训练集中归纳出一组分类规则,或者说是由训练数据集估计条件概率模型。

3.决策树的目标:寻找最优的决策树,即尽可能得减少分支和层数,产生一棵泛化能力强的树

四、决策树的优缺点

优点:

1. 易于理解和解释:决策树以树状结构呈现,可以直观地表示决策规则,易于理解和解释。决策树可以生成可视化的图形,直观展示特征的重要性和决策路径。

2. 适用于离散和连续特征:决策树可以处理离散型和连续型特征,不需要对数据进行特殊的处理或转换。

3. 可处理多类别问题:决策树可以直接处理多类别分类问题,不需要额外的转换或扩展。

4. 可处理缺失值:决策树可以处理缺失值的情况,在决策过程中可以选择其他特征来进行划分。

5. 速度较快:相比于其他复杂的机器学习算法,决策树的构建和预测速度较快,尤其适用于大规模数据集。

缺点:

1. 容易过拟合:决策树容易过度拟合训练数据,特别是当树的深度较大时。过拟合会导致模型在训练集上表现很好,但在新样本上的泛化能力较差。

2. 局部最优问题:决策树是一种贪心算法,每次划分时只考虑当前最优,而无法保证全局最优。

3. 难以处理复杂关系:决策树很难处理具有复杂关系的数据,例如逻辑门电路等。

为了克服决策树的缺点,可以使用剪枝、随机森林等技术来提高决策树的性能和泛化能力。

五、决策树的构造


决策树学习的算法通常是一个递归地选择最优特征,并根据该特征对训练数据进行分割,使得各个子数据集有一个最好的分类的过程。这一过程对应着对特征空间的划分,也对应着决策树的构建。

1) 开始:构建根节点,将所有训练数据都放在根节点,选择一个最优特征,按着这一特征将训练数据集分割成子集,使得各个子集有一个在当前条件下最好的分类。

2) 如果这些子集已经能够被基本正确分类,那么构建叶节点,并将这些子集分到所对应的叶节点去。

3)如果还有子集不能够被正确的分类,那么就对这些子集选择新的最优特征,继续对其进行分割,构建相应的节点,如果递归进行,直至所有训练数据子集被基本正确的分类,或者没有合适的特征为止。

4)每个子集都被分到叶节点上,即都有了明确的类,这样就生成了一颗决策树

1.创建分支的伪代码 createBranch() 如下:
  1. If so return 类标签:
  2. Else
  3. 寻找划分数据集的最好特征
  4. 划分数据集
  5. 创建分支节点
  6. for 每个划分的子集
  7. 调用函数createBranch()并增加返回结果到分支节点中
  8. return 分支节点
2.什么时候递归停止

(1)当子集中只有一个类别时,例如:3:0

(2)纯度极高,但已无属性或特征使得子集可以往下分,例如9:1

(3)无类别,继承父结点的类别,例如:0:0

六、如何划分数据集

划分数据集的大原则是:将无序数据变得更加有序

通常使用一下三种划分方法

ID3 (信息增益)

C4.5(增益率)

CART基尼指数

在ID3的基础上,后续的算法如C4.5和CART对ID3算法进行了改进

1.ID3

划分数据集前后信息发生的变化称为信息增益,获得信息增益最高的特征就是最好的选择,所以必须先学习如何计算信息增益,集合信息的度量方式称为香农熵,或者简称熵。

香农熵(Shannon Entropy),也称为信息熵,是信息论中用来度量信息量或信息不确定性的概念。它由克劳德·香农于1948年引入,是信息论的重要概念之一。

熵用于衡量一个随机变量的不确定性或信息量。对于一个离散型随机变量X,其概率分布为P(X),熵的计算公式如下:

H=-\sum_{i=1}^{n}p(x_{i})\log_{2}p(x_{i})

其中,x表示随机变量X的每个可能取值,P(x)表示x取值发生的概率。

熵的值越大,表示随机变量具有的不确定性或信息量越大;而熵的值越小,表示随机变量具有的不确定性或信息量越少。

当熵中的概率由数据估计(特别是最大似然估计)得到时,所对应的熵称为经验熵。

什么叫由数据估计?比如有10个数据,一共有两个类别,A类和B类。其中有7个数据属于A类,则该A类的概率即为十分之七。

其中有3个数据属于B类,则该B类的概率即为十分之三。浅显的解释就是,这概率是我们根据数据数出来的。

在理解信息增益之前,要明确——条件熵

信息增益表示得知特征 X 的信息而使得类Y的信息不确定性减少的程度。

条件熵H(Y|X)表示在已知随机变量X的条件下随机变量Y的不确定性,随机变量X给定的条件下随机变量Y的条件熵 (conditional entropy) H(Y|X),定义X给定条件下Y的条件概率分布的熵对X的数学期望:

H(Y|X)=\sum_{i=1}^n p_iH(Y|X=x_i)

其中, p_i=P(X=x_i)

当熵和条件熵中的概率由数据估计得到时,所对应的分别为经验熵和经验条件熵,此时如果有0概率,令0log0=0

信息增益:信息增益是相对于特征而言的。所以,特征A对训练数据集D的信息增益g(D,A),定义为集合D的经验熵H(D)与特征A给定条件下D的经验条件熵H(D|A)之差,即:

g(D,A)=H(D)-H(D|A)

g(D,A)即为信息增益,衡量了在已知某个特征的情况下,划分数据集所能带来的信息增加量。信息增益的作用在于帮助决策树算法确定最佳的特征来进行数据集的划分。

2.C4.5

C4.5  (又名增益率,或信息增益比)是指:

特征A 对训练数据集D的信息增益比g R ( D , A ) 定义为其信息增益g(D,A)与训练数据集D的经验熵之比:

g_R(D,A)=\frac{g(D,A)}{H(D)}

3.基尼指数

基尼指数用于衡量从一个数据集中随机抽取两个样本,它们属于不同类别的概率。基尼指数越小表示数据集的纯度越高。

对于一个数据集D,假设有K个类别。则基尼指数的计算公式如下:

CART决策树使用基尼指数(Gini index)来选择划分属性:
Gini(D)=1-\sum_{k=1}^{|y|}{p_k}^2
属性a的基尼指数定义为:

 Gini\_index(D,a)=\sum_{v=1}^V\frac{|D^v|}{|D|}Gini(D^v)

七、ID3、CART和C4.5的区别

ID3、CART和C4.5都是决策树算法的变种,它们在决策树的构建和特征选择上存在一些区别。

1. 特征选择准则:
- ID3(基于信息增益):ID3算法使用信息增益作为特征选择的准则,选择能够最大程度减少信息熵的特征。
- CART(分类和回归树):CART算法使用基尼指数(对于分类问题)或方差(对于回归问题)作为特征选择的准则,选择能够最小化子集纯度的特征。
- C4.5(基于信息增益比):C4.5算法使用信息增益比作为特征选择的准则,修正了ID3算法对特征取值较多的偏好。

2. 处理连续特征:
- ID3:ID3算法不直接支持处理连续特征,需要将连续特征离散化为离散值。
- CART:CART算法可以直接处理连续特征,通过选择一个阈值将连续特征二分为两个子集。
- C4.5:C4.5算法可以直接处理连续特征,通过选择一个阈值将连续特征离散化为二值特征。

3. 处理缺失值:
- ID3:ID3算法对于缺失值敏感,会直接忽略带有缺失值的样本。
- CART:CART算法可以处理缺失值,通过在划分时考虑缺失值的情况。
- C4.5:C4.5算法可以处理缺失值,通过在计算特征选择准则时考虑缺失值的情况。

4. 决策树类型:
- ID3和C4.5:ID3和C4.5算法构建的决策树是多叉树,每个内部节点有多个分支。
- CART:CART算法构建的决策树是二叉树,每个内部节点只有两个分支。

八、代码实战

代码借鉴于原文链接:https://blog.csdn.net/jiaoyangwm/article/details/79525237

  1. from math import log
  2. def creatDataSet():
  3. # 数据集
  4. dataSet=[[0, 0, 0, 0, 'no'],
  5. [0, 0, 0, 1, 'no'],
  6. [0, 1, 0, 1, 'yes'],
  7. [0, 1, 1, 0, 'yes'],
  8. [0, 0, 0, 0, 'no'],
  9. [0, 0, 0, 0, 'no'],
  10. [1, 0, 0, 1, 'no'],
  11. [1, 1, 1, 1, 'yes'],
  12. [1, 0, 1, 2, 'yes'],
  13. [2, 1, 1, 2, 'yes'],
  14. [2, 0, 1, 2, 'yes'],
  15. [2, 0, 1, 1, 'yes'],
  16. [2, 1, 0, 1, 'yes'],
  17. [2, 1, 0, 2, 'yes'],
  18. [2, 0, 0, 0, 'no']]
  19. #分类属性
  20. labels=['年龄','有工作','有自己的房子','信贷情况']
  21. #返回数据集和分类属性
  22. return dataSet,labels
  23. def calcShannonEnt(dataSet):
  24. #返回数据集行数
  25. numEntries=len(dataSet)
  26. #保存每个标签(label)出现次数的字典
  27. labelCounts={}
  28. #对每组特征向量进行统计
  29. for featVec in dataSet:
  30. currentLabel=featVec[-1] #提取标签信息
  31. if currentLabel not in labelCounts.keys(): #如果标签没有放入统计次数的字典,添加进去
  32. labelCounts[currentLabel]=0
  33. labelCounts[currentLabel]+=1 #label计数
  34. shannonEnt=0.0 #经验熵
  35. #计算经验熵
  36. for key in labelCounts:
  37. prob=float(labelCounts[key])/numEntries #选择该标签的概率
  38. shannonEnt-=prob*log(prob,2) #利用公式计算
  39. return shannonEnt #返回经验熵
  40. def chooseBestFeatureToSplit(dataSet):
  41. #特征数量
  42. numFeatures = len(dataSet[0]) - 1
  43. #计数数据集的香农熵
  44. baseEntropy = calcShannonEnt(dataSet)
  45. #信息增益
  46. bestInfoGain = 0.0
  47. #最优特征的索引值
  48. bestFeature = -1
  49. #遍历所有特征
  50. for i in range(numFeatures):
  51. # 获取dataSet的第i个所有特征
  52. featList = [example[i] for example in dataSet]
  53. #创建set集合{},元素不可重复
  54. uniqueVals = set(featList)
  55. #经验条件熵
  56. newEntropy = 0.0
  57. #计算信息增益
  58. for value in uniqueVals:
  59. #subDataSet划分后的子集
  60. subDataSet = splitDataSet(dataSet, i, value)
  61. #计算子集的概率
  62. prob = len(subDataSet) / float(len(dataSet))
  63. #根据公式计算经验条件熵
  64. newEntropy += prob * calcShannonEnt((subDataSet))
  65. #信息增益
  66. infoGain = baseEntropy - newEntropy
  67. #打印每个特征的信息增益
  68. print("第%d个特征的增益为%.3f" % (i, infoGain))
  69. #计算信息增益
  70. if (infoGain > bestInfoGain):
  71. #更新信息增益,找到最大的信息增益
  72. bestInfoGain = infoGain
  73. #记录信息增益最大的特征的索引值
  74. bestFeature = i
  75. #返回信息增益最大特征的索引值
  76. return bestFeature
  77. def splitDataSet(dataSet,axis,value):
  78. retDataSet=[]
  79. for featVec in dataSet:
  80. if featVec[axis]==value:
  81. reducedFeatVec=featVec[:axis]
  82. reducedFeatVec.extend(featVec[axis+1:])
  83. retDataSet.append(reducedFeatVec)
  84. return retDataSet
  85. #main函数
  86. if __name__=='__main__':
  87. dataSet,features=creatDataSet()
  88. # print(dataSet)
  89. # print(calcShannonEnt(dataSet))
  90. print("最优索引值:"+str(chooseBestFeatureToSplit(dataSet)))

结果为:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/901489
推荐阅读
相关标签
  

闽ICP备14008679号