1. 决策树
决策树可以用于分类和回归的应用里面,这里讨论的决策树是一个二叉树的形式,我们可以用伪代码的方式去表达出来:决策树就是一个 if-then 的集合,也可以认为是定义在特征空间与类空间上的条件概率分布。利用训练数据,根据损失函数最小化的原则建立决策树模型,其中包括:特征选择,决策树的生成,决策树的剪枝三个步骤。
下面讨论的都是分类决策树,除了CART树会讨论到回归树
1.1.1 决策树模型
定义:决策树由结点和有向边组成,其中,结点由内部节点(表示一个特征或属性)和叶节点(叶节点表示一个类)组成。
每一条路径构建一条对应的判断规则,而路径的终点就是叶节点表示将当前输入分到这个类别内。
每一个内节点就相当于条件概率上的概率,而所求随机变量的概率就相当于在某个叶节点看那一类占的数目比较多
决策树的本质是从训练数据集中归纳出一组分类规则,从另外一个角度看,决策树是由训练数据集估计出的条件概率模型
决策树学习的损失函数通常是正则化的极大似然函数,学习策略是以损失函数为目标函数的 最小化,也就是启发式学习:从众多筛选出来的决策树中,根据学习策略找到最优的那一棵
现假设我们的输出是“+1”和“-1”
1.1.2 决策树学习
大致的流程:构建根节点,将所有训练数据都放在根节点。选择一个最优特征,按照这一特征将训练数据集分割成自己,使得每个自己有一个当前条件下最好的分类。如果分对了,就放到对应的叶结点中,如果分类不正确,那么就对这些子集重新选择新的最优特征,继续分割。如此递归下去,直到所有训练数据子集被正确分类,或者没有合适的特征为止。以上是生成一棵极有可能过拟合的决策树,于是我们对整棵树进行自下而上地进行剪枝。
如果特征过多,我们应该一开始就选择部分有用的特征参与决策树的构建
决策树的构建是使得当前的判断规则几乎完美地逼近数据集的分类,而剪枝则是使得决策树具有更强的泛化能力
这里引用一下别人的伪代码,写得究极详细
(行 3) 当前结点包含的样本全部属于同一个类别,无需划分;
(行 6) 当前属性集为空,或是所有样本在所有属性上取值相同,无法划分。在这种情况下,把当前结点标记为叶结点,并且将其类别设定为该结点所含样本最多的类别;
(行 12) 当前结点包含的样本集和为空,不能划分,把当前结点标记为叶结点,但是将其类别设定为其父结点所含样本最多的类别,周志华老师的《机器学习》中在该条件下执行了 return,但是按照我的理解由于这里处于 for 循环中,虽然属性中的一个取值样本集合为空,但是其它取值情况下还有有可能有样本集合的,如果这里执行了 return,那么就跳过了其它取值判断的可能。
这里同样是引用别人的总结,因为是后期看自己的笔记觉得这一部分有助于理解,但自己又懒,索性饮用了hh
1.1.3 特征选择问题
我们判断一个特征是否具有很好的区分能力是以信息增益/信息增益比来说明的
首先先定义熵这个概念:
熵表示随机变量不确定性的度量,也就是在当前状态下的混乱程度,越混乱熵越大
随机变量X的熵定义为:
条件熵表示在已知随机变量X的条件下随机变量Y的不确定性。为X给定条件下Y的条件概率分布的熵 对X的数学期望:
当熵和条件熵中的概率由数据估计得到时,所对应的熵与条件熵分别称为经验熵和经验条件熵
我们把信息增益定义为集合的经验熵
与特征A给定条件下D的经验条件熵
之差:
信息增益表示由特征A而使得对数据集D的分类的不确定性的减少程度
1.1.4 信息增益的计算
训练数据集,
表示样本容量。设我们共有
个分类,由
表示,
表示当前类别的数量。设特征A有n个不同的特征:
, 特征A将数据集D氛围n个子集:
,在每个子集中,是类别K的记为
经验熵:
特征A对数据集D的经验条件熵:
这里第二个等式为什么是对n求和,直接套公式,在A的条件下,各个D的概率,各个D就是划分的子集,也就是每个子集出现的概率
然后第三个等式为什么第二个求和是对K求和,因为其实第二个等式H(Di)是H(Di|A),看定义就是“X给定条件下Y的条件概率分布的熵”,所以我们是求这个条件概率的熵,也就是A发生,各个D也发生,所以就用Dik/Di表示这个条件概率。
然后计算信息增益:
1.1.5 信息增益比的计算
以信息增益作为划分训练数据集的特征,存在偏向于选择取值较多的特征的问题(这句话还是有点不理解)。使用信息增益比可以对这一问题进行矫正
从别的博客上摘录过来的:当特征的取值较多时,根据此特征划分更容易得到纯度更高的子集,因此划分之后的熵更低,由于划分前的熵是一定的,因此信息增益更大,因此信息增益比较 偏向取值较多的特征。自己的话理解就是,因为我这个特征的取值可以非常多,所以可以非常好地过拟合地适应训练集的数据,所以我们可以更容易得到纯度更高的子集,从而使得信息增益比更加高。
定义:特征A对训练数据集D的信息增益比,定义为其信息增益与训练数据集关D关于特征A的值的熵
:
其中,这里训练数据集D关于特征A的值的熵,就是计算在A的条件下,数据集D的熵,所以才是用n进行求和
信息增益比本质: 是在信息增益的基础之上乘上一个惩罚参数。特征个数较多时,惩罚参数较小;特征个数较少时,惩罚参数较大。就是上文提到的
但是,当特征取值较少时HA(D)的值较小,因此其倒数较大,因而信息增益比较大。因而偏向取值较少的特征。
使用信息增益比:基于以上缺点,并不是直接选择信息增益率最大的特征,而是现在候选特征中找出信息增益高于平均水平的特征,然后在这些特征中再选择信息增益率最高的特征。
1.2 决策树的生成
1.2.1 ID3算法
ID3的核心就是在各个结点上应用 《 信息增益准则 》作为选择特征的标准,递归地构建决策树。
具体点的步骤:
(1)从根结点开始,对结点计算所有可能的特征的信息增益,选择信息增益最大的特征作为当前结点的特征
(2)若D中所有实例都是同一类K,则这决策树是一个单结点树,直接返回这一类就行;若A是一个空集,也就是区分不出什么来,则把数据集中最大的类K作为该节点的类标记并返回
1.2.2 C4.5算法
因为ID3算法会普遍选择一些特征数量多的特征值进行划分,对此我们加入乘法项,构建一个 《 信息增益比 》的衡量条件
我们不是直接选择 信息增益比 最大的特征,而是现在候选特征中找出 信息增益 高于平均水平的特征,然后在这些特征中再选择 信息增益比 最高的特征。
1.3 决策树的剪枝
在前面介绍提到过剪枝是为了降低模型的复杂度,有更好的泛化能力。
决策树的剪枝往往通过极小化决策树整体的损失函数来实现
我们设树的叶结点个数
(也可以表示模型的复杂度),t是树T的叶结点,该叶结点有
,其中属于k类的样本有
个,
为叶结点t上的经验熵,参数
,则决策树学习的损失函数定义为:
其中上式的第二个等式的第一项C(T) 表示的是模型对训练数据的预测误差,所以要对整个叶子结点都load一遍,看哪个是分错了。预测误差即模型与训练数据的拟合程度,可以表示为:
后面对k求和也就是将Ht(T)展开来了(这是在求经验熵,不是条件经验熵),表示的是在t的条件下(在特征t的条件下)数据集T的熵,所以我们看在整个特征下,各个类的误分类情况,所以:
所以整个式子化简后:
从上面几条式子可以看出较大促使选择较为简单的模型,
较小促使选择较为复杂的模型,当
=0意味着只考虑模型与训练数据的拟合程度,不考虑模型的复杂度
所谓的剪枝,也就是当确定的时候,选择损失函数最小的模型,也就是损失函数最小的子树。
《统计学习方法》写到:上述的损失函数的极小化等驾驭正则化的极大似然估计。所以利用损失函数最小原则则进行剪枝就是用正则化的极大似然估计进行模型选择
1.4 CART树
Classification And Regression Tree,其实也就是决策树,但CART树一定是二叉的,内部特征的取值为“是”和“否”,同样整个流程也是生成和剪枝
1.4.1 回归树
假设X和Y分别为输入和输出变量,并且Y是连续变量,给定训练数据集:
假设一讲输入空间划分为M个单元,这里的M个单元对应了决策树上有M个叶子结点,并且在每个单元
上有一个固定的输出值:
于是决策树的模型可以表示为:,只有匹配上了属于哪一个Rm才会输出对应的Cm,所以求和也相当于把属于自己的那一类的输出值给赋值出去而已
当输入空间的划分确定时,我们用平方误差来表示回归树对于训练数据的预测误差
我们要使得上面这个损失函数最小化,那么什么时候最小化了,就是我们模型输出值是那个区域Rm里所有y输出的平均值时,就会获得最小化:
于是我们根据最小损失函数的方式去找每一个领域的切分变量(记为j)和切分点(记为s),那么怎么衡量呢?原则上还是利用最小化损失函数去做:这里的切分变量和切分点不是一一对应的,先遍历j,然后在每个j上又去遍历s,例子:切分变量:年龄,切分点:从8岁到40岁,所以切分点就[8.40]
切分变量两个相邻取值区间内任一点均可
观察上式,其实就是通过找到一个点j,使得当前这次区分,两边都获得比较小的损失函数,权衡两边的情况去找这个点j
于是,我们根据这个准则就可以构建回归决策树了:
(1)根据上面的最小化损失函数来求解出切分变量j和切分点s
(2)根据(j,s)可以得到两个子区域,接着计算每个子区域对应的输出值:
(3)对每个区域都重复(1)和(2)操作,直到满足停止条件
这里面有一个例子说的非常好地说明回归树是怎么玩的
1.4.2 分类树
回归树是用平方差作为衡量分类标准,分类树则是引入基尼指数作为衡量标准
分类问题中,假设有K个类,样本点属于第k类的概率为,则对应的基尼指数为:
代入给定的样本集合D:
若如果样本集合D根据特征A是否取某一可能值a被分割成D1和D2两个部分,则在特征A的条件下,集合D的基尼指数定义为:
基尼指数Gini(D,A)表示经过A=a分割后集合D的不确定性,基尼指数越大,样本集合的不确定性就越大,所以这个特征分割得不咋滴
有了评价指数就可以生成CART分类树:
(1)设节点的训练数据集为D,计算现有特征对该数据集的基尼指数。此时对每一个特征A,对其可能取的每一个值a,根据样本点对A=a的测试为“是”或“否”将D分割成D1和D2两个子集,然后去计算这个A=a时对这个集合的基尼系数
(2)在计算完这么多基尼指数后,我们选择基尼指数组小的一组对应的切分点和切分特征作为当前点的最优选择,然后切开两份子集继续循环走(1)和(2)
(3)直到满足停止条件:节点中的样本个数小于设定阈值,或样本集的基尼指数小于设定阈值,或没有更多特征可供继续分类了
1.4.3 预剪枝
先对数据集做划分,形成训练集和验证集,训练集用来决定树生成过程中每个结点划分所选择的属性;验证集在预剪枝中用于决定该结点是否有必要依据该属性进行展开,在后剪枝中用于判断该结点是否需要进行剪枝。
1.4.4 CART剪枝
他妈的这一小节我看了好几天才看懂,书上我觉得写得有点简单了,查了好多资料才看懂
基本流程就是先根据不同的评价函数生成不同的决策树,然后从底端开始后不断剪枝,直到
的根结点,每剪一下,我们就将剪后的整棵树给保存下来(剪后剩下的树)
,然后通过交叉见证在独立的验证数据集上对子树的序列进行测试,从中选择最优子树
具体地,从整体树开始剪枝,对整体树任意内部结点t,以t为单结点(被剪枝了)树的损失函数是:
而以t为根节点(还没被剪)的子树的损失函数是:
因为没被剪,就相当于用某个特征分类了,那么这棵子树的预测误差肯定是比单个结点(被剪了)的预测误差要小。然而,随着的不断增大,终有一个时刻,会达到
这样一个平衡条件在里面,此时也就是表明,我剪不剪的损失函数都是一样的。但是在我们参数
终会不断变大的情况下,剪肯定是比不剪好的(两个损失函数的大小关系会相反),于是剪下来后剩余的树作为新的子树T1/T2/T3保存起来,供后面用验证集做比较
我们解决了怎么剪枝后,接下来就引出一个问题,我该选择哪个子树去剪?
我们观察到参数是不断变大的,也就是说,对于整棵树上这么多个结点,在某些时刻,肯定能找到对应的
,使得某个点的
,于是我们每次剪树之前,都计算树上所有结点(除了叶子结点)的状态(这里的状态指的是在
情况下,
究竟是怎么取值的),于是我们得出计算每个结点的
的公式:
这个公式表示的是剪枝后整体损失函数减少的程度函数
我们每次选择,都选择最小的来进行剪枝,具体为什么选择最小的,可以拿一个比他大的情况做比较,其实
,小的g(t)称为g1,大的g(t)称为g2,当alpha达到g1的值时,此时我g2还远没达到,没达到的意思就是我不剪的损失函数比剪的损失函数还要小,那我为什么要去剪g2的呢?于是我们优先选择见g1,此时g1达到了上面提到的平衡条件,是应该要剪的,再不剪,随着alpha增大,不剪的损失函数就要比剪的损失函数大了。于是我们每一步都优先选择最小的g(t)去剪枝
最后一步,在我们得到了这么多的子树后{T0,T1,T2......Tn},我们应用验证集去对每科子树进行误差(平方误差/基尼指数),他们之间误差最小的决策树就是最优决策树