现在工业和竞赛上比较流行的模型大都是集成学习模型, 如LGB, XGB, 这些模型的本质是若干个决策树组成的, 虽然单纯决策树本身的使用不是特别广泛, 但是从本质上理解这个基础模型, 能更好地理解集成学习模型. 决策树本身的逻辑是比较简单的, 但是涉及的领域比较广, 包括信息论的概念等等, 读者们如果花大量精力弄懂其所涉及的领域知识, 实用意义不是很大, 因此本文用大白话讲明白决策树的逻辑即可, 就不分AB类读者了, 大家可以把精力放在后续的集成学习模型上.
决策树是一个基础算法, 可以用于回归或分类, 这里以分类为例讲解方便理解, 回归的后面做补充就很容易明白了 如上图所示就是一个很简单的决策树, 所谓的形状和大小就是一份数据的特征了, 这里是离散特征, 但连续特征也是可以的, 第一个节点称为根节点, 最末端的节点是叶子节点, 其余是内部节点, 显然根节点和内部节点就是特征, 叶子节点就是标签 那么重点来了, 一份数据有很多特征, 怎么决定先划分哪些特征, 后划分哪些特征呢, 这个选择的过程, 是通过算法来实现的, 按照算法的不同, 决策树分为以下3种不同类型: ID3, C4.5, CART
使用信息论里的信息增益, 即熵增益来作划分依据 熵:指事件的不确定程度, 初始值是用样本数据中标注的频率计算, 公式如下: 如抛硬币这件事 X X X,有两种情况, 那么 p 正 = 0.5 p_正=0.5 p正=0.5, p 反 = 0.5 p_反=0.5 p反=0.5,即可代入公式计算出这件事 X X X的不确定程度, 显然 i i i越大(即结果多种多样), 且概率越均匀的事件, 熵就越大, 就是越让人捉摸不透的意思 熵增益:指事件不同阶段下熵的变化, 熵的前后差值即为特征 X X X划分后使事件 Y Y Y明朗了多少, 公式如下: 树生成策略:计算不同特征的熵增益,取差值最大的那个特征作为根节点, 剩下继续递归重复, 直到到达了我们设定的阈值为止(阈值包括树的最大深度, 或熵的最小值, 或最后每个叶子节点包含的最小样本数), 至此一棵树就生长结束了, 这棵树就是ID3树 缺陷: 无法用于连续特征, 同条件下取值比较多的特征比取值少的特征信息增益大,属于多叉树,效率低, 不能剪枝
由上面的缺陷知道, ID3是比较偏向于选择取值比较多的特征来划分的, 实际上这样容易过拟合, 与ID3不同, C4.5使用信息增益率划分特征, 可以一定程度上避免这问题: 树生成策略: H(Y)是数据集关于特征X的值的熵,结合前面ID3中熵增益的公式, 即可求出整个数据集对于不同特征的信息增益率, 依然取比率最大的那个特征来划分, 依旧是递归进行 缺陷: 能剪枝但效果不好, 属于多叉树, 含大量对数和排序运算,效率低
CART称为分类回归树, 可以用于分类和回归
用于分类时(二叉树), 使用基尼指数选择特征划分. 基尼系数的公式如下: 这里就不细说公式里面是怎么计算的了, 意义不是很大, 只需要了解含义即可, 基尼指数衡量了事件的不纯度, 在特征A下, 系统不纯度如果是最小值,则选该特征划分, 对连续特征也是根据基尼指数寻找二分点(阈值)的.
使用平方误差进行特征划分, ,前面说决策树可以用于回归, 就是指CART的这个均方误差划分的情况, 顾名思义, 回归树最后结果不是一个分类, 而是具体的数值 如以下样本集:
X1X2X3Y1……0.52……0.53……0.54……0.55……36……47……48……3算法思想: 方便起见, 这里只列出了X1的值. 穷举每一个特征 X i X_i Xi的每个阈值找最好的分割点, 衡量标准是分割后的两拨数的Y值与两拨数分别的平均值之间的平方误差和要最小, 递归进行, 最后叶子节点中所有值的均值就是预测值 步骤:
从 X 1 X_1 X1这个特征开始, 从 X 1 = 1 X_1=1 X1=1和 X 1 = 2 X_1=2 X1=2之间划分, 即第一部分 y y y的平均值是0.5, 作为该组的预测值, 则每个实际值减去预测值的差的平方和为0, 同理求出第二部分的平方误差和, 两部分的和加起来, 这个总和就衡量了如果按照这个特征的这个阈值划分所造成的总体误差继续从 X 1 = 2 X_1=2 X1=2和 X 1 = 3 X_1=3 X1=3之间划分, 也能求出一个代表了这个划分方法的误差, 以此类推, 那么划分到最后, 肯定有一个总和是最小的,代表按照 X 1 X_1 X1这个特征的某个划分点是最好的, 暂且称为 X 1 X_1 X1的最佳划分点对所有特征 X i X_i Xi都重复上面步骤, 看哪个特征的最佳化分点造成的误差最小, 那么就按照这个划分点划分, 整棵树的每一次划分都按照这三个步骤去选择划分点树生长结束后, 每个叶子节点里面有若干个样本, 这些样本的Y的均值就是这个叶子节点的预测值如果一棵树生长得很大很深, 对样本划分总能表现得很好, 但这样往往都是过拟合的, 所以可以剪掉一些节点, 如一开始那个图为例(实际上这么简单的树是不需要剪枝的, 为了方便理解所以举这个例子), 剪掉"大小"这个节点, 直接认为圆的都是大苹果, 而不区分大苹果小苹果了, 当然也可以认为都是小苹果, 这取决于其中哪一类较多, 因此为了简化模型的复杂度,防止决策树的过拟合问题, 要做预剪枝或后剪枝
在每一次实际对结点进行进一步划分之前,先采用验证集的数据来验证如果划分是否能提高划分的准确性。如果不能,就把结点标记为叶结点并退出进一步划分;如果可以就继续递归生成节点
后剪枝则是先从训练集生成一颗完整的决策树,然后自底向上地对非叶子结点进行考察,若将该结点对应的子树替换为叶结点能带来泛化性能提升,则将该子树替换为叶结点, 即如果某个内部节点的样本在标注上相差悬殊, 则可以剪枝, 少数服从多数 CART采用的办法是后剪枝法,即先生成决策树,然后产生所有可能的剪枝后的CART树,然后使用交叉验证来检验各种剪枝的效果,选择泛化能力最好的剪枝策略; 也可在初始化模型实例时指定最大深度, 最小基尼划分等数值
后剪枝决策树通常比预剪枝决策树保留了更多的分支; 后剪枝决策树的欠拟合风险很小,泛化性能往往优于预剪枝决策树; 后剪枝决策树训练时间开销比未剪枝决策树和预剪枝决策树都要大的多
不难发现, 无论哪种算法, 其目的都是希望我们的数据集从混乱的状态, 趋近于清晰的状态, 只是衡量的手段和指标不同罢了, 因此各有优劣, 三种算法对比如下: