一、什么是决策树的剪枝

对比日常生活中,环卫工人在大街上给生长茂密的树进行枝叶的修剪。在机器学习的决策树算法中,有对应的剪枝算法。将比较复杂的决策树,化简为较为简单的版本,并且不损失算法的性能。

二、为什么要剪枝

剪枝是决策树算法应对过拟合的一种策略,因为在学习过程中,决策树根据训练样本进行拟合,生成了针对于训练数据集精确性极高的模型。但是训练数据集,不可避免是一种有偏的数据。所以我们为了提高决策树的泛化性能,采取了剪枝的策略。使得决策树不那么对于训练数据精确分类,从而适应任何数据。

三、剪枝的基本策略

剪枝的策略可以分为预剪枝和后剪枝两种。

预剪枝:对每个结点划分前先进行估计,若当前结点的划分不能带来决策树的泛化性能的提升,则停止划分,并标记为叶结点。

后剪枝:现从训练集生成一棵完整的决策树,然后自底向上对非叶子结点进行考察,若该结点对应的子树用叶结点能带来决策树泛化性能的提升,则将该子树替换为叶结点

四、预剪枝和后剪枝的优缺点

        1、预剪枝

            优点:思想简单,算法高效,可以降低过拟合风险,减少训练时间。

缺点:可能存在欠拟合的风险。

2、后剪枝

优点:欠拟合风险小,泛化能力优于预剪枝。

缺点:相较于预剪枝,训练开销大。

五、奥卡姆剃刀定律

奥卡姆剃刀是一种思想,在效果相同,性能一致的情况下,模型越简单越好。在简直过程中,若复杂的决策树和简答的决策树的性能相同则优先选择结构简单的决策树。

六、预剪枝和后剪枝的具体实现

1.数据准备

数据依然采用的是集美大学计算机工程学院acm比赛校选的数据,其中每列的属性分别是成绩、用时、年级、奖项。并对其离散化。

 其中将成绩、用时、年级分为4个等级,数字越大,分别代表成绩越高,用时越长,年级越高。奖项分为3个等级,1等奖,2等奖,3等奖。

2.划分数据集

与以往不同的是,这次我们将数据集分为两部分,一部分是大于最优特征的特征值的,一部分是小于目标特征的特征值的。

#按照给定区间划分数据集
def splitDataSet_bydata_font(dataSet,axis,value):# 待划分的数据集 划分数据集的特征 比较的特征值retDataSet_font=[]if isinstance(dataSet,list) ==False:  #判断dataSet是不是列表dataSet=dataSet.tolist() #转化列表for featVec in dataSet:#遍历每一行if featVec[axis] <=value: reducedFeatVec=featVec[:axis]reducedFeatVec.extend(featVec[axis:])#放列表中的元素retDataSet_font.append(reducedFeatVec)#把整个列表放入return retDataSet_font#按照给定特征区间划分数据集
def splitDataSet_bydata_back(dataSet,axis,value):# 待划分的数据集 划分数据集的特征 比较的特征值retDataSet_back=[]if isinstance(dataSet,list) ==False:dataSet=dataSet.tolist()for featVec in dataSet:#遍历每一行if featVec[axis] >value: reducedFeatVec=featVec[:axis]reducedFeatVec.extend(featVec[axis:])#放列表中的元素retDataSet_back.append(reducedFeatVec)#把整个列表放入return retDataSet_back

3.判断最优值

通过计算各特征的信息增益,将信息增益最大的特征及最优的特征值当作划分的标准。

#判断最优值
def chooseBestData(dataset):num=len(dataset[0])-1 #除掉类别baseEnt=calcShannonEnt(dataset)#信息熵print("原本的信息熵",baseEnt)bestGain=0.0 bestFeature=-1bestdata=0for i in range(num):#0 1 2#创建唯一的分类标签列表featlist=[example[i] for example in dataset]#取该行数据的第“ i ”位元素for value in featlist:newEnt=0.0#计算每种划分方式的信息熵subDataSet_font=splitDataSet_bydata_font(dataset,i,value)subDataSet_back=splitDataSet_bydata_back(dataset,i,value)prob_font=len(subDataSet_font)/float(len(dataset))#计算比例prob_back=len(subDataSet_back)/float(len(dataset))newEnt=prob_font*calcShannonEnt(subDataSet_font)+prob_back*calcShannonEnt(subDataSet_back)#计算信息增益inforGain=baseEnt-newEnt#计算最好的信息熵if (inforGain>bestGain):print("当前信息熵增益为:",inforGain,"当前最优特征为",i,"划分值为:",value)bestGain=inforGainbestFeature=ibestdata=valuereturn bestFeature,bestdata

上面的输出结果是第一次划分的所显示的结果。我们发现最佳的特征是成绩,最好的划分值是1。

4. 投票决策

在构建决策树,可能会出现这一种情况,如果数据集已经处理了所有的属性,但是类标签依然不是唯一的。在这种情况下,我们通常会采用多数表决的方法决定叶子节点的分类。

#投票分类
def majorityCnt(classList):classCount={}for vote in classList:if vote not in classCount.keys():classCount[vote]=0classCount[vote]+=1sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)print(sortedClassCount)return sortedClassCount[0][0] #返回出现次数最多的分类

5.创建树

创建出还未进行剪枝的树进行观察

def createTree(dataSet,labels):#类别完全相同则停止划分classList=[example[-1] for example in dataSet]if classList.count(classList[0])==len(classList):#print("发生了类别完全相同",classList[0])return classList[0]#遍历完所有特征时返回出现次数最多的类别if len(dataSet[0])==1:return majorityCnt(classList)bestFeat,bestData=chooseBestData(dataSet)bestFeatLabel=labels[bestFeat]myTree={bestFeatLabel:{}}#分支的多少和循环次数有关listJudge=["<="+str(bestData),">="+str(bestData)]subLabels=labels[:] #复制一份print(bestFeat,bestData)newDataSet_font=splitDataSet_bydata_font(dataSet,bestFeat,bestData)newDataSet_back=splitDataSet_bydata_back(dataSet,bestFeat,bestData)print(newDataSet_font)if(newDataSet_font!=[] and bestFeat!=-1):myTree[bestFeatLabel][listJudge[0]]=createTree(newDataSet_font,subLabels)if(newDataSet_back!=[] and bestFeat!=-1):myTree[bestFeatLabel][listJudge[1]]=createTree(newDataSet_back,subLabels)return myTree

将树的结构可视化的代码与上次的博客相同,这里就不列出了。树可视化为

6.进行预减枝

预减枝有多种方法,我在本文中采用的是限定树的深度进行预剪枝。

def createTree(dataSet,labels,depth):classList=[example[-1] for example in dataSet]#达到指定深度停止划分if depth==0:return majorityCnt(classList)#类别完全相同则停止划分if classList.count(classList[0])==len(classList):return classList[0]#遍历完所有特征时返回出现次数最多的类别if len(dataSet[0])==1:return majorityCnt(classList)bestFeat,bestData=chooseBestData(dataSet)bestFeatLabel=labels[bestFeat]myTree={bestFeatLabel:{}}#分支的多少和循环次数有关listJudge=["<="+str(bestData),">"+str(bestData)]subLabels=labels[:] #复制一份print(bestFeat,bestData)newDataSet_font=splitDataSet_bydata_font(dataSet,bestFeat,bestData)newDataSet_back=splitDataSet_bydata_back(dataSet,bestFeat,bestData)print(newDataSet_font)if(newDataSet_font!=[] and bestFeat!=-1):newDepth=depth-1myTree[bestFeatLabel][listJudge[0]]=createTree(newDataSet_font,subLabels,newDepth)if(newDataSet_back!=[] and bestFeat!=-1):newDepth=depth-1myTree[bestFeatLabel][listJudge[1]]=createTree(newDataSet_back,subLabels,newDepth)return myTreeif __name__ == '__main__':mytree=createTree(data,labels,3)createPlot(mytree)

效果如下

我们发现,将深度设置为3时,年级的分类就被剪枝去掉了。存在欠拟合的风险。

7.错误记录

(1)报错:

AttributeError: 'dict' object has no attribute 'iteritems'

原因:

python3中已经没有 “iteritems” 这个属性了,现在属性是:“ items ” 。

解决办法:

将代码中的iteritems 修改为:items

机器学习--决策树二(预剪枝和后剪枝)相关推荐

  1. 机器学习:决策树的预剪枝和后剪枝

    述概: 剪枝:在机器学习的决策树算法中,为防止过拟合现象和过度开销,而采用剪枝的方法,主要有预剪枝和后剪枝两种常见方法. 预剪枝:在决策树生成的过程中,预先估计对结点进行划分能否提升决策树泛化性能.如 ...

  2. 机器学习-预剪枝和后剪枝

    一棵完全生长的决策树会面临一个很严重的问题,即过拟合.当模型过拟合进行预测时,在测试集上的效果将会很差.因此我们需要对决策树进行剪枝, 剪掉一些枝叶,提升模型的泛化能力. 决策树的剪枝通常有两种方法, ...

  3. 决策树_(预剪枝和后剪枝)_以判断西瓜好坏为例

    剪枝的目的: 剪枝的目的是为了避免决策树模型的过拟合.因为决策树算法在学习的过程中为了尽可能的正确的分类训练样本,不停地对结点进行划分,因此这会导致整棵树的分支过多,也就导致了过拟合.决策树的剪枝策略 ...

  4. 【机器学习入门】(4) 决策树算法理论:算法原理、信息熵、信息增益、预剪枝、后剪枝、算法选择

    各位同学好,今天我向大家介绍一下python机器学习中的决策树算法的基本原理.内容主要有: (1) 概念理解:(2) 信息熵:(3) 信息增益:(4) 算法选择:(5) 预剪枝和后剪枝. python ...

  5. 决策树的预剪枝与后剪枝

    前言: 本次讲解参考的仍是周志华的<机器学习>,采用的是书中的样例,按照我个人的理解对其进行了详细解释,希望大家能看得懂. 1.数据集 其中{1,2,3,6,7,10,14,15,16,1 ...

  6. 【机器学习】树模型预剪枝和后剪枝

    在树模型建模的过程中的树模型的超参数会影响模型的精度,那么如何调整超参数呢?可以提前限制模型的超参数,也可以在训练模型之后再调整.本文将介绍树模型的预剪枝和后剪枝的实践过程. 原始模型 使用基础数据集 ...

  7. 决策树剪枝的基本策略有预剪枝和后剪枝,请简述并分析两种剪枝策略

    1.决策树是一类常见的机器学习方法,是基于树结构进行决策的.一般的,一棵决策树包含两类结点:内部节点和叶结点,其中内部节点表示表示一个特征或属性,叶结点表示__决策结果____. 2.在决策树学习中, ...

  8. 决策树剪枝:预剪枝、后剪枝

    一棵完全生长的决策树会面临一个很严重的问题,即过拟合.当模型过拟合进行预测时,在测试集上的效果将会很差.因此我们需要对决策树进行剪枝, 剪掉一些枝叶,提升模型的泛化能力. 决策树的剪枝通常有两种方法, ...

  9. 【ML】决策树--剪枝处理(预剪枝、后剪枝)

    1. 剪枝(pruning)处理 首先,我们先说一下剪枝的目的--防止"过拟合". 在决策树的学习过程中,为了保证正确性,会不断的进行划分,这样可能会导致对于训练样本能够达到一个很 ...

最新文章

  1. 【译】Asp.Net Identity Cookies 格式化
  2. 自由自在带你品尝一种能长出果蔬的冰淇淋
  3. JZOJ__Day 1:【NOIP普及模拟】JABUKE
  4. 导致Android手机崩溃的壁纸,使用错误的壁纸会使你的Android手机崩溃
  5. 网易云课堂测试微专业前置课
  6. 学习python: 函数参数
  7. 从零开始学习前端JAVASCRIPT — 14、闭包与继承
  8. mysql-8.0.16-winx64的最新安装教程
  9. 深入linux设备驱动程序内核机制(第三章) 读书笔记
  10. iPhone手机蓝牙找不到AirPods耳机的解决方法
  11. addobe dwcs6静态表格
  12. 关于幂级数求和是否弃用首项的理解
  13. 天才程序员: 那些年我偷懒没敲的EOS代码, 让我失去了一切, 如果...
  14. 魏小亮:参加编程竞赛对实际工作的用处
  15. C语言:从键盘上输入10个整数,求他们的平均值以及正数的个数,并加以输出
  16. 在本地计算机无法启动t6,T6服务无法启动,有以下提示,请问如何解决,谢谢!...
  17. 一张六西格玛证书,换取五十万年薪 -- 优思学院
  18. css利用什么xhtml标记构建网页布局,css是利用什么XHTML标记构建网页布局
  19. Linux 下终于成功安装 pytorch !( Virtualenv 和 Anaconda 安装)
  20. 赤兔四足机器人的作用_四足机器人来了 浙大造能跑能跳的“赤兔“获国际大奖...

热门文章

  1. (面试总结)SSM 整合案例:订单操作
  2. 【matlab教程】12、已知函数表达式画函数图
  3. 手推公式之“层归一化”梯度
  4. 解析京东搜索商品带b‘‘字符类型解析
  5. openstack国内源
  6. PAT甲级1052:Linked List Sorting (25)
  7. 比特币发NFT,却引发社区争议?
  8. 单片机魔法编程百度云_嵌入式单片机编程魔法之三权分立~
  9. python爬虫实现股票数据存储_Python 爬虫 | 股票数据的获取
  10. python(dict字典相关知识以及小例子:生成一个列表,存放100个随机整数,找出出现次数最多的数字)