第十三章 Python 机器学习入门之决策树
目录
系列文章目录
前言
一、决策树模型
1 什么是决策树模型?
2 决策树学习的过程
二、如何确定在节点使用的特征
1 熵的定义
2 什么是信息增益?
3 利用信息增益来看看构建决策树的整个过程
三、独热编码one-hot
1 什么是one-hot
2 one-hot 在决策树中的应用
四、回归树
五、 使用多个决策树
1 为什么要使用树集合
2 有放回抽样
3 随机森林算法
4 XG Boost 算法
六、何时使用决策树
总结
本文从决策树出发,
第一部分讲解了什么是决策树模型,了解了一些决策树的基本概念;
第二部分提到了如何确定在决策树节点使用什么特征,其中介绍了熵的概念、什么是信息增益,以及如何使用信息增益去构建决策树;
第三部分讲到了独热编码,以及在决策树中的应用;
第四部分讲了如何使用决策树解决回归问题;
第五部分介绍了如何使用多个决策树,其中提到了有放回抽样、随机森林算法、xgboost算法;
第六部分重点讲了什么时候去使用决策树,将决策树与神经网络做了个比较。
决策树模型 Decision tree model
我们以猫分类为例,构建一个神经网络模型,
如图,我们有3个输入特征,输出标签0或1,这是一个二元分类问题。
输入的特征X 采用分类值,也就是说,这些特征值只取几个值,第一个特征形状要么是尖的,要么是松软的;脸型要么是圆的,要么不是圆的;胡须要么有,要么没有。
那么,什么是决策树呢?
图中每个圆形或方形的框都称为决策树中的一个节点,该模型的工作原理就是,当我们有一个新的测试示例(耳朵尖尖的,圆脸,有胡须),我们会从树的最顶层节点处开始向下;耳朵是圆的,所以向左left边走,也就是左下方的分支;在查看脸型,因为是圆脸,使用继续向左下方运行,最后得出结论,这是一只猫。当我们到达最后一个节点,系统就会根据结果预测这是只猫。
决策树中的最顶层的节点称为根节点;所有椭圆形的节点,也就是除了最底层的矩形框外,都称为决策节点;最底层的矩形框称为叶子节点。
决策树学习的第一步就是确定我们在根节点使用什么特征(假设我们选择了耳朵形状特征),也就意味着,我们会根据耳朵的形状来差分所有的输出图片,如图,我们有10个输入的例子,结果将耳朵尖的5个例子分到左边,耳朵松软的5个例子分到右边;
第二步是在决策节点处选择要使用的特征(假设使用面部形状特征),
决策树的左边五个例子中,4个被分到圆脸的左边,1个被分到 不是圆脸的右边,我们观察会发现左边的4个例子都是猫,所以不用继续预测了,就创建一个叶节点。右边的1个例子不是猫,所以可以给它一个节点 不是猫;
决策树的左边五个例子中,假设我们在决策节点处选择使用是否有胡须的特征进行分类,1个被分到有胡须的左边,4个被分到无胡须的右边,我们观察会发现左边的1个例子都是猫,所以不用继续预测了,就创建一个叶节点。右边的4个例子不是猫,所以可以给它一个节点 不是猫
以上,就是构建决策树算法的过程了。
在这些过程中,我们每个决策节点都做出了判断,让我们来看看每个关键的决定是什么。
我们在每个特征节点都使用了特征进行分类,那么如何知道在哪一个节点使用哪一个特征呢?
我们一般是根据哪一个特征在这一次分类中,可以使得分类的纯度最大,这里第一个特征选择耳朵形状会使得纯度最大。(文章下面会说到什么是纯度)
所以在决策树学习时,我们做的第一步就是决定选择哪个特征;
第二个关键的决定就是何时停止使用特征进行分类,也就是何时停止拆分。我们刚才使用的标准是确定了100%是猫或者不是猫才停止拆分。除此之外,我们可以在分裂没有进一步的结果导致树超过最大深度。树的最大深度时可以人为设定的一个参数;
在决策树中,节点的深度定义为跳数,从表示最顶部的根节点到特点节点所需的时间,
根节点所在的位置是depth 0,如果我们设定决策树最大深度为2.那么它在depth 2就会输出结果,将不会拆分此级别以下的任何节点,这时决策树永远也不会到达深度3。
限制决策树的深度,是为了不让决策树变得太大、太笨重;其次,保持决策树很小,它也不容易过度拟合
这是我们决定停止拆分决策树的一个原因。
另一个原因是,优先级分数的改进(后面会说到),就是如果拆分后得到的收益太小,由于要尽量保持决策树较小,我们也会考虑停止拆分。
还有就是,如果某个节点示例数低于某个阈值,我们也可能会停止分裂。
我们一般会使用熵来衡量一组示例的纯度
先来看一下熵的定义:熵就是衡量一组数据是否不纯的指标。
例如给定一个例子,有3只猫、3只狗。我们如果将p_1定义为猫样本的比例,也就是标签为1占的比例
这个例子中p_1=3/6
我们将建立如图所示的函数来表示熵,熵函数通常表示为H,这里横轴为p_1值,纵轴为熵的值
这里p_1 = 0.5 时,熵的值H(p_1)=1
如果我们的数据集里全是猫,或都不是猫时,熵的值为0
可以看见图中下面一个例子,有5只猫和1只狗,此时正例p_1 = 5/6 = 0.8333 ,熵的值H(p_1)大约为0.65
如图,如果p_1=p_0 时,也就是取0.5,这时熵函数H取得最大值1
在构建决策树时,我们将决定在节点上拆分什么样的特征取决于 选择什么样的特征可以最大程度的减小熵,或最大化纯度。
在决策树学习中,熵的减少称为信息增益,下面我们来看看如何来计算信息增益,来决定要在决策树上每个支点上选择什么特征进行拆分。
如图,如果以耳朵是尖还是软的为特征,拆分结果左边5个中有4个是猫,右边5个中有1个是猫,概率分别为0.8和0.2. 如果应用熵公式,那么左边的杂质是熵0.72,右边的熵也是0.72。
如果以 脸是圆的和不是圆的 为特征,拆分结果左边7个中有4个是猫,右边3个中有1个是猫,概率分别为0.57和0.33. 如果应用熵公式,那么左边的杂质是熵0.99,右边的熵也是0.92,所以左右节点的杂质程度比前一个要高得多。
如果以 有没有胡须 为特征,拆分结果左边4个中有3个是猫,右边6个中有2个是猫,概率分别为0.75和0.33. 如果应用熵公式,那么左边的杂质是熵0.81,右边的熵也是0.92.
我们需要做的就是对比这3个特征,找出哪一个特征在根节点使用的效果最好。
事实证明可以对这些计算出来的熵值进行加权平均,然后在做比较。
还从头开始,第一个,我们10个例子中有5个去了左分支,5个去了右分支,那么我们就可以直接计算加权平均值,如图,依次类推,其他的特征计算也是一样的。3个加权平均值最小的哪个就是我们需要的那个特征。
但是这样并不准确,在构建决策树的方式中,我们实际上要对这些公式在决策数构建中遵循惯例,除了计算这个加权平均熵,我们需要将计算熵的减少与我们没有进行分裂的情况相比较。
我们回到上面的例子,没有进行分裂时,10个中有5只猫,p_1=0.5, 根节点的熵实际上等于1,这时纯度最高,我们实际上用于拆分的公式如图
计算出来的0.28、0.03、0.12这些被称为信息增益。它衡量的是熵的减少。
随这决策树的不断分裂,经过不断的拆分,我们最终会得到较低的熵值
这两个值之间的差异,就是熵的减少
为什么我们要计算熵的减少而不仅仅是左右分支的熵呢?
因为决定何时停止或不停止分裂的标准之一,如果熵的减少太小,则需要进一步拆分。
在这种情况下,我们可以选择熵减少的较多的结果进行拆分,因为一直拆分会有过度拟合的风险。
信息增益标准让我们决定如何去选择一个特征来分割一个节点,
我们从根节点开始,首先计算所有的3个特征的信息增益,发现耳朵形状的信息增益最大,也就是说耳朵形状就是最好的分裂特征,所以我们在根节点使用耳朵形状作为特征。
随后,我们创建一个左支行和右支行,并将数据集按照特征进行分类。
我们先看左边的5个数据子集,是否符合停止分裂的标准(节点中的所有东西都属于一个类)
很明显不符合停止分裂的标准,所以我们要选择拆分的特征,计算每个特征的信息增益,发现脸型的特征信息增益最大,所以我们选择脸型特征进行拆分,然后建立左右分支,进行拆分
我们还是先看左边分支,4个全是猫,所以我们停止拆分,建立一个预测猫的叶节点。
同样右边是一只狗,我们停止拆散,建立一个不是猫的叶节点。
在构建了左边的决策树后,我们来看看右边的,步骤也是同样的。
注意,当我们在根节点决定使用上面特征进行拆分后,我们构建左子树的方法是在5个示例的子集上构建决策树,构建右子树的方法是再次在5个示例的子集上构建决策树。
在计算机科学中,这是递归算法的一个 例子,也就是说,我们在根部构建决策树的方式是在左右支行上再构建其他较小的决策树。
计算机科学中的递归算法是指编写调用自身的代码,这在构建决策树上出现的方式是我们通过构建整个决策树较小的子决策树,然后把它们放在一起。
在目前学习的特征中都是只有两个离散值的,像猫的脸是圆的或者不是圆的、有胡须或没有胡须等。
如果特征可以采用两个以上的离散值呢?我们可以使用one-hot 编码解决这种特征。
还是以猫狗分类为例,猫的耳朵有3种类型了,尖的、软的或椭圆形的。
初始特征仍然是一个分类值特征,但它可以采用3个可能的值,如果在决策树支点使用这个特征,那么我们就会创建3个子分支。这里有一种处理特征不同的方式,使用one-hot 编码,将这一个特征,变成3个特征。
如图,使用one-hot 编码,我们将创建3个新的特征,分别是耳朵是尖的、耳朵是松软的、耳朵是椭圆的。
对于第一个示例,我们之前说耳朵形状是尖尖的,现在我们说这种动物耳朵是尖的值为1、耳朵是松软的值为0、耳朵是椭圆的值为0,以此类推,其他的示例也这样写。
我们现在就是构建了3个新特征,而不是1个特征取3个可能的值,每个特征都可以取两个可能的值0或1。
更详细一点,如果一个分类特征可以取k个可能的值,我们可以创建k个二进制特征(可以取的可能值为0或1)来实现.
在之前的例子中,我们训练决策树使用one-hot 编码来进行建模 编码分类特征也适用于训练神经网络。
如果我们将脸型和胡须的特征也用0或1 来表示,这样我们就有3个可能的耳朵形状值,1个可能的脸型值和1个可能的胡须值 这5个特征列表。
这5个特征列表可以输入到新网络或者逻辑回归中,来训练猫分类器。
所以one-hot编码时一种不仅仅适用于决策树学习的技术,它允许我们使用0或1对分类特征进行编码,一边它可以作为输入馈送到神经网络,也可以将数字作为输入。可以用于新的网络或线性回归或逻辑回归训练。
我们现在已经会使用一些离散的特征了。
让我们来看看如何修改决策树,使其可以使用连续值的特征(可以是任意数字的特征,不仅仅是0或1)。
如果我们给猫狗分类的例子加了一个重量特征,它是一个连续值的特征,那我们怎么分割这个重量特征呢?
我们可以根据重量是否大于或对于某个值,比如说数字8,然后我们画一条直线,将例子分裂,计算两边的信息增益,选出信息增益最大的一个。
我们一般会尝试x 轴上的多个值,一种惯例是根据权重或根据该特征的值对所有示例进行排序,并取所有训练排序列表之间的中点值,以此处作为阈值考虑值的示例。
如果我们有10个训练示例,我们将针对此阈值测试9个不同的可能值,然后尝试选择可以为我们提供最高信息增益的那个值,它就是连续值的特征。
这里,我们当值为9时,信息增益最大为0.61,假设算法选择这个特征来分割,我们最终会得到两个子集,
然后可以使用递归构建额外的决策树,这两个子集就用来构建树的其他部分。
我们目前只学习了作为分类算法的决策树, 如果我们有一个回归问题,我们如何使用决策树来预测数字。
其实决策树可以泛化处理回归问题。
假设我们要使用下图中的3个特征来预测猫或狗的重量,来看看怎么使用决策树进行预测数字。
与前面不同,这里我们不是预测动物是猫还是狗,我们的输出目标是一个数字。
首先,我们还是要构建一个决策树,我们将动物分好类了,如何输出权重呢?
如图,输入示例会跟随决策节点,一直到叶节点,如何预测该值(图中红色部分),我们是取每个叶节点示例的权重的平均值作为输出值。这种决策树称为回归树。
首先看根节点,我们分别看看3个特征的分类结果,那么怎么确定使用哪一个特征呢?
让我们一个个的看,一般我们会先计算左边分裂的方差,然后计算右边分类的方差;再写出左右分支数量的占比;如何计算加权平均方差,如图。
这个和我们在决定使用什么分割时使用的加权平均熵的作用非常相似。
然后我们继续对其他的特征计算这个加权平均方差。
在回归树中,选择拆分的一个好办法时只选择最低的加权平均方差值。
类似于我们计算信息增益(其实就是熵的减少),所以我们也可以进一步计算方差的减少,拿根节点的方差20.51 减去其他的,如图。
结果如图,第一个结果的方差减少的最多,所以它就是我们需要的特征。
单个决策树的缺点之一是该决策树可能对数据中的微小变化高度敏感,
为了解决这个问题,我们通常构建多个决策树,称之为树集合。
来举例说明,如图,我们之前在根节点处使用的特征是耳朵的形状,它具有最高的信息增益。
如果我们将数据集中的一个狗改成猫呢?在这个根节点的使用的特征就会改变为是否有胡须,因为这个特征现在具有最高信息增益。
这就是为什么说 单个决策树可能对数据中的微小变化高度敏感,
改变一个训练示例就会使得算法有所改变,显然这个算法不那么稳定。
所以我们通常会训练多个决策树来解决这个问题,也就是训练一个树集合。
当我们有一个树集合,那么每一个决策树都可能是一种对猫或不是猫进行分类的合理方法。
如果我们有一个新的示例想要进行预测,那我们要做的就是在新示例上运行所有的决策树(图中是3个)
让它们共同决定哪个是最终预测结果,3个决策树都对新示例进行了预测,其中2个预测是猫,一个不是,3个决策树“投票”,结果是猫的可能性较大,所以预测结果就是猫。
为了构建树集合,我们需要一种技术,称为有放回抽样。
如果有10个训练示例放在一个箱子里,每次取样都是随机拿出一个样本,再放回,再随机拿出一个样本,直到我们拿到10个样本,这其中可能有重复的,这个训练集也可能不包括10个原始的训练示例。这就是带有替换程序的抽样的一部分。
带放回抽样,可以让我们构建一个新的训练集,这是构建树集合的关键。
现在我们有了一种使用替换的方法来创建新的训练集,这些训练集有点类似于原始的数据集,但是也有些不同。
下面来看看如何构建树集成算法,会使用到随机森林算法,它是比使用单个决策树效果更好的示例算法。
如果我们有一个训练集大小为m,我们将使用带放回抽样,创建一个大小为M的新训练集(有些是重复的没有关系)。
然后在新的数据集上训练决策树,这样我们就会得到一个决策树。
然后在使用带放回抽样来生成另一个训练集M,在这个新的数据集上训练决策树,我们会得到另一个决策树。
以此类推,构建出多个决策树(B个,在64-228左右),比如说我们构建了100棵不同的树组成的集合,然后当你试图做出预测时,让这些树共同决定预测结果。事实证明,当训练的决策树太多时,远大于100,它实际上不会取得更好的效果,反而会减慢计算速度,而不会显著提高整体算法。
对于以上的方法,实际上做一点修改,它会工作的更好,也就是将这个算法从反向决策树更改为随机森林算法。
关键思想是,即使我们使用这种带有替换过程的采样,有时我们最终也会在根节点处使用同样的特征进行拆分,在根节点处的分裂也是十分相似的。
对这个算法进行更改,尝试随机化每个节点处的特征选择,这可能导致树集合预测的更准确。
具体做法就是:如果我们有n个特征可以选择,我们会创建一个含有k个特征的随机子集。
当我们在节点要选择特征进行拆分时,我们会在子集k中随机选择一个信息增益最高的特征进行拆分。
如果n很大时,几十或几百时,k值一般会取n的平方根。
除了随机森林,还有另一种效果更好的算法,它是一个增强的决策树,一种XG boost 增强决策树的算法。
到目前为止,决策树集成或决策树最常用的方式是一张名为XGBoost的方法,它运行速度快、开源、容易使用,来看看XGBoost是如何运行的。
前面学了反向决策树算法的修改,随机森林,它可以使其工作更好。
这里是我们之前的,给定训练集来调整它们的大小,重复B次。
使用有放回抽样来创建一个大小为M的新训练集,然后在新的训练集上训练决策树。
第一次通过这个循环,我们可以创建一个训练集并训练一个决策树,如图。
我们将查看我们训练出来的决策树,找到那些还可以改进的示例,然后在构建下一个决策树时,我们将更多的关注我们可以做的更好的示例。
不是查看所有训练示例,而是集中在尚未表现良好的示例子集上,并获得新的决策树。
争取在下一个决策树上做得很好,这就是boosting的思路。
如图,当构建了一个决策树后,我们返回到原始数据集,查看所有的10个示例,看看预测结果的准确性。
然后我们会通过有放回抽样来生成另一个包含10个示例的新训练集。
注意,每次我们从这10个例子中挑选一个例子时,都会有更高的机会从 上一个决策树预测错误的的例子中挑选一个。
要想实现这个,我们需要通过一个过程,比如刻意学习,将第二个决策树的注意力集中在还可以做的更好的例子上。
并且提升过程将在每次迭代中 总共执行B次,我们就会得到一个树集合。
xgboost算法是一种boosting的集成学习算法,是将多个弱学习模型进行组合,从而获得更好的效果,使得组合后的模型有更强的泛化能力。
目前使用最广泛的一种实现提升的方法就是XGBoost ,代表极端梯度提升,它是一个开源算法,非常快速和高效,而且有一个很好的选择默认拆分标准和何时停止拆分的标准。
这就是XGBoost算法的使用,左边left是分类问题,右边right是回归问题。
决策树、树集合与神经网络是非常强大、非常有效的学习算法。
决策树或树集合通常用于表格数据,也称为结构化数据。像房价预测,有房子大小、房间数等多个特征。
决策树或树集合一个优点是它们的训练数据非常快。
神经网络可以处理非结构化数据任务,像图像、视频、音频和文本等。
小型决策树可能是我们可以解释的,可以了解它是如何做出决策的。
如果我们决定使用决策树或树集合,那就有很大可能使用XGBoost 算法来处理大多数应用程序。
对于神经网络,与决策树和树集合相比较,它适用于所有类型的数据,包括表格或结构化数据以及非结构化数据,包括结构化和非结构化组件的混合数据也可以处理。
神经网络通常用于处理非结构化数据任务,像图像、视频、音频和文本等。
对于表格结构化数据,神经网络和决策树都可以解决,而在非结构化数据任务,像图像、视频、音频和文本等问题中,神经网络还是首选。
缺点是神经网络可能比决策树慢。
优点是神经网络可以和迁移学习一起使用,这点非常重要,因为对于许多应用程序,我们只有一小部分数据集,可以使用迁移学习并进行预训练一个更大的数据集。
可以将多个神经网络串联起来,构建一个更大的机器学习系统。因为神经网络输入x后 将输出y计算为平滑或连续的函数,即使我们有很多不同的模型,都可以使用梯度下降同时训练它们。对于决策树,一次只能训练一颗决策树。
如果我们正在构建一个由多个机器学习模型协同工作的系统,串联起来训练多个神经网络可能更容易,而不是使用决策树。
本文从决策树出发,第一部分讲解了什么是决策树模型,了解了一些决策树的基本概念;第二部分提到了如何确定在决策树节点使用什么特征,其中介绍了熵的概念、什么是信息增益,以及如何使用信息增益去构建决策树;第三部分讲到了独热编码,以及在决策树中的应用;第四部分讲了如何使用决策树解决回归问题;第五部分介绍了如何使用多个决策树,其中提到了有放回抽样、随机森林算法、xgboost算法;第六部分重点讲了什么时候去使用决策树,讲决策树与神经网络做了个比较。