项目地址:https://github.com/Daya-Jin/ML_for_learner
原博客:https://daya-jin.github.io/tag/#tree
模型概述
决策树算法最早用于分类任务,算法根据数据的特征与类别生成一棵树,并以这棵树对未知数据进行分类。
首先要了解熵(Entropy)的概念。在热力学中,熵被用于表示系统的混乱程度;而在信息论中,熵用于表示信息量的大小。
在一个有个类别的样本中,假设类别的概率分布为:
那么这个具有个类别的样本的信息熵为:
当整个数据集只有一个类别时,熵最低,为
当数据集各类别为均匀分布时,熵最大,为
假设某一离散属性有个不同的的取值,那么当以特征来划分时可以将数据集分为个子集:
那么划分之后的个子数据集的加权熵为:
ID3
Iternative Dichotomizer,是最早的决策树算法,其根据信息增益(Information Gain)来寻找最佳决策特征,当按特征A来划分数据集时的信息增益定义为:
首先,树的根节点中包含整个数据集,ID3算法会遍历所有特征分别做test来计算划分后的信息增益,然后选择信息增益最大的那个test,按该特征的类别数将数据集划分到下一层的各个子节点中;对各个子节点中的数据递归进行这个过程,直到信息增益足够小或者无特征可用。
可以看出,ID3算法有如下特点:
- 贪心算法
- 每次做决策时只用一个特征
- 没有办法处理连续特征跟缺失值
- 容易过拟合
在只考虑信息增益的情况下,ID3算法有一个致命缺陷,就是会倾向于选择类别数多的特征来做划分。假设有一列特征(如样本ID)类别数与样本数相等,如果以该特征来进行划分数据集,则数据集被划分成了单样本节点,每个节点的熵均为0,总熵也为0,这样一来得到了最大的信息增益,但是这种划分显然是不合理的。
实现指导:分类 回归
完整代码:分类 回归
C4.5
为了修正ID3算法的缺陷,C4.5算法应运而生。
首先,C4.5在ID3的基础上改进了生成树算法,不再使用信息增益,而是使用增益比(gain ratio)来决定使用哪个特征来划分数据集。
增益比定义为:
其中被称为固有值(intrinsic value),它等价于某一特征在数据集中的熵。
假设在一个数据集中有某个特征,其有个不同的取值,那么特征在数据集中的概率分布为:
那么数据集中该特征的固有值(熵)为:
这样一来就减少了信息增益在做决策时的比重。
此外,C4.5算法还加入了对连续值的处理。对于一个连续特征,假设其在样本中有个不同的取值,其有序集合为,那么对应的就有处划分点,取相邻两值的中点做划分点,那么划分点集合可表示为:。当选取某一划分点进行划分时,数据集被分成两部分:中所有样本的特征都要小于等于,中所有样本的特征都要大于。然后再以之前的公式计算划分之后的信息增益与增益比。
然后是C4.5对缺失值的处理,决策树算法在处理缺失值熵需要解决三个问题:熵的计算,数据集的划分,带缺失值的预测。
第一条,在做test时,当前特征为缺失值的样本不参与熵的计算;
第二条,在做test时,给当前特征缺失的样本赋一个初始值为的权重,做划分时,这些特征缺失的样本会被复制多份分配到所有子节点中,并按照叶子节点中非缺失样本的比例更新权重。设某个子结点中的非缺失样本占父节点非缺失样本比例为 ,则更新该结点中每个缺失值样本的权重为。
第三条,在预测带缺失值的样本时,样本在决策树中的行走路线同上,最后该样本会同时出现在多个叶子节点中,按在各叶子节点中的权重和来给出预测类别。
最后,C4.5使用自底向上的剪枝策略来避免过拟合。
Classification And Regression Tree
CART是一棵二叉树,每次test都将问题空间分成两个区域,可处理连续变量与类别型变量,所以one-hot encoding对CART是无效的。
分类
CART分类树的生成类似上面两种算法,不过做test时选取特征的依据是基尼指数(Gini Index)。对于有个类别的数据集,某一样本属于类别的概率等于该类别的分布概率:
那么该数据集的基尼指数定义如下:
从公式易得,基尼指数表示的是从数据集中随机取两个不同类别样本的概率,其值越小则数据集纯度越高。
由于CART的特殊性,其在做test时与ID3、C4.5略有不同,CART是二叉树,并且在对类别型变量做划分时做得是非划分。如对一个数据集以特征的一个取值来划分,那么数据集会被划分成和,那么数据集依照特征划分之后的加权基尼指数为:
CART在划分时会遍历所有的特征与其所有可能的取值,再全局考量选取一个最佳特征与最佳划分点。若数据集有个特征,每个特征有种不同取值,上述过程可以用下式来表述:
实现指导
完整代码
回归
首先需要说明的是回归树的输出是叶子结点中所有样本目标值的均值。那么对于回归任务,怎么去生成树?可以采用一种直观的方式来对数据集进行划分,假设某一时刻数据集(数据子集)被决策树以特征按取值划分成了两部分(或两个叶子节点):
则此次划分的优劣可用MSE来判断:
其中,为区域所有样本目标值的均值,为区域所有样本目标值的均值。
在生成回归树时,使用贪心策略,遍历所有特征下所有可能的取值,找到一个最优划分点,然后以此类推。决策树在做预测时,首先将测试样本丢进决策树进行判定,判定该测试样本属于哪一个叶子节点,然后把该叶子结点内所有训练样本的目标均值作为测试样本的预测值。
除了使用MSE作为分裂依据(splitting criteria)之外,还有一个变量可以用作回归树的分裂:方差(variance)。当使用方差作为分裂依据时,生成树的目的很明显,希望子节点内的值越稳定越好。
CART同样使用剪枝来避免过拟合。
注意:能做回归任务并不是CART树的专利,ID3与C4.5都可以用于回归!
实现指导
完整代码
树的正则化
决策树算法的缺点就在于极易过拟合,所以控制决策树的模型复杂度以防止过拟合是很有必要的。首先可以设定几个参数抑制树的生长:最大树深(max_depth),最大叶子结点数(max_leaf_nodes),叶子结点最小样本数(min_samples_leaf),分裂最小增益(min_impurity_decrease)。除此之外,也可以对树的生长不做限制,然后再对树进行剪枝(pruning)。
Pessimistic Estimate Pruning
C4.5使用悲观估计剪枝法(待补充)。
Cost-Complexity Pruning
CART使用cost-complexity剪枝方法。类似线性模型中的正则化,可以加入一项结构风险项来指导剪枝过程,定义一个Cost-Complexity函数:
其中表示一棵树,表示树的分类(回归)误差,为正则化系数,为能表示树结构复杂度的函数。下面以分类任务做示例。
令树的结构复杂度函数等于树的叶节点数:
再令树的误差函数为:
其中为树中的第个叶节点,为该叶节点的分类误差率,为该叶节点的样本比例,上式实质上是一个加权误差率。对一个确定的值,一定会有一颗最小化的树。为了找到这颗最优剪枝树,使用最弱链接剪枝(weakest link pruning)策略,自底向上地对非叶节点进行剪枝并查看效果,然后选取一个表现最好的。
假设某一时刻以节点进行剪枝,那么剪枝后与剪枝前的CC函数差为:
其中,为树中以节点为根节点的子树。令得,整个CCP算法流程如下所述:
生成一颗完整树,对所有的非叶节点都进行剪枝尝试,找到一个最小化的剪枝节点,令,
对所有的非节点都进行剪枝尝试,找到一个最小化的剪枝节点,令,
依次进行下去,直到只剩下一个根节点为止,那么可以得到一个子树序列和一系列参数,然后在所有子树上使用交叉验证来选取一个最佳参数与最佳剪枝树。
总结
决策树算法的优缺点分别在于
优点:
- 可解释性强,甚至强于线性模型
- 可可视化
- 不需要太多的数据预处理
- 能同时处理数值型数据与类别型数据
- 自带多分类解决方案
缺点:
- 预测准确性不如其他模型,因为树模型中没有统计模型
- 树模型的variance很大,一方面是模型本身极易过拟合,非常不稳定;另一方面是顶层划分的误差会逐级往下传播
- 树模型的if-else规则难以捕获到数据中的非轴向关系
- 做回归任务时缺少平滑性,需要增加树深来提高表现
各决策树算法的对比:
| | ID3 | C4.5 | CART |
| :--------: |: ----: | :--: | :--: |
| splitting criterion | Information Gain | gain ratio | Gini Index |
| tree structure | multiway tree | multiway tree | binary tree |
| continuous attribute support | - | √ | √ |
| handling missing value | - | √ | √ |
| pruning | - | √ | √ |
| regression support | - | - | √ |
集成学习
讲决策树就不得不提集成学习。因为树模型中没有引入统计模型,导致树模型对的variance很大,虽然在训练集上表现很好,但是在测试集上的表现却差强人意,所以集成学习很适合应用到决策树算法上。