决策树 概念


决策树(Decision Tree)是一种基本的分类与回归方法,本文主要讨论分类决策树。决策树模型呈树形结构,在分类问题中,表示基于特征对实例进行分类的过程。它可以认为是if-then规则的集合,也可以认为是定义在特征空间与类空间上的条件概率分布。相比朴素贝叶斯分类,决策树的优势在于构造过程不需要任何领域知识或参数设置,因此在实际应用中,对于探测式的知识发现,决策树更加适用。

决策树学习通常包括 3 个步骤:特征选择、决策树的生成和决策树的修剪。

决策树 算法思想


模型定义

分类决策树模型是一种描述对实例进行分类的树形结构。决策树由结点(node)和有向边(directed edge)组成。结点有两种类型:内部结点(internal node)和叶结点(leaf node)。内部结点表示一个特征或属性(features),叶结点表示一个类(labels)。

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

例子:邮件分类系统

首先检测发送邮件域名地址。如果地址为 myEmployer.com, 则将其放在分类 "无聊时需要阅读的邮件"中。 如果邮件不是来自这个域名,则检测邮件内容里是否包含单词 "曲棍球" , 如果包含则将邮件归类到 "需要及时处理的朋友邮件", 如果不包含则将邮件归类到 "无需阅读的垃圾邮件" 。

决策树与if-then规则

现在我们可以更抽象一些。决策树可以看成一个if-then规则的集合:由决策树的根结点到叶结点的每一条路径构建一条规则;路径上的内部结点的特征对应着规则的条件,而叶结点对应着分类的结论。决策树的路径和其对应的if-then规则集合是等效的,它们具有一个重要的性质:互斥并且完备。这里的意思是说:每一个实例都被一条路径或一条规则所覆盖,而且只被一条规则所覆盖。

决策树的学习

决策树学习算法包含特征选择、决策树的生成与剪枝过程。决策树的学习算法通常是递归地选择最优特征,并用最优特征对数据集进行分割。开始时,构建根结点,选择最优特征,该特征有几种值就分割为几个子集,每个子集分别递归调用此方法,返回结点,返回的结点就是上一层的子结点。直到所有特征都已经用完,或者数据集只有一维特征为止。

使用伪代码:

def createBranch():
'''
此处运用了迭代的思想。 感兴趣可以搜索 迭代 recursion, 甚至是 dynamic programing。
'''检测数据集中的所有数据的分类标签是否相同:If so return 类标签Else:寻找划分数据集的最好特征(划分之后信息熵最小,也就是信息增益最大的特征)划分数据集创建分支节点for 每个划分的子集调用函数 createBranch (创建分支的函数)并增加返回结果到分支节点中return 分支节点

算法特点

优点:计算复杂度不高,输出结果易于理解,数据有缺失也能跑,可以处理不相关特征。

缺点:容易过拟合。

适用数据类型:数值型和标称型。

特征选择


决策树学习的关键就是如何选择最优划分属性。

1.信息增益

著名的ID3决策树学习算法就是以信息增益为准则来选择划分属性

熵(entropy): 熵指的是体系的混乱的程度,在不同的学科中也有引申出的更为具体的定义,是各领域十分重要的参量。

信息论(information theory)中的熵(香农熵): 是一种信息的度量方式,表示信息的混乱程度,也就是说:信息越有序,信息熵越低。例如:火柴有序放在火柴盒里,熵值很低,相反,熵值很高。

信息增益(information gain): 在划分数据集前后信息发生的变化称为信息增益。

了解更多信息熵https://www.zhihu.com/question/22178202

熵(entropy) 
熵是表示随机变量不确定性的度量。设X是一个取有限个值的离散随机变量,其概率分布为

则随机变量的熵定义为

条件熵(conditional entropy)

设有随机变量(X,Y),其联合概率分布为

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

信息增益(information gain)

信息增益表示得知特征X的信息而使得类Y的信息的不确定性减少的程度。特征A对训练数据集D的信息增益g(D,A),定义为集合D的经验熵H(D))与特征A给定条件下D的经验条件熵H(D|A)之差,即

如果选择一个特征后,信息增益最大(信息不确定性减少的程度最大),那么我们就选取这个特征。

信息增益恰好是:信息熵-条件熵。

2.信息增益率

实际上,信息增益准则对可取值数目较多的属性有所偏好,为了减少这种偏好可能带来的不利影响,C4.5决策树算法不直接使用信息增益,而是使用增益率来选择最优划分属性

特征A对训练数据集D的信息增益比gR(D,A)定义为其信息增益g(D,A)与训练数据集D关于特征A的值的熵HA(D)之比,即

需要注意的是,增益率准则对可取值数目较少对属性有所偏好。所以,C4.5算法并不是直接选择增益率最大对候选划分属性,而是用了一个启发式:先从候选划分属性中找出信息增益高于平均水平的属性,再从中选择增益率最高的。

信息增益与信息增益率计算详例参考 https://www.cnblogs.com/feiyumo/p/9284490.html

3.基尼指数

CART决策树算法使用基尼指数来选择划分属性,这个准则不再用熵和增益来衡量数据集的纯度,而是用基尼值来度量。直观来说这个值反映了从数据集中随机抽取两个样本,其类别标记不一致的概率。因此基尼值越小,则数据集的纯度越高。

项目案例-信息增益的代码实现


判定鱼类与非鱼类

项目概述

根据以下 2 个特征,将动物分成两类:鱼类和非鱼类。

特征:

  1. 不浮出水面是否可以生存
  2. 是否有脚蹼

创建数据

创建一组示例数据

def create_dataset():data_set = [[1, 1, 'yes'],[1, 1, 'yes'],[1, 0, 'no'],[0, 1, 'no'],[0, 1, 'no']]features = ['no surfacing', 'flippers']return data_set, features

分析数据

计算给定数据的信息熵(根节点信息熵)

def calcShannonEnt(dataSet):# 求list的长度,表示计算参与训练的数据量numEntries = len(dataSet)# 计算分类标签label出现的次数labelCounts = {}# the the number of unique elements and their occurrencefor featVec in dataSet:# 将当前实例的标签存储,即每一行数据的最后一个数据代表的是标签currentLabel = featVec[-1]# 为所有可能的分类创建字典,如果当前的键值不存在,则扩展字典并将当前键值加入字典。每个键值都记录了当前类别出现的次数。if currentLabel not in labelCounts.keys():labelCounts[currentLabel] = 0labelCounts[currentLabel] += 1# 对于 label 标签的占比,求出 label 标签的香农熵shannonEnt = 0.0for key in labelCounts:# 使用所有类标签的发生频率计算类别出现的概率。prob = float(labelCounts[key])/numEntries# 计算香农熵,以 2 为底求对数shannonEnt -= prob * log(prob, 2)return shannonEnt

按照给定特征划分数据集,即划分分支节点数据集

def splitDataSet(dataSet, index, value):"""splitDataSet依据index特征列进行分类,编列dataset,如果index列的数据等于value的时候,就要将此行划分到新的数据集中Args:dataSet 数据集                 待划分的数据集index 表示每一行的index列        划分数据集的特征value 表示index列对应的value值   需要返回的特征的值。Returns:index列为value的数据集【该数据集需要排除index列】"""retDataSet = []for featVec in dataSet: # index列为value的数据集【该数据集需要排除index列】# 判断index列的值是否为valueif featVec[index] == value:# chop out index used for splitting# [:index]表示前index行,即若 index 为2,就是取 featVec 的前 index 行reducedFeatVec = featVec[:index]'''           music_media.append(object) 向列表中添加一个对象objectmusic_media.extend(sequence) 把一个序列seq的内容添加到列表中 (跟 += 在list运用类似, music_media += sequence)1、使用append的时候,是将object看作一个对象,整体打包添加到music_media对象中。2、使用extend的时候,是将sequence看作一个序列,将这个序列和music_media序列合并,并放在其后面。music_media = []music_media.extend([1,2,3])print music_media#结果:#[1, 2, 3]music_media.append([4,5,6])print music_media#结果:#[1, 2, 3, [4, 5, 6]]'''reducedFeatVec.extend(featVec[index+1:])# [index+1:]表示从跳过 index 的 index+1行,取接下来的数据# 收集结果值 index列为value的行【该行需要排除index列】retDataSet.append(reducedFeatVec)return retDataSet

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

def chooseBestFeatureToSplit(dataSet):"""chooseBestFeatureToSplit选择最好的特征Args:dataSet 数据集Returns:bestFeature 最优的特征列"""# 求第一行有多少列的 Feature, 最后一列是label列嘛numFeatures = len(dataSet[0]) - 1# 数据集的原始信息熵baseEntropy = calcShannonEnt(dataSet)# 最优的信息增益值, 和最优的Featurn编号bestInfoGain, bestFeature = 0.0, -1# iterate over all the featuresfor i in range(numFeatures):# create a list of all the examples of this feature# 获取对应的feature下的所有数据featList = [example[i] for example in dataSet]# get a set of unique values# 获取剔重后的集合,使用set对list数据进行去重uniqueVals = set(featList)# 创建一个临时的信息熵newEntropy = 0.0# 遍历某一列的value集合,计算该列的信息熵 # 遍历当前特征中的所有唯一属性值,对每个唯一属性值划分一次数据集,计算数据集的新熵值,并对所有唯一特征值得到的熵求和。for value in uniqueVals:subDataSet = splitDataSet(dataSet, i, value)# 计算概率prob = len(subDataSet)/float(len(dataSet))# 计算信息熵newEntropy += prob * calcShannonEnt(subDataSet)# gain[信息增益]: 划分数据集前后的信息变化, 获取信息熵最大的值# 信息增益是熵的减少或者是数据无序度的减少。最后,比较所有特征中的信息增益,返回最好特征划分的索引值。infoGain = baseEntropy - newEntropyprint 'infoGain=', infoGain, 'bestFeature=', i, baseEntropy, newEntropyif (infoGain > bestInfoGain):bestInfoGain = infoGainbestFeature = ireturn bestFeature

训练算法:构造树的数据结构

def majorityCnt(classList):major_label = Counter(classList).most_common(1)[0]return major_labeldef creat_tree(dataset, feature_names):"""递归创建决策树:param dataset: 数据集,每递归一层删减最优特征列:param feature_names: 特征名称,每递归一层删减最优特征列名称:return:"""labels = [data[-1] for data in dataset]# 第一个停止条件:所有的类标签完全相同,则直接返回该类标签。if labels.count(labels[0]) == len(dataset):return labels[0]# 如果数据集只有1列,那么出现label次数最多的一类,作为结果# 第二个停止条件:使用完了所有特征,仍然不能将数据集划分成仅包含唯一类别的分组。if len(dataset[0]) == 1:return majorityCnt(labels)# 信息增益,选择最优的列best_feat_index = chooseBestFeatureToSplit(dataset)# 获取feature的名称作为树节点名称best_feat_name = feature_names[best_feat_index]# 初始化本层决策树节点和分支tree = {best_feat_name: {}}del (labels[best_feat_index])# 依据最优列划分分支数据,继续迭代以上信息增益步骤best_feat_column = [data[best_feat_index] for data in dataset]best_feat_class = set(best_feat_column)for one_class in best_feat_class:# 分支数据,且不包含最优列数据branch_data = split_dataset(dataset, best_feat_index, one_class)tree[best_feat_name][one_class] = creat_tree(branch_data, labels[:])return tree

测试算法:使用决策树执行分类

def classify(decision_tree, feat_labels, test_data):"""以字典的方式递归遍历树,找到最终分类:param decision_tree: 决策树 dict结构:param feat_labels: 特征名称 ["xxx","xx"]:param test_data: 测试数据,列表[1,1]:return:"""# 获取tree的根节点对于的key值top_key = decision_tree.keys()[0]# 通过key得到根节点对应的valuevalue_dict = decision_tree[top_key]# 判断根节点名称获取根节点在features中的为重feat_index = feat_labels.index(top_key)# 获取测试数据的特征值,决定分支走向test_feat_value = test_data[feat_index]class_label = value_dict[test_feat_value]# 判断分枝是否结束: 判断valueOfFeat是否是dict类型if isinstance(class_label, dict):class_label = classify(class_label, feat_labels, test_data)return class_label

注意问题


连续与缺失值

1、连续值处理

以上的属性值都是离散的,现实中通常会遇到连续的属性值。这个时候,连续属性离散化技术就可以用上啦,C4.5决策树算法采用的是最简单的策略二分法来对连续值进行处理。给西瓜属性考虑密度的属性,首先把不同样本的密度值按照从小到大排序,然后找到候选划分点,把每个候选划分点的信息增益算出来,取max的值作为密度的信息增益。第二次max就是找到最优划分属性了。

这里需要注意的是,与离散属性值不同,若当前结点划分属性为连续的,那么该属性还可以作为后面结点的划分属性。

2、缺失值处理

如果样本中有缺失值,那么会产生以下两个问题:

(1)如何在属性值缺失的情况下计算属性的信息增益,从而进行划分属性的选择?

(2)给定划分属性,如果样本在该属性值上是缺失的,如何对这个样本进行划分?

针对(1)的处理非常简单,假设17个样本在“色泽”属性上只有14个是有值的,另外3个是缺失的,那么就以这14个样本的属性值计算信息增益,然后把这个值乘以14/17,相当于乘上一个权重,当作这全部17个样本的信息增益。然后进行后续的属性划分。

针对(2)的处理也很简单,本来每个样本在结点中的权重都是1,当样本「8」在“纹理”上出现缺失值,那么在“纹理=清晰”、“纹理=模糊”、“纹理=稍糊”这三个分支中都会出现样本「8」,只是权重不再是1,而是7/15,5/15,3/15(这三个权重的来源是这三个分支中各个样本的比例,不包括这个样本「8」)

【机器学习】决策树算法 1相关推荐

  1. [飞桨机器学习]决策树算法

    [飞桨机器学习]决策树算法 一.简介 1.概述 决策树算法是一种逼近离散函数值的方法.它是一种典型的分类方法,首先对数据进行处理,利用归纳算法生成可读的规则和决策树,然后使用决策对新数据进行分析.本质 ...

  2. 机器学习-决策树算法原理及实现-附python代码

    1.决策树-分类树 sklearn.tree.DecisionTreeClassifier官方地址: https://scikit-learn.org/stable/modules/generated ...

  3. 机器学习-决策树算法ID3实现,含例子(红酒分类)

    决策树原理实现代码如下所示:(参考自机器学习实践 Peter Harrington). import mathx=[[0,1,"no"],[0,1,"no"], ...

  4. 机器学习 决策树算法

    4.1 决策树算法简介 学习目标 知道什么是决策树 能够通过sklearn实现决策树分类,进一步认识决策树 1 概念 决策树思想的来源非常朴素,程序设计中的条件分支结构就是if-else结构,最早的决 ...

  5. 机器学习——决策树算法

    文章目录 一.决策树介绍 二.利用信息增益选择最优划分属性 三.ID3代码实现 1.jupyter下python实现 2. 使用sklearn实现ID3 四.C4.5算法实现 五.CART算法实现 六 ...

  6. python决策树原理_Python机器学习决策树算法 | kTWO-个人博客

    ps:这篇文章主要来介绍决策树算法的基本原理和概念.具体的Python应用将在下一篇文章中介绍. 1.什么是决策树? 决策树(decision tree)也叫做判定树,类似于流程图的结构,每个内部的结 ...

  7. 机器学习决策树算法泰坦尼克号乘客生存预测

    目录 1 决策树算法api 2 泰坦尼克号乘客案例背景 2.1 步骤分析 2.2 代码实现 2.3 决策树可视化 2.3.1 保存树的结构到dot文件 2.3.2 网站显示结构 3 决策树总结 4 小 ...

  8. 机器学习——决策树算法原理及案例

    机器学习在各个领域都有广泛的应用,特别在数据分析领域有着深远的影响.决策树是机器学习中最基础且应用最广泛的算法模型.本文介绍了机器学习的相关概念.常见的算法分类和决策树模型及应用.通过一个决策树案例, ...

  9. Python数据分析实战【十二】:机器学习决策树算法案例实战【文末源码地址】

    文章目录 构造数据 决策树解决 报错解决 源码地址 构造数据 我们用pandas生成20条数据,其中标签为bad的数据有6条,标签为good的数据有14条,代码如下: import pandas as ...

  10. 机器学习——决策树算法的应用

    对于买电脑的示例,在Python数据包sk-learn中利用决策树算法实现数据分类,并画出决策树的结构 1.准备工作 (1)安装Graphviz(数据可视化软件),并配置好环境变量,加入到path中, ...

最新文章

  1. elasticsearch报错expected <block end>, but found BlockMappingStart解决方法
  2. 【转】ora-00031:session marked for kill处理oracle中杀不掉的锁
  3. 关联数组不能转化为JSON字符串
  4. vue动态生成表单元素
  5. Python风格总结:日期操作
  6. 中油即时通信电脑版_一文看懂云视频会议与即时聊天软件的差别
  7. java父类可以强转为子类吗_java父类可以强制转化成子类吗?
  8. 基于visual Studio2013解决C语言竞赛题之1064互质数差1验证
  9. 软件工程领域权威期刊
  10. 全国各省份结婚离婚面板数据(2000-2019年)
  11. NOI2015 小园丁和老司机
  12. Win11 开机资源管理器频繁崩溃闪退怎么处理?
  13. 提交application/x-www-form-urlencoded类型数据
  14. excel2016 for mac 二维表转一维表
  15. Orin 调试GMSL camera遇到问题之MIPI CSI2 报文解析
  16. rewind函数+php,PHP SplFixedArray rewind()用法及代码示例
  17. Java线程的调度(线程的优先级、线程睡眠、线程让步、线程插队)
  18. C语言_入门_我和编程
  19. Python 库打包分发(setup.py 编写)
  20. OpenSSL 证书

热门文章

  1. MySQL 判断语句 条件函数 case when、if、ifnull
  2. cocostudio导出数据在代码中加载
  3. 重读《DOOM启世录》
  4. 卡巴斯基终身免费用的方法!不要再到处奔波寻找Key啦!
  5. 10款免费开源图表插件推荐
  6. 基于Arduino的简易跑马灯+呼吸灯
  7. 操作系统习题1-银行排队叫号问题
  8. 解开VC++调用.Net DLL的神秘面纱
  9. 安装程序无法自动安装Virtual Machine Communication Interface
  10. Python超详细基础教程,从入门到实践