一 决策树

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

决策树(decision tree)是一种基本的分类与回归方法,上图就是一个决策树。

长方形:decision block  判断模块

椭圆:terminating block  终止模块(表示已经得出结论,可以终止运行)

左右箭头:branch  分支

  我们可以把决策树看成一个if-then规则的集合,由(root node)到(leaf node)的每一条路径构建一条规则;路径上内部结点的特征对应着规则的条件,而叶结点的类对应着规则的结论。决策树的路径:互斥并且完备。每一个实例都被一条路径或一条规则所覆盖,而且只被一条路径或一条规则所覆盖。

决策树过程:

  • 收集数据:可以使用任何方法。比如想构建一个相亲系统,我们可以从媒婆那里,或者通过参访相亲对象获取数据。根据他们考虑的因素和最终的选择结果,就可以得到一些供我们利用的数据了。
  • 准备数据:收集完的数据,我们要进行整理,将这些所有收集的信息按照一定规则整理出来,并排版,方便我们进行后续处理。
  • 分析数据:可以使用任何方法,决策树构造完成之后,我们可以检查决策树图形是否符合预期。
  • 训练算法:这个过程也就是构造决策树,同样也可以说是决策树学习,就是构造一个决策树的数据结构。
  • 测试算法:使用经验树计算错误率。当错误率达到了可接收范围,这个决策树就可以投放使用了。
  • 使用算法:此步骤可以使用适用于任何监督学习算法,而使用决策树可以更好地理解数据的内在含义。

二  构建决策树

  这一过程可以概括为3个步骤:特征选择、决策树的生成和决策树的修剪。

2.1 最优特征选择

ID 年龄 有工作 有自己的房子 信贷情况 类别(是否个给贷款)
1 青年 一般
2 青年
3 青年
4 青年 一般
5 青年 一般
6 中年 一般
7 中年
8 中年
9 中年 非常好
10 中年 非常好
11 老年 非常好
12 老年
13 老年
14 老年 非常好
15 老年 一般

    特征选择就是决定用哪个特征来划分特征空间。选取对训练数据具有分类能力的特征。如果利用一个特征进行分类的结果与随机分类的结果没有很大差别,则称这个特征是没有分类能力的。经验上扔掉这样的特征对决策树学习的精度影响不大。

  通常特征选择的标准是信息增益(information gain)或信息增益比。

  熵定义为信息的期望值。在信息论与概率统计中,熵是表示随机变量不确定性的度量。

  Xi信息量:  

  熵:         (熵越大,随机变量的不确定性就越大。)

  训练数据集D的经验熵为H(D)(empirical entropy):

  ( 当熵中的概率由数据估计(特别是最大似然估计)得到时,称为经验熵。|D|表示其样本容量,及样本个数。设有K个类Ck,k = 1,2,3,···,K,|Ck|为属于类Ck的样本个数)

2.1.1  编写代码计算熵

 from math import log       #要用log函数需要import
'''创建数据集
dataset 数据集
labels 分类属性'''
def createdataset():
dataset = [[0, 0, 0, 0, 'no'], #数据集
[0, 0, 0, 1, 'no'],
[0, 1, 0, 1, 'yes'],
[0, 1, 1, 0, 'yes'],
[0, 0, 0, 0, 'no'],
[1, 0, 0, 0, 'no'],
[1, 0, 0, 1, 'no'],
[1, 1, 1, 1, 'yes'],
[1, 0, 1, 2, 'yes'],
[1, 0, 1, 2, 'yes'],
[2, 0, 1, 2, 'yes'],
[2, 0, 1, 1, 'yes'],
[2, 1, 0, 1, 'yes'],
[2, 1, 0, 2, 'yes'],
[2, 0, 0, 0, 'no']]
labels = ['年龄', '有工作', '有自己的房子', '信贷情况','类别(是否给贷款)'] #分类属性
return dataset, labels #返回数据集和分类属性
'''计算熵'''
def shannon(dataset):
numlines = len(dataset) #返回数据的行数 样本数量
labelcount = {} #保存每个标签出现次数的字典
for feature in dataset:
currentlabel = feature[-1]
if currentlabel not in labelcount.keys():
labelcount[currentlabel] = 0
labelcount[currentlabel] += 1
shannonent = 0.0
for key in labelcount:
prob = float(labelcount[key])/numlines
shannonent -= prob *log(prob,2) #log(pro,2) log以2为底,pro的对数
return shannonent if __name__ == '__main__':
dataset,features = createdataset()
print(dataset)
print(shannon(dataset))

2.1.2  信息增益

  条件熵H(Y|X)表示在已知随机变量X的条件下随机变量Y的不确定性

      

   同理,当条件熵中的概率由数据估计(特别是极大似然估计)得到时,所对应的条件熵成为条件经验熵(empirical conditional entropy)。

  信息增益是相对于特征而言的,信息增益越大,特征对最终的分类结果影响也就越大,我们就应该选择对最终分类结果影响最大的那个特征作为我们的分类特征。所以,特征A对训练数据集D的信息增益g(D,A),定义为集合D的经验熵H(D)与特征A给定条件下D的经验条件熵H(D|A)之差,即

    (H(D|A)就是针对某一特征来计算的熵)

  熵H(D)与条件熵H(D|A)之差称为互信息(mutual information)。决策树学习中的信息增益等价于训练数据集中类与特征的互信息。

  最后,比较特征的信息增益,由于特征A3(有自己的房子)的信息增益值最大,所以选择A3作为最优特征。

2.1.3  编写代码计算信息增益

 from math import log

 '''计算经验熵
dataset 数据集
shannonent 经验熵''' def shannon(dataset):
samplesnumber = len(dataset)
labelcounts = {}
for feature in dataset:
currentlabel = feature[-1]
if currentlabel not in labelcounts:
labelcounts[currentlabel] = 0
labelcounts[currentlabel] += 1
shannonent = 0.0
for key in labelcounts:
prob = float(labelcounts[key])/samplesnumber
shannonent -= prob * log(prob,2)
return shannonent '''创建测试数据集
dataset 数据集
labels 分类属性''' def creatdataset():
dataSet = [[0, 0, 0, 0, 'no'], # 数据集
[0, 0, 0, 1, 'no'],
[0, 1, 0, 1, 'yes'],
[0, 1, 1, 0, 'yes'],
[0, 0, 0, 0, 'no'],
[1, 0, 0, 0, 'no'],
[1, 0, 0, 1, 'no'],
[1, 1, 1, 1, 'yes'],
[1, 0, 1, 2, 'yes'],
[1, 0, 1, 2, 'yes'],
[2, 0, 1, 2, 'yes'],
[2, 0, 1, 1, 'yes'],
[2, 1, 0, 1, 'yes'],
[2, 1, 0, 2, 'yes'],
[2, 0, 0, 0, 'no']]
labels = ['年龄', '有工作', '有自己的房子', '信贷情况'] # 分类属性
return dataSet, labels # 返回数据集和分类属性 '''按照给定的特征进行划分数据集
dataset 待划分的数据集
axis 划分数据集的特征
value 需要返回的特征的值
'''
def splitdataset(dataset,axis,value):
retdataset = []
for featvec in dataset:
if featvec[axis] == value:
reducedfeatvec = featvec[:axis] #去掉axis特征
reducedfeatvec.extend(featvec[axis+1:]) #list.extend(anotherlist) 函数用于在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)。
retdataset.append(reducedfeatvec) #定义了一个空列表,然后用append的方式,参数可以是列表(表中表)可以是元素对象
return retdataset #返回的是在 ==value时,去掉了特征值得列表 '''选择最优特征
dataset 数据集
bestfeature 信息增益最大的特征的索引值
'''
def choosebestfeature(dataset):
numfeatures = len(dataset[0]) -1 #特征的数量
baseentropy = shannon(dataset) #计算数据集的熵
bestinfogain = 0.0 #信息增益
bestfeature = -1
for i in range(numfeatures):
#获取dataset的第i个所有的特征
featlist = [example[i] for example in dataset] #函数展开式
uniquevals = set(featlist) #创建set集合,元素不可重复
newentropy = 0.0 #计算信息增益
for value in uniquevals: #计算信息增益
subdataset = splitdataset(dataset,i,value) #筛选出的是等于value的列表,并去掉了该特征
prob = len(subdataset)/float(len(dataset)) #计算出的是该特征值出现的概率
newentropy += prob * shannon(subdataset) #pro *(在特定特征下的熵,即是否给予贷款的熵)
infogain = baseentropy - newentropy #信息增益
print('第%d个特征的增益为%.3f'%(i,infogain))
if (infogain > bestinfogain):
bestinfogain = infogain
bestfeature = i
return bestinfogain,bestfeature if __name__ =='__main__':
dataset,features = creatdataset()
print('最优特征索引值:' + str(choosebestfeature(dataset)))

三  决策树的生成和修剪

我们已经学习了从数据集构造决策树算法所需要的子功能模块,包括经验熵的计算和最优特征的选择,其工作原理如下:得到原始数据集,然后基于最好的属性值划分数据集,由于特征值可能多于两个,因此可能存在大于两个分支的数据集划分。第一次划分之后,数据集被向下传递到树的分支的下一个结点。在这个结点上,我们可以再次划分数据。因此我们可以采用递归的原则处理数据集。

构建决策树的算法有很多,比如C4.5、ID3和CART,这些算法在运行时并不总是在每次划分数据分组时都会消耗特征。由于特征数目并不是每次划分数据分组时都减少,因此这些算法在实际使用时可能引起一定的问题。目前我们并不需要考虑这个问题,只需要在算法开始运行前计算列的数目,查看算法是否使用了所有属性即可。

决策树生成算法递归地产生决策树,直到不能继续下去未为止。这样产生的树往往对训练数据的分类很准确,但对未知的测试数据的分类却没有那么准确,即出现过拟合现象。过拟合的原因在于学习时过多地考虑如何提高对训练数据的正确分类,从而构建出过于复杂的决策树。解决这个问题的办法是考虑决策树的复杂度,对已生成的决策树进行简化。

decision tree 决策树(一)的更多相关文章

  1. Decision tree(决策树)算法初探

    0. 算法概述 决策树(decision tree)是一种基本的分类与回归方法.决策树模型呈树形结构(二分类思想的算法模型往往都是树形结构) 0x1:决策树模型的不同角度理解 在分类问题中,表示基于特 ...

  2. Decision tree——决策树

    基本流程 决策树是通过分次判断样本属性来进行划分样本类别的机器学习模型.每个树的结点选择一个最优属性来进行样本的分流,最终将样本类别划分出来. 决策树的关键就是分流时最优属性$a$的选择.使用所谓信息 ...

  3. OpenCV码源笔记——Decision Tree决策树

    来自OpenCV2.3.1 sample/c/mushroom.cpp 1.首先读入agaricus-lepiota.data的训练样本. 样本中第一项是e或p代表有毒或无毒的标志位:其他是特征,可以 ...

  4. 决策树Decision Tree 及实现

    Decision Tree 及实现 标签: 决策树熵信息增益分类有监督 2014-03-17 12:12 15010人阅读 评论(41) 收藏 举报  分类: Data Mining(25)  Pyt ...

  5. 用于分类的决策树(Decision Tree)-ID3 C4.5

    决策树(Decision Tree)是一种基本的分类与回归方法(ID3.C4.5和基于 Gini 的 CART 可用于分类,CART还可用于回归).决策树在分类过程中,表示的是基于特征对实例进行划分, ...

  6. 决策树(decision tree)

    决策树是一种常见的机器学习模型.形象地说,决策树对应着我们直观上做决策的过程:经由一系列判断,得到最终决策.由此,我们引出决策树模型. 一.决策树的基本流程 决策树的跟节点包含全部样例,叶节点则对应决 ...

  7. (ZT)算法杂货铺——分类算法之决策树(Decision tree)

    https://www.cnblogs.com/leoo2sk/archive/2010/09/19/decision-tree.html 3.1.摘要 在前面两篇文章中,分别介绍和讨论了朴素贝叶斯分 ...

  8. 决策树decision tree原理介绍_python sklearn建模_乳腺癌细胞分类器(推荐AAA)

    sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003& ...

  9. [ML学习笔记] 决策树与随机森林(Decision Tree&Random Forest)

    [ML学习笔记] 决策树与随机森林(Decision Tree&Random Forest) 决策树 决策树算法以树状结构表示数据分类的结果.每个决策点实现一个具有离散输出的测试函数,记为分支 ...

随机推荐

  1. 解读HDFS(转载)

    是蛮久木有写过关于hadoop的博客了额,虽然最近也看了一些关于linux的基础知识,但似乎把这个东西忘记了,其实时不时回顾一下以前的知识还是蛮有意思的,且行且忆! 我们Hadoop 主要由HDFS和 ...

  2. 21.boost Ford最短路径算法(效率低)

    到某个节点最近距离                  最短路径当前节点的父节点 完整代码 #include <iostream> #include <string> #incl ...

  3. iOS开发-Tools-CocoaPods

    CocoaPods是什么? 当你开发iOS应用时,会经常使用到很多第三方开源类库,比如JSONKit,AFNetWorking等等.可能某个类库又用到其他类库,所以要使用它,必须得另外下载其他类库,而 ...

  4. POJ 3693 后缀数组+RMQ

    思路: 论文题 后缀数组&RMQ 有一些题解写得很繁 //By SiriusRen #include <cmath> #include <cstdio> #includ ...

  5. dl learn task

    https://deeplearning4j.org/cn/word2vec Task 1 分类http://blog.csdn.net/czs1130/article/details/7071734 ...

  6. 「JavaSE 重新出发」01. Java介绍

    「白皮书」关键术语 简单性(C++--) 面向对象 分布式 健壮性 安全性 体系结构中立 可移植性 解释型 高性能 多线程 动态性 Java 发展历程 SUN公司--Stanford Universi ...

  7. Reactive programming-文章解析

    数据源(信息源):静态的数组.动态的流: In computing, reactive programming is a declarative programming paradigm concer ...

  8. SpringBoot学习笔记(6)----SpringBoot中使用Servlet,Filter,Listener的三种方式

    在一般的运用开发中Controller已经大部分都能够实现了,但是也不排除需要自己实现Servlet,Filter,Listener的方式,SpringBoot提供了三种实现方式. 1. 使用Bean ...

  9. No mapping found for HTTP request with URI [/spring_liu/hello.do] in DispatcherServlet with name 'SpringMVC'

    控制台一直报No mapping found for HTTP request with URI [/spring_liu/hello.do] in DispatcherServlet with na ...

  10. CF1015F Bracket Substring (KMP+DP)

    题目大意:给你一个长度为$n$的括号序列$T$,要求你构造一个长度为$2n$的括号序列$S$,保证这个括号序列在插入数字后一定是正确的,并且$T$是$S$的一个子串 还以为是什么纯粹的数学构造题,一通 ...