好多算法之类的,看理论描述,让人似懂非懂,代码走一走,现象就了然了。

引:

from sklearn import tree

names = ['size', 'scale', 'fruit', 'butt']
labels = [1,1,1,1,1,0,0,0] p1 = [2,1,0,1]
p2 = [1,1,0,1]
p3 = [1,1,0,0]
p4 = [1,1,0,0]
n1 = [0,0,0,0]
n2 = [1,0,0,0]
n3 = [0,0,1,0]
n4 = [1,1,0,0]
data = [p1, p2, p3, p4, n1, n2, n3, n4] def pred(test):
dtre = tree.DecisionTreeClassifier()
dtre = dtre.fit(data, labels)
print(dtre.predict([test]))
with open('treeDemo.dot', 'w') as f:
f = tree.export_graphviz(dtre, out_file = f, feature_names = names) pred([1,1,0,1])

  画出的树如下:

  关于这个树是怎么来的,如果很粗暴地看列的数据浮动情况:

  或者说是方差,方差最小该是第三列,fruit,然后是butt,scale(方差3.0),size(方差3.2857)。再一看树节点的分叉情况,fruit,butt,size,scale,两相比较,好像发现了什么?

衡量数据无序度

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

  那么如何评价数据有序程度?比较直观地,可以直接看数据间的差距,差距越大,无序度越高。但这显然还不够聪明。组织无序数据的一种方法是使用信息论度量信息。在划分数据集之前之后信息发生的变化叫做信息增益(information gain),为了让信息更准确分类,必然希望信息增益最大化,那么信息增益如何计算?

  集合信息的度量方式叫做香农熵(名字源自信息论支付克劳德·香农),简称熵(entropy)。

  熵定义为期望值,如果P(Xi) 是分类为i的概率,那么对于分类i的熵L(Xi) 的公式是:

  显然地,随着分类的概率越高,其熵(L(X))越小。这很有意思,概率越高的东西,大家的期望值越低;越容易发生的事情,大家对它的发生不惊奇,没有期待;反过来说,发生几率越小的事情,一旦发生了,大家都会很惊奇,那么这个叫惊奇度可能比较合适hhh。

  计算熵值,不仅是要看单个分类的熵,要看所有分类的期望值,其中n是分类数目:

  从这个公式看来,这是一个带权重(是i分类的概率)的期望和。这个值可以用来表示事情的无序度。熵越高,则混合的数据越多。

为什么是以2为底的对数?

  首先还是可以从“数学期望”(设为E(X))是个什么东西入手,E(X) = ∑XP(X),这个X是个随机变量,可以把数学期望看成是:加权的概率和。那么如何确定随机变量X呢?可以这样看:X是这个概率出现的次数。我的描述可能有些不对,但从直观的加权上,大概是这样。例如有人去打猎,猎中1只概率1/5,猎中2只是3/5,猎中3只是1/5,那么他这一次出猎可能猎中多少只?E(X) = 1*1/5 + 2*3/5 + 3*1/5 = 2,每次平均2只。

  现在再来琢磨log2,为什么随机变量是2的对数?——我们来猜数字,这个数字在1~32,猜16,如果比16大就猜8,比8大就猜(8, 16)之间,以此类推,最多5次可以猜出——所有可能情况与对数log有关。而如果已经能排除一些不可能数字,那猜到答案的速度会更快。

参考:https://blog.csdn.net/lingtianyulong/article/details/34522757

  另一种度量集合无序度的方法是基尼不纯度(Gini impurity),公式原理并不太明白,先摆出来吧:

信息增益:

  信息增益(设为infoGain)作为无序度减少程度。

  某一列的直接按分类结果(label)的信息熵(设为baseEnt)与该列按标志值分类的信息熵(设为newEnt)的差距。

  ID3算法应用其差值:

infoGain = baseEntropy – newEntropy

  C4.5算法应用其比值,其中i为列标志值分类总数:

ID3创建决策树

  以信息熵来作为数据无序度判断依据的话,决策树如何创建?

  下面以这个 DataSet 作为计算demo,列名分别是:“不浮出水面是否可以生存”,“是否有脚蹼”,特别地,最后一列为 “是否为鱼类” 的分类标签:

no surfacing

flippers

Label

1

1

yes

1

1

yes

1

0

no

0

1

no

0

1

no

那么有矩阵:

[[1,1,’yes’],

[1,1,’yes’],

[ 1,0,’no’],

[ 0,1,’no’],

[ 0,1,’no’]]

步骤1:

  以label列作为分类标准,计算第一列熵,首先看第一列和标签列,计算如下图:

[0] 此处直接以0和1作为数据划分判断,对于标志性的数据可行,但如果是数值型的数据,那么就需要采取另一种决策树的构造算法。

  以此类推,计算第2列:

步骤2:

  比较所有列的熵,取无序度最小(也即信息增益 infoGain = baseColEnt - newColEnt 最大)的列(特征),做为决策树的节点。

  上例中,第一列信息熵最高,那么第一个节点就是no surfacing特征列。

步骤3:

  处理分裂节点。

  此时取步骤2中获得的特征列作DataSet行上的分类,划分出若干数据块后,其中信息熵为0的数据块是不再分裂的节点;信息熵不为0的,需要处理为新的DataSet,回到步骤1进行计算。

  对于本例,按照第一列,可以把DataSet分裂成2个数据块[1]:

[[1,1,’yes’],

[1,1,’yes’],

[ 1,0,’no’]]  ——设为DataSet_A

和:

[[ 0,1,’no’],

[ 0,1,’no’]]  ——设为DataSet_B

[1] 这两个数据块的划分还是依靠标志型数据的0与1,数值型数据采用另外的决策树构造法。

  此时DataSet_B全部为一个分类,那么这个节点就结束了。

  DataSet_A的标签分类不止一个,那么这个节点还需要继续分裂,而此时DataSet_A的第一列曾经做过分类列,新的DataSet可以除去这一列,即DataSet = [[1,’yes’],[1,’yes’] ,[0,’no’]]重新进入步骤1。

步骤4:

  绘制图像,叶节点为分类的标签结果,其中0为False,1为True。

  这种构造决策树的方法叫做ID3,ID3无法直接处理数值型数据,尽管可以通过量化的方法将数值型数据转化为标志型的数据,但如果存在太多的特征划分,ID3算法仍会有其他问题。其他的决策树构造法,有C4.5和CART等。

  ID3算法构建的决策树,其数据值需要是标志型(例如0表示否,1表示是,或者其他字符串[2],标志总数较少)的数据,如果是数值型的数据,需要换其他构建方法。另外,可能会出现匹配选项过多的问题,这叫做过度匹配(overfitting),为了减少过度匹配,可以裁剪决策树。

[2] 一个隐形眼镜类型的示例,数据集如下,列名依次为:age,prescript,astigmatic,tearRate,最后一列为标签列,其中no lenses表示不适合佩戴隐形眼镜,soft:软材质,hard:硬材质。

young        myope      no     reduced   no lenses

young        myope      no     normal      soft

young        myope      yes   reduced   no lenses

young        myope      yes   normal      hard

young        hyper        no     reduced   no lenses

young        hyper        no     normal      soft

young        hyper        yes   reduced   no lenses

young        hyper        yes   normal      hard

pre   myope      no     reduced   no lenses

pre   myope      no     normal      soft

pre   myope      yes   reduced   no lenses

pre   myope      yes   normal      hard

pre   hyper        no     reduced   no lenses

pre   hyper        no     normal      soft

pre   hyper        yes   reduced   no lenses

pre   hyper        yes   normal      no lenses

presbyopic        myope      no     reduced   no lenses

presbyopic        myope      no     normal      no lenses

presbyopic        myope      yes   reduced   no lenses

presbyopic        myope      yes   normal      hard

presbyopic        hyper        no     reduced   no lenses

presbyopic        hyper        no     normal      soft

presbyopic        hyper        yes   reduced   no lenses

presbyopic        hyper        yes   normal      no lenses

其决策树如下:

创建决策树的类库

    from sklearn import tree

  具体代码可见上文,不过代码示例是以基尼不纯度作为数据划分的评判准则,可以在声明树对象的时候传入参数,criterion = “entropy”设置决策树以信息熵作为划分标准:

    dtre = tree.DecisionTreeClassifier(criterion="entropy")

  此外,

    with open('treeDemo.dot', 'w') as f:
f = tree.export_graphviz(dtre, out_file = f, feature_names = names)

  这两句会创建保存在运行路径命名为treeDemo的dot文件,打开可见树节点信息:

digraph Tree {

node [shape=box] ;

0 [label="butt <= 0.5\nentropy = 0.954\nsamples = 8\nvalue = [3, 5]"] ;

1 [label="fruit <= 0.5\nentropy = 1.0\nsamples = 6\nvalue = [3, 3]"] ;

0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ;

2 [label="size <= 0.5\nentropy = 0.971\nsamples = 5\nvalue = [2, 3]"] ;

1 -> 2 ;

3 [label="entropy = 0.0\nsamples = 1\nvalue = [0, 1]"] ;

2 -> 3 ;

4 [label="scale <= 0.5\nentropy = 1.0\nsamples = 4\nvalue = [2, 2]"] ;

2 -> 4 ;

5 [label="entropy = 0.0\nsamples = 1\nvalue = [1, 0]"] ;

4 -> 5 ;

6 [label="entropy = 0.918\nsamples = 3\nvalue = [1, 2]"] ;

4 -> 6 ;

7 [label="entropy = 0.0\nsamples = 1\nvalue = [1, 0]"] ;

1 -> 7 ;

8 [label="entropy = 0.0\nsamples = 2\nvalue = [0, 2]"] ;

0 -> 8 [labeldistance=2.5, labelangle=-45, headlabel="False"] ;

}

  这个文件可以通过dot.exe(下载链接https://graphviz.gitlab.io/_pages/Download/Download_windows.html)绘制图像。

  (在安装目录的命令行窗口走dot -Tpng sample.dot -o sample.png语句,即可得到决策树图像)

  Samples是此时dataSet的样本个数,那么还有2个问题,1.节点阈值是如何确定;2.节点上的value是什么意思?(叶节点上最终分类的标志是?)这个类库的决策树构造方法与数值有关。

【机器学习笔记】ID3构建决策树的更多相关文章

  1. python机器学习笔记 ID3决策树算法实战

    前面学习了决策树的算法原理,这里继续对代码进行深入学习,并掌握ID3的算法实践过程. ID3算法是一种贪心算法,用来构造决策树,ID3算法起源于概念学习系统(CLS),以信息熵的下降速度为选取测试属性 ...

  2. 机器学习笔记----- ID3算法的python实战

    本文申明:本文原创,如有转载请申明.数据代码来自实验数据都是来自[美]Peter Harrington 写的<Machine Learning in Action>这本书,侵删. Hell ...

  3. 机器学习算法总结(二)——决策树(ID3, C4.5, CART)

    决策树是既可以作为分类算法,又可以作为回归算法,而且在经常被用作为集成算法中的基学习器.决策树是一种很古老的算法,也是很好理解的一种算法,构建决策树的过程本质上是一个递归的过程,采用if-then的规 ...

  4. 【机器学习实战学习笔记(2-2)】决策树python3.6实现及简单应用

    文章目录 1.ID3及C4.5算法基础 1.1 计算香农熵 1.2 按照给定特征划分数据集 1.3 选择最优特征 1.4 多数表决实现 2.基于ID3.C4.5生成算法创建决策树 3.使用决策树进行分 ...

  5. 机器学习笔记5-Tensorflow高级API之tf.estimator

    前言 本文接着上一篇继续来聊Tensorflow的接口,上一篇中用较低层的接口实现了线性模型,本篇中将用更高级的API--tf.estimator来改写线性模型. 还记得之前的文章<机器学习笔记 ...

  6. Python机器学习笔记:不得不了解的机器学习面试知识点(1)

    机器学习岗位的面试中通常会对一些常见的机器学习算法和思想进行提问,在平时的学习过程中可能对算法的理论,注意点,区别会有一定的认识,但是这些知识可能不系统,在回答的时候未必能在短时间内答出自己的认识,因 ...

  7. 用Python开始机器学习(2:决策树分类算法)

    http://blog.csdn.net/lsldd/article/details/41223147 从这一章开始进入正式的算法学习. 首先我们学习经典而有效的分类算法:决策树分类算法. 1.决策树 ...

  8. 机器学习算法实践:决策树 (Decision Tree)(转载)

    前言 最近打算系统学习下机器学习的基础算法,避免眼高手低,决定把常用的机器学习基础算法都实现一遍以便加深印象.本文为这系列博客的第一篇,关于决策树(Decision Tree)的算法实现,文中我将对决 ...

  9. Python机器学习笔记:不得不了解的机器学习知识点(2)

    之前一篇笔记: Python机器学习笔记:不得不了解的机器学习知识点(1) 1,什么样的资料集不适合用深度学习? 数据集太小,数据样本不足时,深度学习相对其它机器学习算法,没有明显优势. 数据集没有局 ...

随机推荐

  1. JavaWeb之JSP & EL & JSTL

    JSP & EL & JSTL JSP Java Server Page 什么是JSP 从用户角度看,就是一个网页.从程序员角度看,就是一个Java类,它继承Servlet,所以可以说 ...

  2. MySQL报错注入总结

    mysql暴错注入方法整理,通过floor,UpdateXml,ExtractValue,NAME_CONST,Error based Double Query Injection等方法. 报错注入: ...

  3. 【转载】不可不知的 Android strings.xml 那些事

    相信 strings.xml 已经是大家在 Android 开发中最熟悉的文件之一了,但其实它也有很多需要注意的地方和一些小技巧,知道了这些可以让你的 Android 应用更加规范易用,大家来看看吧. ...

  4. NetCoreAPI添加Swagger

    public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; ...

  5. rust 高级话题

    目录 rust高级话题 前言 零大小类型ZST 动态大小类型DST 正确的安装方法 结构体 复制和移动 特征对象 引用.生命周期.所有权 生命周期 错误处理 交叉编译 智能指针 闭包 动态分派和静态分 ...

  6. layui获取checkbox复选框值

    获取layui表单复选框已选中的数据 HTML <!DOCTYPE html> <html> <head> <meta charset="utf-8 ...

  7. spark streaming checkpointing windows

    spark streaming的相关概念: spark的核心是创建一个RDD对象,然后对RDD对象进行计算操作等 streaming可以理解为是 一个连续不断的数据流 ,然后将每个固定时间段里的数据构 ...

  8. 使用DRF来快速实现API调用服务

    本帖最后由 范志远 于 2019-3-19 16:55 编辑 增加加载Djagno REST Framework模块的选项 对于settings.py文件的INSTALLED_APPS增加'rest_ ...

  9. leetcode 树类问题

    208. Implement Trie (Prefix Tree) 子节点个数对应的是数组

  10. SpringBoot(十八)_springboot打成war包部署

    最近在做项目的时候,由于使用的是springboot,需要打成war包.我就按照正常的思路去打包,结果部署后无法访问,一直报错404.后续问了问 公司同事,他给解决了.说大部分都是这个原因. 如果需要 ...