何为决策树?

决策树(Decision Tree)是在已知各种情况发生概率的基础上,通过构成决策树来求取净现值的期望值大于等于零的概率,评价项目风险,判断其可行性的决策分析方法,是直观运用概率分析的一种图解法。由于这种决策分支画成图形很像一棵树的枝干,故称决策树。在机器学习中,决策树是一个预测模型,他代表的是对象属性与对象值之间的一种映射关系。Entropy = 系统的凌乱程度,使用算法ID3, C4.5和C5.0生成树算法使用熵。这一度量是基于信息学理论中熵的概念。

决策树是一种树形结构,其中每个内部节点表示一个属性上的测试,每个分支代表一个测试输出,每个叶节点代表一种类别。

分类树(决策树)是一种十分常用的分类方法。它是一种监督学习,所谓监督学习就是给定一堆样本,每个样本都有一组属性和一个类别,这些类别是事先确定的,那么通过学习得到一个分类器,这个分类器能够对新出现的对象给出正确的分类。这样的机器学习就被称之为监督学习。

决策树的流程

第1步;数据准备:通过数据清洗和数据处理,将数据被理为没有缺省值的向量,第2步:寻找最佳特征:遍历每个特征的每一种划分方式,找到最好的划分特征。第3步:生成分支:划分成两个或多个节点。第4步:生成决策树:对分裂后的节点分别继续执行2-3步,直到每个节点只有一种类别。第5步:决策分类:根据训练决策树模型,将预测数据进行分类。

特征的选择--信息增益

在信息增益中,衡量标准是看特征能够为分类系统带来多少信息,带来的信息越多,该特征越重要。对一个特征而言,系统有它和没它时信息量将发生变化,而前后信息量的差值就是这个特征给系统带来的信息量。所谓信息量,就是熵。

假如有特征D,其可能的取值有k种,每一种取到的概率为Pi,那么D的熵就定义为

​​​​​​​        

计算过熵后,怎么计算信息增益呢?信息增益的计算就是将父节点的熵减去其下所有子节点的熵之和,并且在求和时,由于类别比重不同,需要对其实现加权平均。

决策树的实现(通过一些特征辨别性别)

数据处理

数据来源集美大学同学,特别感谢集美大学同学能够免费回答我的问卷。

数据类别:身高,体重,年龄,脚码,性别

数据处理:对数据的类别进行分级,以每列数据的平均值来作为分级的标准

def dealData(filename):fr = open(filename,'r',encoding='utf-8-sig')arrayOLines = fr.readlines() numberOfLines = len(arrayOLines)data = np.zeros((numberOfLines, 5))index = 0for line in arrayOLines:line = line.strip()listFromLine = line.split('\t')data[index,:] = listFromLine[0:5]index += 1#对数据特征进行分类for j in range(4):for i in range(numberOfLines):#身高if(j==0):if(data[i][j])>1.69:data[i][j]=3elif(data[i][j]==1.69):data[i][j]=2else:data[i][j]=1#体重if(j==1):if(data[i][j])>64:data[i][j]=3elif(data[i][j]==64):data[i][j]=2else:data[i][j]=1#年龄if(j==2):if(data[i][j])>26:data[i][j]=3elif(data[i][j]==26):data[i][j]=2else:data[i][j]=1#脚码if(j==3):if(data[i][j])>32:data[i][j]=3elif(data[i][j]==32):data[i][j]=2else:data[i][j]=1return data

构建决策树(参考《机器学习实战》代码)

计算给定数据集的信息熵:


#计算给定数据集的信息熵
def calcEntroy(dataSet):numEntroy=len(dataSet)labelCounts={}for featVec in dataSet:currentLabel=featVec[-1]if currentLabel not in labelCounts.keys():  #labelCounts.keys()表示返回labelCounts字典的键列表labelCounts[currentLabel]=0 #将字典不存在的键添加到字典中并且给键值赋初值labelCounts[currentLabel]+=1 #记录当前类别的出现的次数Entroy=0.0'''计算信息熵'''for key in labelCounts:prob=float(labelCounts[key])/numEntroyEntroy-=prob*log(prob,2)return Entroy

按照给定特征划分数据集:

#按照给定特征划分数据集
def splitDataSet(dataSet,axis,value):retDataSet=[]if isinstance(dataSet,list)==False:dataSet=dataSet.tolist()for featVec in dataSet:if featVec[axis]== value:reducedFeatVec=featVec[:axis]reducedFeatVec.extend(featVec[axis+1:])retDataSet.append(reducedFeatVec)return retDataSet

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

#选择最好的数据集划分方式
def chooseBestFeatureToSplit(dataSet):numFeatures=len(dataSet[0])-1 #数据集最好一项是标签,而前len(dataSet[0])-1表示数据特征数baseEntropy = calcEntroy(dataSet)bestInfoGain=0.0; bestFeature=-1for i in range(numFeatures):featList=[example[i] for example in dataSet]uniqueVals=set(featList) #创建一个无序重复元素集newEntropy=0.0'''计算每种划分方法的信息熵'''for value in uniqueVals:subDataSet=splitDataSet(dataSet,i,value)prob=len(subDataSet)/float(len(dataSet))newEntropy+=prob*calcEntroy(subDataSet)infoGain=baseEntropy-newEntropyif (infoGain>bestInfoGain):bestInfoGain=infoGainbestFeature=i#返回最好特征划分的索引值return bestFeature

计算出现次数最多的分类名称:

#计算出现次数最多的分类名称
def majorityVCnt(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)return sortedClassCount[0][0]

构建决策树函数 :

#构建决策树函数
def createTree(dataSet,labels):classList=[example[-1] for example in dataSet] #用索引的-1位置表示列表最后的位置#如果第一个类别的数目=整个数据集的长度,即整个数据集只有一个类别,可以直接返回该类标签#第一个停止条件if classList.count(classList[0])==len(classList):return classList[0]#如果数据集只有一列,则无法简单的返回唯一的类标签,这里使用前面介绍的majorityCnt函数挑选出现次数最多的类别作为返回值if len(dataSet[0])==1:return majorityVCnt(classList)#获取数据集中最好特征划分的索引bestFeatSplitIndex=chooseBestFeatureToSplit(dataSet)#获取最好特征所属类别标签bestFeatLabel=labels[bestFeatSplitIndex]#初始化myTreemyTree={bestFeatLabel:{}}del(labels[bestFeatSplitIndex])#获取数据集中最优的列featValues=[example[bestFeatSplitIndex] for example in dataSet]uniqueVals=set(featValues)for value in uniqueVals:#求出剩余的类标签subLables=labels[:]#遍历当前选择特征包含的所有属性值,递归调用createTree()函数myTree[bestFeatLabel][value]=createTree(splitDataSet(dataSet,bestFeatSplitIndex,value),subLables)return myTree

使用Matplotlib注解绘制树形图 :

import matplotlib.pyplot as plt#定义文本框和箭头格式
decisionNode=dict(boxstyle="sawtooth",fc='0.8')
leafNode=dict(boxstyle="round4",fc='0.8')
arrow_args=dict(arrowstyle="<-")#绘制带箭头的注释
def plotNode(nodeTxt,centerPt,parentPt,nodeType):createPlot.axl.annotate(nodeTxt,xy=parentPt,xycoords='axes fraction',xytext=centerPt,textcoords='axes fraction',va="center",ha="center",bbox=nodeType,arrowprops=arrow_args)#获取叶节点的数目和树的层数
def getNumLeafs(myTree):numLeafs=0
#  firstStr=myTree.keys()[0]firstStr=list(myTree.keys())[0]secondDict=myTree[firstStr]for key in secondDict.keys():if type(secondDict[key]).__name__=='dict':numLeafs+=getNumLeafs(secondDict[key])else:numLeafs+=1return numLeafsdef getTreeDepth(myTree):maxDepth=0firstStr=list(myTree.keys())[0]secondDict=myTree[firstStr]for key in secondDict.keys():if type(secondDict[key]).__name__=='dict':thisDepth=1+getTreeDepth(secondDict[key])else:thisDepth=1if thisDepth>maxDepth:maxDepth=thisDepthreturn maxDepthdef plotMidText(cntrPt,parentPt,txtString):xMid=(parentPt[0]-cntrPt[0])/2.0+cntrPt[0]yMid=(parentPt[1]-cntrPt[1])/2.0+cntrPt[1]createPlot.axl.text(xMid,yMid,txtString)def plotTree(mytree,parentPt,nodeTxt):numLeafs=getNumLeafs(mytree)depth=getTreeDepth(mytree)firstStr=list(mytree.keys())[0]cntrPt=(plotTree.xOff+(1.0+float(numLeafs))/2.0/plotTree.totalW,plotTree.yOff)plotMidText(cntrPt,parentPt,nodeTxt)plotNode(firstStr,cntrPt,parentPt,decisionNode)secondDict=mytree[firstStr]plotTree.yOff=plotTree.yOff-1.0/plotTree.totalDfor key in secondDict.keys():if type(secondDict[key]).__name__=='dict':plotTree(secondDict[key],cntrPt,str(key))else:plotTree.xOff=plotTree.xOff+1.0/plotTree.totalWplotNode(secondDict[key],(plotTree.xOff,plotTree.yOff),cntrPt,leafNode)plotMidText((plotTree.xOff,plotTree.yOff),cntrPt,str(key))plotTree.yOff=plotTree.yOff+1.0/plotTree.totalDdef createPlot(inTree):fig=plt.figure(1,facecolor='white')fig.clf()axprops=dict(xticks=[],yticks=[])createPlot.axl=plt.subplot(111,frameon=False,**axprops)plotTree.totalW=float(getNumLeafs(inTree))plotTree.totalD=float(getTreeDepth(inTree))plotTree.xOff=-0.5/plotTree.totalW;plotTree.yOff=1.0;plotTree(inTree,(0.5,1.0),'')plt.show()

代码测试:

if __name__=='__main__':labels=['high','weight','age','subdcript','sex']data=dealData('D:/learn/three first/machine learning/Data1.txt')myTree=createTree(data,labels)print(myTree)createPlot(myTree)

实现结果:

结果分析:

从决策树可以看出身高的信息增益对性别判别最大,当身高等级为1时,年龄的信息增益最大;为3时,体重增益最大。当年龄等级为1时体重增益最大,最后分配脚码。

不足:数据过于少,对数据类型的分级不够好,应采用更准确的方法来分类,而不是通过平均数来分级。

决策树的优缺点:

优点:决策树算法的时间复杂度较小,可以处理不相关特征数据。

缺点:容易出现过拟合对连续性的字段比较难预测

机器学习-决策树(python)相关推荐

  1. 机器学习--决策树python实现案例

    注:文中相关截图或内容取自<统计学习方法>李航编 简介: 决策树(decision tree)是基本的分类与回归方法.对分类和回归的理解,通俗的讲就是最终结果是离散的为分类任务,结果是连续 ...

  2. 机器学习实验二---决策树python

    机器学习实验二---决策树python 一.了解一下决策树吧 决策树基本流程 信息增益 决策树的优缺点 二.数据处理 三.决策树的构建 计算给定数据集的香农熵 按照给定特征划分数据集 选择最好的数据划 ...

  3. 机器学习——决策树模型:Python实现

    机器学习--决策树模型:Python实现 1 决策树模型的代码实现 1.1 分类决策树模型(DecisionTreeClassifier) 1.2 回归决策树模型(DecisionTreeRegres ...

  4. 模式识别与机器学习(Python实现):决策树分男女

    模式识别与机器学习(Python实现):决策树分男女 欢迎大家来到安静到无声的<模式识别与人工智能(程序与算法)>,如果对所写内容感兴趣请看模式识别与人工智能(程序与算法)系列讲解 - 总 ...

  5. 机器学习-决策树之回归树python实战(预测泰坦尼克号幸存情况)(三)

    本文用通俗易懂的方式来讲解分类树中的回归树,并以"一维回归的图像绘制"和"泰坦尼克号幸存者预测"两个例子来说明该算法原理. 以下是本文大纲: 1 Decisio ...

  6. 机器学习决策树DecisionTree以及python代码实现

    机器学习决策树DecisionTree以及python代码实现 1.基本算法原理 2.选择最优特征进行划分 2.1信息增益 2.2信息增益率 2.3基尼系数 4.连续值以及缺失值的处理 4.1连续值的 ...

  7. 机器学习——决策树学习

    机器学习--决策树学习 一.什么是决策树 二.决策树的学习过程 特征选择: 决策树生成: 剪枝: 三.决策树的一个具体的实例 导入数据 python strip() 函数和 split() 函数的详解 ...

  8. 机器学习 --- 决策树(educode实训作业)

    引言:本文主要对educoder机器学习 --- 决策树的实训作业进行讲解,创造不易!请您点点关注,点点收藏叭!!! 目录 第1关:什么是决策树 任务描述 相关知识 引例 决策树的相关概念 编程要求 ...

  9. 机器学习 决策树篇——解决离散变量的分类问题

    机器学习 决策树篇--解决离散变量的分类问题 摘要 熵增益和熵增益率计算 熵增益和熵增益率运行结果 离散变量的决策树模型 决策树模型运行结果 摘要 本文通过python实现了熵增益和熵增益率的计算.实 ...

  10. 机器学习——决策树剪枝

    目录 一.决策树剪枝策略 1.1剪枝目的 1.2剪枝策略 1.3判断决策树泛化性能是否提升的方法 二.预剪枝 (prepruning) 2.1概述 2.2预剪枝优缺点 2.3代码实现 三.后剪枝(po ...

最新文章

  1. matlab实例 pdf,matlab65实例教程(含语句注释).pdf
  2. C#多线程编程实战1.1创建线程
  3. 去除 计算机里面的百度云管家,WIN7如何彻底清除“百度云管家”图标或残留文件?...
  4. boost::mpl::negate相关的测试程序
  5. idea链接oracle数据库报错:[66000][12505] Listener refused the connection with the following error:
  6. 关于C++,Java和Python中的随机数生成法
  7. 桌面消息提醒_手机消息总是延迟,真的是网速不行?3招教你找出捣鬼设置
  8. 授人以鱼不如授人以渔,UCHome全面大解析培训【第二集】
  9. python实践作业_实践-python实现假设检验
  10. 软件工作相关考试001---PMP等各种考试
  11. WordPress /wp-admin/users.php畸形s参数路径泄漏漏洞
  12. Day1 安装虚拟机和centos7系统
  13. 【SQL 学习】表连接--natural join 的一个bug
  14. 华翼宽带android客户端,太凶残了:电信推华翼宽带专门防蹭网
  15. 安卓设置屏幕方向后,恢复自动旋转
  16. 【高项】第4章 项目整体管理与变更管理【知识点精华笔记】
  17. 2012-7-10可樂词汇积累#9315;
  18. java中的解耦_java-了解如何解耦
  19. ERASOR:解决动态环境下的SLAM建图问题,有效过滤动态物体(ICRA2021)
  20. Successfully deployed.Backed up previous deployment.

热门文章

  1. 10月11月黑科技资源大全总结
  2. 走近“科技冬奥”|智慧支付、安心入住
  3. Redis分布式锁 | 黑马点评
  4. 政治生态档案监督管理系统建立完善廉政风险预警监控机制
  5. 亏损扩大近十倍、裁撤总裁职位,宣布996的有赞如何enjoy?
  6. Word控件Spire.Doc 【页面背景】教程(7) ;在 C# 中为 word 文档设置图像背景
  7. 如何一个模型走天下?集成训练多数据集,打造通用目标检测模型方法详解
  8. ubuntu里一些不熟的命令
  9. 7天搞定FPGA精录总结Episode.6 串口通信,系统设计【基于Robei、Altera QuartusⅡ与Python】
  10. 机器学习--监督学习以及无监督学习案例