热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

机器学习总结(一)Adaboost,GBDT和XGboost算法

一:提升方法概述提升方法是一种常用的统计学习方法,其实就是将多个弱学习器提升(boost)为一个强学习器的算法。其工作机制是通过一个弱学习算法,从初始训练集中训练出一个弱学习器,再根据弱学习器的

一: 提升方法概述

提升方法是一种常用的统计学习方法,其实就是将多个弱学习器提升(boost)为一个强学习器的算法。其工作机制是通过一个弱学习算法,从初始训练集中训练出一个弱学习器,再根据弱学习器的表现对训练样本分布进行调整,使得先前弱学习器做错的训练样本在后续受到更多的关注,然后基于调整后的样本分布来训练下一个弱学习器。如此反复学习 ,得到一系列的弱学习器,然后 组合这些弱学习器,构成一个强学习器。提升方法生成的弱学习器之间存在强依赖关系,必须串行生成一系列的弱学习器。目前提升方法主要有 AdaBoost,GBDT,XGBoost等算法。而通常我们所知的Bagging,随机森林等算法生成的弱学习器之间不存在强依赖关系,可同时生成并行化的方法。

二: 提升方法AdaBoot算法

通常对提升方法来说,有两个问题需要回答:一是如何在每一轮改变训练样本的分布,二是如何将弱分类器组合成一个强分类器。

对于第一个问题,AdaBoost算法的做法是提高被前一轮弱分类器错误分类样本的权值,而降低被正确分类样本的权值。这样,没有得到正确分类的数据由于权值被加大而受到后轮的弱分类器更大关注。

对于第二个问题,AdaBoost算法的做法是AdaBoosting采取 加权多数表决的方法。具体就是加大分类误差小的弱分类器的权值,使其在表决中起较大的作用,减小分类误差率大的弱分类器的权值。

 AdaBoost算法的具体步骤(该步骤主要是基于模型为加法模型,损失函数为指数函数):

给定一个二类分类的训练数据集,每个样本点由实例xi与标记yi y={-1,1}组成,样本数为N 

目标从训练数据中学习一系列弱分类器,然后将这些弱分类器Gm(x)组合成一个强分类器G(x)。

(1)初始化训练数据的权值分布

(2)对于第m=1,2,..M轮迭代

(a)使用具有权值分布的Dm的训练数据集学习,得到基本分类器

(b)计算基分类器Gm(x)在训练数据集上的分类误差

这里wmi表示第m轮中第i个实例的权值,Gm(x)在加权的训练集上的分类误差是被Gm(x)误分类的样本的权值和,由此可看出基分类器Gm(x)的分类误差与权值分布Dm关系

(c)计算Gm(x)基分类的系数即基分类器的权值,log为自然对数

可知当em<=1/2时,αm>0,且分类误差率em越小的弱分类器,其权值αm越大。所以分类误差率越小的弱分类器在最终分类器中的作用越大。

(d)更新训练数据集的权值分布

其中,Zm为规范化因子,意思就是让Dm+1是被正确定义的 概率

权值分布更新也可表达成如下形式:

由此可知,下一轮训练时正确分类的样本的权值得以缩小,而被误分类的样本的权值得以扩大。因此误分类的样本在下一轮中起更大的作用,不改变所给的训练数据,而不断的改变训练数据的权值分布,使得训练数据在弱分类器的学习过程中起不同的作用。

(3)构建弱分类器的线性组合:步骤2完成后得到M(m=1,2,…M)个弱分类器Gm(x):

得到最终的强分类器:

线性组合f(x)实现了 M个基本分类器的加权表决。系数αm表示基本分类器Gm(x)的重要性,系数之和并 不 为1。f(x)的符号决定了实例x的类别,f(x)的绝对值表示分类的确信度。

三:GBDT(梯度提升树)算法

提升树:是一种以分类树或者回归树作为基本分类器的算法。提升树一般采用加法模型,即基函数的线性组合与前向分步算法。对分类问题决策树是二叉分类树,对回归问题决策树是二叉回归树。提升树模型可表示为决策树的加法模型:

 

表示为第m棵决策树,表示为第m决策树参数,M表示树的棵数。

提升树算法采用前向分步算法,第m步的模型是

其中fm-1(x)为当前树,损失函数如下:

 

即通过迭代,第m棵决策树使得L(fm(x),y)的损失最小化。

对于损失函数,回归问题用平方误差损失函数,分类问题用指数损失,一般决策问题用一般损失函数。

GBDT梯度提升树:

对于提升树,当损失函数是平方误差损失函数和指数损失函数时,每一步优化比较简单,但是对于一般损失函数,往往每一步优化没那么容易。

通常优化损失函数,是希望损失函数能够不断的减小,而且是损失函数能够尽可能快的减小。而梯度提升算法针对这问题 ,让损失函数沿着梯度方向最速下降的方法,关键是利用损失函数的负梯度在当前模型的值:

作为回归问题提升树算法中残差的近似值。其中为当前模型。gbdt 每轮迭代的时候,都去拟合损失函数在当前模型下的负梯度。这样每轮训练的时候都能够让损失函数尽可能快的减小,尽快的收敛达到局部最优解或者全局最优解。

GBDT的算法如下:

 (1)首先计算损失函数在当前模型Fm&#x2212;1(x)">Fm1(x)的负梯度值:

 (2)根据y&#x007E;i">yi学习得到了第m">m棵回归树,对应的叶节点区域为am

y&#x007E;i">m">{Rj}1J"> (3)在叶结点区域上求得损失最小化的pm

y&#x007E;i"> (4)得到最终模型

四:XGBoost算法

XGBoost(eXtreme Gradient Boosting)也是一种梯度提升树算法

1:XGboost的损失函数推导

XGboost的基分类器为分类和回归树(CART)

CART会把输入根据输入的属性分配到各个叶子节点,而每个叶子节点上面都会对应一个实数分数。得到一个实数分数有很多好处,如可以做概率预测,排序。

一颗树往往过于简单,所以将多棵树集成在一起。如下图,用两棵树来进行预测。我们对于每个样本的预测结果就是每棵树预测分数的和。

 XGboost 的Tree Ensemble 模型以及损失目标函数为:

假设Model中有K棵树,根据损失函数和正则化构造一个目标函数,然后我们要做的就是去尝试优化这个目标函数。目标函数的左边为经验损失误差,右侧为正则化项,目标是降低模型的复杂度。这里目标函数优化的是整体的模型,yi^是整个累加模型的输出,正则化项是所有树的复杂度之和(k棵树的复杂度之和)。

 

对于yi^ 采用前向 分布算法和加法模型,跟boosting的学习策略一样,每次学习当前的树,找到当前最佳的树模型加入到整体模型中,因此关键在于学习第t棵树。

在第t轮也就是学习第t棵树时,目标就是第t棵树的加入能够使得整个模型的误差损失最小。

 

所以如上,即优化目标 Objt,yi^(t-1)为常量,前t-1棵树的复杂度为常量,用constant表示。Ω(ft)为第t棵树的正则化项,ft为第t棵树的复杂度。如果损失函数为平方损失,那么跟回归问题提升树一样,只需要拟合当前模型的残差就可以得到第t棵树。

倘若损失函数不是平方损失,我们可以用GBDT算法,利用损失函数的负梯度在当前模型的值来近似残差。在GBDT中只需对当前模型求一阶导。

而XGBoost的思想是对误差函数进行二阶展开,保留二次项。与GBDT相比,多了计算损失函数的二阶梯度这一项系数。

于是省略掉一些常数项后,可得到新的损失目标函数

目标函数保留的泰勒展开的二次项。在这个目标函数里需要优化gi和hi。得到这个目标函数有啥意义?

2:重新定义每棵树的复杂度

把树拆分成结构部分q叶子权重部分w。下图是一个具体的例子。结构函数q把输入映射到叶子的索引号上面去,而w给定了每个索引号对应的叶子分数是什么。如wq(x)是该节点的打分,即该样本的模型预测值 。

定义这个复杂度包含了一棵树里面节点的个数,以及每个树叶子节点上面输出分数的L2模平方。当然这不是唯一的一种定义方式,不过这一定义方式学习出的树效果一般都比较不错。

在这种新的定义下,我们可以把目标函数进行如下改写,其中I被定义为每个叶子上面样本集合

在这一目标函数中,加了两个正则项,一个是叶子结点个数的正则项,一个是叶节点分数的正则项。所以目标函数里出现了两种累加,一种是叶子节点中样本个数的累加,一种是叶子节点个数的累加

从目标函数看出,包含了两个相互独立的单变量二次函数,令

目标函数可化简为

 

对目标函数的wj进行求导得:

然后把最优解代入得到:

Obj代表了当一棵树的结构(叶节点个数)是确定的时候,目标函数的分数越小即结构分数(structure score),结构越好。

切分点的查找采用贪心算法:遍历每一个已有的叶子,并尝试去分割,在分割后,目标函数的变化如下:

分割后,可以观察到,不仅是结构分数发生了变化,叶节点的的复杂度也有变化.优化这个目标对应了树的剪枝, 当引入的分割带来的增益小于一个阀值的时候,我们可以剪掉这个分割。

 XGBOOST的算法流程如下:

 

五 :总结

(一):Adaboost与GBDT算法

Adaboost算法的模型是一个弱学习器线性组合,特点是通过迭代,每一轮学习一个弱学习器,在每次迭代中,提高那些被前一轮分类器错误分类的数据的权值,降低正确分类的数据的权值。最后,将弱分类器的线性组合作为强分类器,给分类误差小的基本分类器大的权值。每一次迭代都可以减少在训练集上的分类误差率。

AdaBoost能够有效的降低偏差,能够在泛化性能非常弱的学习器上构建成很强的集成。缺点是对噪声敏感。

GBDT与Adaboost的主要差别为,Adaboost每轮学习的一个基本学习器是通过改变样本的权值,关注上轮分类错误的样本的权值,以逐步减少在训练集上的分类误差率。而GBDT每轮学习一个基本学习器是通过改变输出值,每轮拟合的值为真实值与已有的加法模型的差值(即残差)。GBDT无论是进行分类还是回归问题,都用的CART树。对于分类问题用二叉分类树,回归问题用二叉回归树。 

(二):GBDT与XGboost

1:传统GBDT在优化时只用到一阶导数信息,xgboost则对代价函数进行了二阶泰勒展开,同时用到了一阶和二阶导数。xgboost工具支持自定义代价函数,只要函数可一阶和二阶求导。

2:Xgboost在代价函数里加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、每个叶子节点上输出的score的L2模的平方和。从Bias-variance tradeoff角度来讲,正则项降低了模型variance,使学习出来的模型更加简单,防止过拟合,这也是xgboost优于传统GBDT的一个特性。正则化包括了两个部分,都是为了防止过拟合,剪枝是都有的,叶子结点输出L2平滑是新增的。还可以进行列抽样,从而降低过拟合的风险。

3:XGboost可进行并行计算,但是这种并行计算并不是像随机森林那样是在tree粒度上去进行,而是在特征粒度上并行。


(三):

Boosting算法的基学习器之间都存在强的依赖关系,必须串行的生成序列化的方法。训练过程关注偏差的降低。

 


推荐阅读
  • 编译原理中的语法分析方法探讨
    本文探讨了在编译原理课程中遇到的复杂文法问题,特别是当使用SLR(1)文法时遇到的多重规约与移进冲突。文章讨论了可能的解决策略,包括递归下降解析、运算符优先级解析等,并提供了相关示例。 ... [详细]
  • 深入解析层次聚类算法
    本文详细介绍了层次聚类算法的基本原理,包括其通过构建层次结构来分类样本的特点,以及自底向上(凝聚)和自顶向下(分裂)两种主要的聚类策略。文章还探讨了不同距离度量方法对聚类效果的影响,并提供了具体的参数设置指导。 ... [详细]
  • 计算机学报精选论文概览(2020-2022)
    本文汇总了2020年至2022年间《计算机学报》上发表的若干重要论文,旨在为即将投稿的研究者提供参考。 ... [详细]
  • 本打算教一步步实现koa-router,因为要解释的太多了,所以先简化成mini版本,从实现部分功能到阅读源码,希望能让你好理解一些。希望你之前有读过koa源码,没有的话,给你链接 ... [详细]
  • 最近遇到了一道关于哈夫曼树的编程题目,需要在下午之前完成。题目要求设计一个哈夫曼编码和解码系统,能够反复显示和处理多个项目,直到用户选择退出。希望各位大神能够提供帮助。 ... [详细]
  • 第14周实践项目(4)-验证平衡二叉树
    问题**Copyright(c)2015,烟台大学计算机学院*Allrightsreserved.*文件名称:test.cpp*作者:王敏*完成日 ... [详细]
  • 本文整理了一份基础的嵌入式Linux工程师笔试题,涵盖填空题、编程题和简答题,旨在帮助考生更好地准备考试。 ... [详细]
  • 网络流24题——试题库问题
    题目描述:假设一个试题库中有n道试题。每道试题都标明了所属类别。同一道题可能有多个类别属性。现要从题库中抽取m道题组成试卷。并要求试卷包含指定类型的试题。试设计一个满足要求的组卷算 ... [详细]
  • 本文介绍了如何利用OpenCV库进行图像的边缘检测,并通过Canny算法提取图像中的边缘。随后,文章详细说明了如何识别图像中的特定形状(如矩形),并应用四点变换技术对目标区域进行透视校正。 ... [详细]
  • 机器学习实践:逻辑回归与过拟合控制
    本文深入探讨了逻辑回归在机器学习中的应用,并详细解释了如何通过正则化等方法来有效避免模型的过拟合问题。 ... [详细]
  • 二叉搜索树转换为排序双向链表的面试题解析
    本文探讨了一道经典的面试问题,即将给定的一棵二叉搜索树转换为一个排序的双向链表,过程中不允许创建新节点,仅能通过调整现有节点的指针来实现转换。 ... [详细]
  • 线段树详解与实现
    本文详细介绍了线段树的基本概念及其在编程竞赛中的应用,并提供了一个具体的线段树实现代码示例。 ... [详细]
  • 开发笔记:树的浅析与实现 ... [详细]
  • 本文详细介绍了MySQL故障排除工具及其使用方法,帮助开发者和数据库管理员高效地定位和解决数据库性能问题。 ... [详细]
  • 【转】强大的矩阵奇异值分解(SVD)及其应用
    在工程实践中,经常要对大矩阵进行计算,除了使用分布式处理方法以外,就是通过理论方法,对矩阵降维。一下文章,我在 ... [详细]
author-avatar
芸阁__907
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有