决策树一种简单的机器学习方法。它是对被观测数据进行分类的一种相当直观的方法,决策树在经过训练以后,看起来就像是以树状形式排列的一系列if-then语句。
1. 描述决策树(二叉树)
用一个类表示树上的每一个节点,每个节点会有以下5个信息:
a) 待检验的判断条件所对应的列值key ;
b) 对应为了是结果为true,当前列匹配的值value;
c) 结果为true的节点(左子树);
d) 结果为false的节点(右子树);
e) 存储当前分支的结果,除叶节点外,在其他节点上该值为None。
构造决策树直接返回根节点,沿着左右子树一直遍历。
2.训练决策树
这里用的方法是CART(Classification and Regression Trees)分类回归树。
在决策树的每一个节点上我们可以按任一个属性的任一值进行划分。
3.选择合适的划分方案
度量方式:
1)基尼不纯度
背景:总体内包含的类别越杂乱,GINI指数就越大。比如A类:5个,B类:2个
计算方式:GINI=1-[(5/7)*(5/7)+(2/7)*(2/7)]
备注:本书中计算的方式不是上面的公式,是个等值的计算(a+b+c)(a+b+c)-(a*a+b*b+c*c)=2(a*b+b*c+a*c)。这里a+b+c=1 可以有很多个类,不只有3个类,此处是为了说明问题。
衡量标准:概率的值越高,说明对数据的拆分越不理想。概略值为0则代表拆分的结果非常理想。因为这说明了每一行数据都已经被分配到了正确的集合中
2)熵
说明:代表集合的无序程度,
计算公式:p(x)log(p(x))之和的相反数。
衡量标准:熵为0,说明所有结果都相同。熵越高,说明群组越混乱
熵和基尼不纯度之间的主要区别在于,熵达到峰值的过程要相对慢一些。(why??没太明白)。为了区分哪个属性最适合用来拆分,算法会计算相应的信息增益。最好的划分就是使得增益最小的划分
3)信息增益
概念:当前衡量值(GINI不纯度 or 熵)与两个新群组经加权平均后的衡量值(GINI不纯度 or 熵)之间的差值
计算方式:以GINI不纯度为例,根据某个属性进行分类:在true结果下:A类:5个,B类:2个;在false结果下:C类:3个,D类:3个,E类:2个
true下:GINI=1-[(5/7)*(5/7)+(2/7)*(2/7)]=20/49
false下:GINI=1-[(3/8)*(3/8)+(3/8)*(3/8)+(2/8)*(2/8)]=42/64
根据这个属性进行分类,得到的GINI增益为:GINI_Gain=7/15*20/49+8/15*42/64
4.构造决策树(递归方式)
基于上述的CART方法,遍历数据集中的每一列,针对各列查找每一种可能的取值,并将数据集拆分成两个新的子集。计算每个新的子集的增益,取增益最小的子集作为当前的拆分方式。如此递归下去,完成决策树的构造
5.决策树的剪枝
前面训练决策树会有一个问题,就是决策树可能会变得过度拟合。上面的算法直到无法再进一步降低熵的时候才会停止分支的创建过程。所以一种可能的解决方法是,只要当熵减少的数量小于某个最小值时,就停止分支的创建。这种策略常被采用,但有个小小的缺陷,可能会遇到这样的数据集:某一次分支的创建并不会令熵降低多少,但是随后创建的分支却会使熵大幅降低。对此,一种替代的策略,先构造好整棵树,然后尝试消除多余的节点,这就是剪枝。
预剪枝(前剪枝)
通过提前停止树的构造来对决策树进行剪枝;一旦停止该节点下树的继续构造,该节点就成了叶节点;
后剪枝
首先构造完整的决策树,允许决策树过度拟合训练数据;然后对那些置信度不够的节点的子树用叶节点来替代。文中采用的是前剪枝:对具有相同父节点的一组节点进行检查,判断如果将其合并,熵的增加量是否会小于某个指定的阈值。如果确实如此,则这些叶节点会被合并成一个单一的节点,合并后的新街点包含了所有可能的结果值
6.决策数的使用(针对例子而言)
优势:可以轻易地对一个受训模型给与解释。
缺陷:1)对小的训练集,效率没有多大影响,对于拥有大量可能结果的数据集时,算法的效率有待考证。2)可以处理简单的数值型数据,但是只能创建满足“大于/小于”条件的节点。对于某些数据集,当我们对其进行分类的时候,决定分类的因素往往取决于更多变量的复杂组合。如果结果值是由两个变量来决定,树就会变得庞大,预测的准确率也会下降
总之,对于有大量数值型输入和输出的问题,决策树不一定是好的选择;决策树最适合用来处理的,是那些带分界点的、由大量分类数据和数值数据共同组成的数据集。
附录:
1.python的lambda函数
匿名函数,即函数没有具体的名称
def f(x):
return x**2
等同于
g=lambda x:x**2