决策树
📜

决策树

 

决策树概述

  • 决策树是一种非参数的有监督学习方法,它能够从一系列有特征和标签的数据中总结出决策规则,并用树状图的结构来呈现这些规则,以解决分类和回归问题。
  • 决策树模型:树形结构,内部节点表示特征或属性,分支代表一个判断结果的输出,叶节点代表分类结果。
  • 决策树的学习:主要包括特征选择、决策树生成、决策树的剪枝三个部分,生成算法有ID3算法、C4.5算法、CART算法
  • 决策树的主要优点:模型具有可读性,分类速度快。
 

决策树模型

notion image
需要解决的问题:
选择哪些属性作为内部节点——>特征选择
怎样得到树的结构,何时形成叶子节点——>决策树生成和剪枝
 

特征选择

特征选择在于选取对训练数据具有分类能力的特征,
  • ID3的特征选择准则为信息增益最大化
  • C4.5的特征选择准则为信息增益比最大化
  • CART分类树的特征选择准则为基尼指数最小化
  • CART回归树的特征选择准则为平方误差最小化准则

信息增益和信息增益比

熵的定义
notion image
信息增益
  • 信息增益:表示经过特征A的划分,使得训练数据集D分类结果的不确定性减少的程度。定义为熵和条件熵之差,也即类与特征的互信息
    • g(D,A)=H(D)H(DA)g(D,A)=H(D)-H(D|A)
  • 利用极大似然估计概率来计算训练数据集D关于特征A的信息增益
    • 给定训练数据集D,其有K个类Ck,k=1,2,,KC_k,k=1,2,\ldots,K。给定特征A,特征A的取值集合为A={a1,a2,,an}A=\{a_1,a_2,\ldots,a_n\},根据该特征将训练数据集D划分为n个子集D1,D2,,DnD_1,D_2,\ldots,D_n,子集DiD_i中属于CkC_k的样本集合记为Dik=DiCkD_{ik}=D_i\cap C_k
      1. 计算D的经验熵
        1. H(D)=k=1KCkDlogCkDH(D)=-\sum_{k=1}^K\frac{|C_k|}{|D|}\log\frac{|C_k|}{|D|}
      1. 计算A对D的经验条件熵
        1. H(DA)=i=1nDiDk=1KDikDilogDikDiH(D|A)=-\sum_{i=1}^n\frac{|D_i|}{|D|}\sum_{k=1}^K\frac{|D_{ik}|}{|D_i|}\log\frac{|D_{ik}|}{|D_i|}
      1. 计算信息增益比
        1. g(D,A)=H(D)H(DA)g(D,A)=H(D)-H(D|A)
      问题:以信息增益作为划分训练数据集的特征,存在偏向于取值较多的特征的问题。
      原因:特征取值越多,划分的越细,划分的结果的纯度越高,信息增益越大。
      解决方法:信息增益比。
信息增益比
  • 信息增益比:定义为信息增益g(D,A)g(D,A)与训练数据集D关于特征A的熵HA(D)H_A(D)之比。
    • gR(D,A)=g(D,A)HA(D)g_R(D,A)=\frac{g(D,A)}{H_A(D)}HA(D)=k=1KDiDlogDiDH_A(D)=-\sum_{k=1}^K\frac{|D_i|}{|D|}\log\frac{|D_i|}{|D|}
      由于特征取值越多,熵HA(D)H_A(D)越大,信息增益比就越小,故可以对信息增益偏向于取值较多的特征的问题进行校正。
 

ID3算法

算法核心思想:以信息增益来度量特征选择,选择信息增益最大的特征进行分裂。
算法采用自顶向下的贪婪搜索遍历(同C4.5)可能的决策树空间,算法流程为
notion image
ID3算法缺点
  • 没有剪枝策略,容易过拟合;
  • 信息增益准则对可取值数目较多的特征有所偏好,类似“编号”的特征其信息增益接近于 1;
  • 只能用于处理离散分布的特征;
  • 没有考虑缺失值。
 

C4.5算法

C4.5相对于ID3的改进
  • 使用信息增益率作为特征选择准则,避免了信息增益偏向于取值较多的特征的问题。
  • 引入悲观剪枝策略进行后剪枝
  • 能够处理连续特征
  • 能够处理缺失值

悲观剪枝策略

剪枝策略分为预剪枝和后剪枝
预剪枝
预剪枝
利用超参数来控制树的结构,在节点划分前来确定是否继续增长,及早停止增长的主要方法有:
  • 是否达到最大深度;
  • 节点内数据样本低于某一阈值;
  • 所有节点特征都已分裂;
  • 节点划分前准确率比划分后准确率高;
  • 是否达到最小分裂增益;
预剪枝可以降低过拟合的风险而且还可以减少训练时间,但另一方面它是基于“贪心”策略,会带来欠拟合风险。
后剪枝
后剪枝
利用测试集在已经生成的决策树上进行剪枝,从而得到简化版的剪枝决策树。
后剪枝决策树的欠拟合风险很小,泛化性能往往优于预剪枝决策树。但同时其训练时间会大的多。
一般的后剪枝方法:基于误判的剪枝|REP|错误率降低修剪
一般的后剪枝方法:基于误判的剪枝|REP|错误率降低修剪
为最简单的方法,利用测试数据集来修改树结构。具体做法:
  • 对于完全决策树中的每一个非叶子节点的子树,尝试把它替换成一个叶子节点,该叶子节点的类别用子树所覆盖训练样本中存在最多的那个类来代替,这样就产生了一个简化决策树,然后比较这两个决策树在测试数据集中的表现,如果简化决策树在测试数据集中的错误比较少,并且该子树里面没有包含另外一个具有类似特性的子树(所谓类似的特性,指的就是把子树替换成叶子节点后,其测试数据集误判率降低的特性),那么该子树就可以替换成叶子节点。
    • notion image
  • 该算法以自底向上的方式遍历所有的子树,直至没有任何子树可以替换使得测试数据集的表现得以改进时,算法就可以终止。
REP方法的缺点:需要一个额外测试集。为了解决这个问题,提出了悲观剪枝。
C4.5 采用的悲观剪枝方法
悲观剪枝方法
悲观剪枝方法
不需要额外测试集去计算误判率,而是直接利用训练数据集去估算每个内部节点所覆盖样本节点的误判率。
  1. 利用惩罚因子估算误判率
    1. 把一颗子树(具有多个叶子节点)的分类用一个叶子节点来替代的话,在训练集上的误判率肯定是上升的,但是在新数据上不一定。于是我们需要把子树的误判计算加上一个经验性的惩罚因子。
      • 叶子节点的误判率:对于一颗叶子节点,它覆盖了N个样本,其中有E个错误,那么该叶子节点的误判率估计为E+0.5N\frac{E+0.5}{N},其中的0.5即惩罚因子。
      • 子树的误判率:那么一颗子树,它有L个叶子节点,那么该子树的误判率估计为i=1LEi+0.5Li=1LNi\frac{\sum_{i=1}^L E_i+0.5 * L}{\sum_{i=1}^L N_i}这样一来,虽然一颗子树具有多个子节点,但由于加上了惩罚因子,所以子树的误判率计算未必占到便宜。
      • 剪枝后子树变为叶子节点的错误率:该叶子节点的误判个数为J,则剪枝后的误判率估计为J+0.5N,(N=i=1LNi)\frac{J+0.5}{N},(N=\sum_{i=1}^L N_i)
      • 判断一颗子树是否需要剪枝成叶子节点:即判断J+0.5J+0.5是否在i=1LEi+0.5L\sum_{i=1}^L E_i+0.5 * L标准误差内。
  1. 根据分布模型估算误判次数
    1. 有了子树的误判率e1=i=1LEi+0.5Li=1LNie_1=\frac{\sum_{i=1}^L E_i+0.5 * L}{\sum_{i=1}^L N_i},再根据经验把它估计成各种各样的分布模型,比如正态分布、伯努利分布等。假设子树的误判次数服从伯努利分布,则可以估计出该子树的误判次数的均值和标准差:
      E(subtree_err_count)=Ne1var(subtree_err_count)=Ne1(1e1)\begin{aligned}E(subtree\_err\_count)&=N*e_1\\var(subtree\_err\_count)&=\sqrt{N*e_1*(1-e_1)}\end{aligned}
      把子树替换成叶子节点后,该叶子的误判次数也是一个伯努利分布,其概率误判率e2=J+0.5N,(N=i=1LNi)e_2=\frac{J+0.5}{N},(N=\sum_{i=1}^L N_i),因此叶子节点的误判次数均值为
      E(leaf_err_count)=Ne2E(leaf\_err\_count)=N*e_2
      这里我们采用一种保守的分裂方案,即有足够大的置信度保证分裂后准确率比不分裂时的准确率高时才分裂,否则就不分裂(即剪枝)。如果要分裂(即不剪枝)至少要保证分裂后的误判数E(subtree_err_count)要小于不分裂的误判数E(leaf_err_count),而且为了保证足够高的置信度,甚至要
      E(subtree_err_count)+var(subtree_err_count)<E(leaf_err_count)E(subtree\_err\_count)+var(subtree\_err\_count)<E(leaf\_err\_count)
      这里加了一个标准差可以有95%的置信度。反之,就是要进行剪枝。
notion image
 

处理连续特征

C4.5先把连续属性转换为离散属性,使用二分法进行处理。
具体做法:假设 n 个样本的连续特征 A 有 m 个取值,C4.5 将其排序并取相邻两样本值的平均数共 m-1 个划分点,的分到左子树,的分到右子树,分别计算以该划分点作为二元分类点时的信息增益,并选择信息增益最大的点作为该连续特征的二元离散分类点。
具体做法:假设 n 个样本的连续特征 A 有 m 个取值,C4.5 将其排序并取相邻两样本值的平均数共 m-1 个划分点vj(j=1,,m)v_j(j=1,\ldots,m)vj\leq v_j的分到左子树,vj\geq v_j的分到右子树,分别计算以该划分点作为二元分类点时的信息增益,并选择信息增益最大的点作为该连续特征的二元离散分类点。
notion image
(对于离散的特征只需做一次信息增益的计算,对于连续的特征需要做m-1次信息增益的计算)
更近一步减少计算量的方法
更近一步减少计算量的方法
对于连续属性先进行排序,只有在决策属性发生改变的地方才需要切开。
notion image
另外在决定分界点时应该采用信息增益,原因如下:
分界点将样本分成两个部分,这两个部分的样本个数之比也会影响信息增益率。根据增益率公式,我们可以发现,当分界点能够把样本分成数量相等的两个子集时(称此时的分界点为等分分界点),增益率的抑制会被最大化,因此等分分界点被过分抑制了。子集样本个数能够影响分界点,显然不合理。因此在决定分界点是还是采用信息增益这个指标,而选择属性的时候才使用信息增益率这个指标。这个改进能够很好得抑制连续值属性的倾向。

处理缺失值

如何计算带缺失值的特征的收益?
使用不含缺失值的样本集D˜\~D计算关于特征A的信息增益(或信息增益率),再乘以非缺失值样本所占的比例。
Gain(D,A)=ρ×Gain(D~,A)\operatorname{Gain}(D, A)=\rho \times \operatorname{Gain}(\tilde{D}, A)
训练的时候,如果选中了缺失特征,遇到这个这个特征缺失的样本,如何划分到子节点?
将样本同时划分到所有子节点,不过要调整样本的权重值,即以不同概率划分到不同节点中。比如特征缺失的样本x划分到第i个分支,那么这个权重就是第i分支里面不缺失的样本占父节点不缺失的样本的比重。这些权重会参与到后续信息收益的计算过程中。
初始化所有样本的权重为1,经过缺失特征分叉点后权重会降低。
预测的时候如何处理特征缺失的样本?
全部下发到子节点,这样会产生多条路径,分类的结果将会是类别的分布而不是某一类别,选择概率最高的类别作为结果。
 

CART算法

ID3 和 C4.5 虽然在对训练样本集的学习中可以尽可能多地挖掘信息,但是其生成的决策树分支、规模都比较大,CART 算法的二分法可以简化决策树的规模,提高生成决策树的效率。
CART假设决策树是二叉树,内部结点特征的取值为“是”和“否”,左分支是取值为“是”的分支,右分支是取值为“否”的分支。
CART的基本过程
  • 分裂:分裂过程是一个二叉递归划分过程(其输入和预测特征既可以是连续型的也可以是离散型的);
  • 剪枝:采用代价复杂度剪枝,从最大树开始,每次选择训练数据熵对整体性能贡献最小的那个分裂节点作为下一个剪枝对象,直到只剩下根节点。CART 会产生一系列嵌套的剪枝树,需要从中选出一颗最优的决策树;
  • 树选择:用单独的测试集评估每棵剪枝树的预测性能(也可以用交叉验证)。
CART 相比于 C4.5 的提升
C4.5
CART
树的结构
多叉树,运算速度慢
二叉树,运算速度快
应用场景
只能分类
既可以分类也可以回归
特征选择
信息增益率
使用 Gini 系数,减少了大量的对数运算
处理缺失值
以不同概率划分到不同节点中
采用代理测试来估计缺失值
剪枝策略
悲观剪枝方法
用“基于代价复杂度剪枝”方法进行剪枝
处理类别不平衡
通过一种先验机制来对数据自动加权,对类别进行均衡

CART 树分为分类树和回归树

CART分类树利用基尼指数最小化准则进行二分
基尼指数
基尼指数
  • 数据集D的纯度用基尼值度量为
    • Gini(D)=k=1Kkkpkpk=1k=1Kpk2=1k=1KCk2D2\begin{gathered}\operatorname{Gini}(D)=\sum_{k=1}^{K} \sum_{k^{\prime} \neq k} p_k p_{k^{\prime}} =1-\sum_{k=1}^{K} p_k^2=1-\sum_{k=1}^{K} \frac{|C_k|^2}{|D|^2}\end{gathered}
      直观来说,Gini(D)反映了从数据集D中随机选取两个样本,其类别标记不一致的概率,因此Gini(D)越小,则数据集D的纯度越高。
  • 在特征A下数据集D的条件基尼指数为
    • Gini(DA)=i=1nDiDGini(Di)\operatorname{Gini}(D|A)=\sum_{i=1}^n \frac{\left|D_i\right|}{|D|} \operatorname{Gini}\left(D_i\right)
      基尼指数偏向于特征值较多的特征,类似信息增益。
notion image
CART分类树生成算法
CART分类树生成算法
输入:训练数据集D,停止计算的条件;
输出:CART决策树
根据训练数据集,从根节点开始,递归地对每个结点进行以下操作,构建二叉决策树:
  1. 设结点的训练数据集为D,计算现有特征对该数据集的基尼指数,此时,对每一个特征A,对其可能取的每一个值a,根据样本点A=a的测试为“是”或“否”将D分割成D1和D2两部分,然后计算Gini(D,A)。
  1. 在所有可能的特征A以及他们所有可能的切分点a中,选择基尼指数最小的特征及其对应的切分点作为最优特征与最佳切分点。依最优特征与最优切分点,从现结点生成两个子节点,将训练数据集依特征分配到两个子节点中去。
  1. 对两个子节点递归调用1,2,直至满足停止条件。
  1. 生成CART决策树。
算法停止计算的条件是结点中的样本个数小于预定的阈值,或样本集的基尼指数小于预定的阈值(样本基本属于同一类),或者没有更多特征。
 
CART回归树利用平方误差最小化准则进行二分
回归树模型:其中 s 是切分点,x 是特征,y 是目标变量;利用切分点 s 将特征空间进行划分,y 是在划分单元上的输出值。
回归树模型:其中 s 是切分点,x 是特征,y 是目标变量;利用切分点 s 将特征空间进行划分,y 是在划分单元上的输出值。
回归树的关键是如何选择切分点、如何利用切分点划分数据集、如何预测 y 的取值。
CART回归树模型
CART回归树模型
给定训练数据集D={(x1,y1),(x2,y2),,(xN,yN)}D=\{(x_1,y_1),(x_2,y_2),\ldots,(x_N,y_N)\},其中x为输入变量,y为输出变量(且y为连续变量)。
假设已将输入空间划分成M个单元R1,R2,,RMR_1,R_2,\ldots,R_M,并且在每个RmR_m上有一个输出cmc_m.
回归树模型可以表示为
f(x)=m=1McmI(xRm)f(x)=\sum_{m=1}^Mc_mI(x\in R_m)
平方误差最小准则
平方误差最小准则
当输入空间的划分确定时,可以用平方误差来表示回归树对于训练数据的预测误差:
xiRm(yif(xi))2\sum_{x_i\in R_m}(y_i-f(x_i))^2
用平方误差最小的准则求得每个单元上的最优输出值c^m\hat{c}_m即Rm上所有实例对应的输出值的平均值:
c^m=ave(yixiRm)\hat{c}_m=ave(y_i|x_i\in R_m)
采用启发式的算法选择切分点
采用启发式的算法选择切分点
选择切分变量x(j)x^{(j)}和切分点s,定义两个区域R1(j,s)={xx(j)s}R_1(j,s)=\{x|x^{(j)}\leq s\}R2(j,s)={xx(j)>s}R_2(j,s)=\{x|x^{(j)}> s\},求解
minj,s[minc1xiR1(j,s)(yic1)2+minc2xiR2(j,s)(yic2)2]\min _{j, s}\left[\min _{c_1} \sum_{x_i \in R_1(j, s)}\left(y_i-c_1\right)^2+\min _{c_2} \sum_{x_i \in R_2(j, s)}\left(y_i-c_2\right)^2\right]
由上知,当j和s固定时,c^1=ave(yixiR1(j,s)),c^2=ave(yixiR2(j,s))\hat{c}_1=ave(y_i|x_i\in R_1(j,s)),\hat{c}_2=ave(y_i|x_i\in R_2(j,s));
固定j,遍历变量x(j)x^{(j)}所有可能的取值作为切分点,计算不同切分点对应的平方误差,取平方误差最小的取值作为变量变量x(j)x^{(j)}对应的切分点sjs_j,由此构成了一个(j,sj)(j,s_j)对。
遍历j,记录不同j值对应的(j,sj)(j,s_j)以及其平方误差,选择平方误差最小的(j,sj)(j,s_j)作为最优切分变量和切分点。
由此可以确定一个节点选择的特征和切分点,以此将区域划分为两个子区域。之后对两个新的子空间递归地进行上述的计算,直到满足停止条件,从而得到整个CART回归树。
notion image

CART剪枝

CART剪枝的损失函数:
Cα(T)=C(T)预测误差+αT复杂度C_\alpha(T)=\underbrace{C(T)}_{预测误差}+\alpha\underbrace{|T|}_{复杂度}
其中,T为任意子树,C(T)C(T)为对训练数据的预测误差(如回归树中的平方误差和分类树中的基尼指数),|T|为子树的叶结点个数,表示树的复杂度,α≥0为参数,控制预测误差和复杂度之间的平衡。
CART剪枝步骤
从生成算法产生的决策树T0T_0底端开始不断剪枝,直到T0T_0的根节点,形成一个子树序列{T0,T1,,Tn}\{T_0,T_1,\ldots,T_n\};
从完整树T0T_0开始剪枝,其任意内部结点为t,以t为单结点树(即仅t一个结点)的损失函数和以t为根结点的子树Tt的损失函数分别是:
Cα(t)=C(t)+αCα(Tt)=C(Tt)+αTt\begin{aligned}& C_\alpha(t)=C(t)+\alpha \\& C_\alpha\left(T_t\right)=C\left(T_t\right)+\alpha\left|T_t\right|\end{aligned}
  • α=C(t)C(Tt)Tt1\alpha=\frac{C(t)-C\left(T_t\right)}{\left|T_t\right|-1}时,Cα(Tt)=Cα(t)C_\alpha\left(T_t\right)=C_\alpha\left(t\right),即剪枝前后的损失函数相同,当剪枝的节点数更小,故剪枝;
  • α\alpha比该值小时,Cα(Tt)<Cα(t)C_\alpha\left(T_t\right)<C_\alpha\left(t\right),不剪枝;
  • α\alpha比该值大时,Cα(Tt)>Cα(t)C_\alpha\left(T_t\right)>C_\alpha\left(t\right),剪枝。
对于不同的内节点t而言,它们都存在一个对应的α值,使剪枝前后两者的损失相同。此时为了节点更少,应该选择剪枝。但参数α应该怎么设置呢,即用哪个α值使得模型的整体损失更小呢?
  1. 为此对T0T_0的每个内结点都进行上述的计算,此时α是t的函数,我们用g(t)表示,即g(t)=C(t)C(Tt)Tt1g(t)=\frac{C(t)-C\left(T_t\right)}{\left|T_t\right|-1},该式表示剪枝后整体损失函数减少的程度。
  1. T0T_0中剪去g(t)最小的TtT_t,将得到的子树作为T1T_1,同时将最小的g(t)设为α1\alpha_1,则T1为区间最小[α1,α2)的最优子树。如此剪枝下去,直至得到根节点,在这一过程中不断增加α的值,产生新的区间。
  1. 将剪枝后的所有子树{T0,T1,,Tn}\{T_0,T_1,\ldots,T_n\}保存起来,得到子树序列。
Breiman 证明:将从小增大, ,在每个区间中,子树是这个区间里最优的。
Breiman 证明:将α\alpha从小增大,0=α0<α1<<αn<0=\alpha_0<\alpha_1<\cdots<\alpha_n<\infty ,在每个区间[αi,αi+1)[\alpha_i,\alpha_{i+1})中,子树TiT_i是这个区间里最优的。
对子树序列用独立验证集进行交叉验证,从中选择一个平方误差或基尼系数最小的树作为最后的决策树模型。
使用独立测试集对子树序列进行交叉验证,计算每个子树的平方误差或者基尼系数,并选择最小的决策树作为最优的决策树TkT_k,该决策树对应于一个αk\alpha_k值,于是选出了最优的α参数。
CART剪枝算法
notion image

CART对缺失值的处理

在特征值缺失的情况下如何进行划分特征的选择?
计算缺失特征信息收益的时候,严格选择该特征不缺失的样本进行计算。同时乘以非特征缺失样本的比重(这部分和C4.5相似)。
如果最近分裂特征就是缺失特征,缺失样本应该划分到哪个子树?
对于该问题,CART 算法的机制是为树的每个节点都找到代理分裂器(无论在训练数据上得到的树是否有缺失值都会这样做):不选择增益最大的特征做为分裂特征,而是在剩下的其他【非缺失】的特征里面,找到增益最大的那个特征,把它选做分裂特征(代理)。如果这个代理的值也缺失了,那么就使用排名第二的代理,以此类推,如果所有代理值都缺失,那么默认规则就是把样本划分到较大的那个子节点。
代理分裂器可以确保无缺失训练数据上得到的树可以用来处理包含缺失值的新数据。

CART可以处理类别不平衡的问题

CART 使用了一种先验机制,其作用相当于对类别进行加权。这种先验机制嵌入于 CART 算法判断分裂优劣的运算里,在 CART 默认的分类模式中,总是要计算每个节点关于根节点的类别频率的比值,这就相当于对数据自动加权,对类别进行均衡。
对于一个二分类问题,节点 node 被分成类别 1 当且仅当:N1( node )N1( root )>N0( node )N0( root )\frac{N_1(\text { node })}{N_1(\text { root })}>\frac{N_0(\text { node })}{N_0(\text { root })}
比如二分类,根节点属于 1 类和 0 类的分别有 20 和 80 个。在子节点上有 30 个样本,其中属于 1 类和 0 类的分别是 10 和 20 个。如果 10/20>20/80,该节点就属于 1 类。通过这种计算方式就无需管理数据真实的类别分布。假设有 K 个目标类别,就可以确保根节点中每个类别的概率都是 1/K。这种默认的模式被称为“先验相等”。
先验设置和加权不同之处在于先验不影响每个节点中的各类别样本的数量或者份额。先验影响的是每个节点的类别赋值和树生长过程中分裂的选择。
 
 
 
 
参考链接:
悲观剪枝
C4.5缺失值的处理