原创:程祥国
XGBoost是陈天奇提出的一个端对端的梯度提升树系统,该算法在GBDT【关于GBDT这里不再展开叙述,可以参考李航老师统计学习方法一书中对该算法的讲述】的基础之上,在算法层面和系统设计层面都做了一些创新性的改进,可以把XGBoost看作是GBDT更好更快的实现。XGBoost在许多机器学习以及数据挖掘的任务中表现惊艳,2015年,kaggle竞赛平台上发布了29个挑战获胜的解决方案,其中17个解决方案用了XGBoost。由于XGBoost在实际任务中的良好表现,因此搞清XGBoost的实现细节对于在实践中应用XGBoost是非常有帮助的。因此本文基于陈天奇的论文XGBoost: A Scalable Tree Boosting System,详细阐述XGBoost的各种细节。
上述我们提到XGBoost在算法层面和系统设计层面都做了一些创新性的改进,我们首先将XGBoost的创新做一个总结:
(1)在GBDT目标函数的基础上,在对优化目标求解的时候使用了二阶导数的信息,因此会使优化目标的定义更加精确,训练速度会更快;此外,XGBoost在优化目标函数中加入了正则项,这会限制模型的复杂度,防止过拟合的发生。
(2)提出了一种处理缺失值的算法,XGBoost能够自动对缺失值进行处理
(3)在树生成选择特征划分节点的时候,通过加权分位数草图算法,预先对每个特征建立候选的划分节点,不在使用原先的贪婪算法(遍历每个特征所有取值),从而大大加快训练速度
(1)对训练的每个特征排序并且以块(block)的结构存储在内存中,方便后续训练迭代重复使用,减少计算量。对于不同的特征的特征划分点,XGBoost分别在不同的线程中并行选择分裂的最大增益,从而实现了并行训练。
(2)提出了一种有效的缓存感知块结构用于树模型的核外学习
下面我们将分别对上述5项进行分析。
假设数据集D有n个样本m个特征:,树集成算法使用加法模型对K个基学习器进行合成,作为最终的预测输出。如图1所示。

为了使上述预测的结果尽可能的接近实际值,我们首先定义模型的优化目标函数,优化目标函数如下所示:
这里是一个可微的凸损失函数,它表示预测
和目标
之间的差值。T是每棵树叶子的数量,
表示模型对叶子节点的预测数值。第二项
是惩罚项,限制回归树模型的复杂度。正则化项有助于使最终学习到的权值更加平滑,避免过拟合。直观地说,带有正则化的目标函数倾向于选择简单的预测模型。当第
颗树生成的时候,我们可以将公式1.1变成如下形式:
在公式1.3中,是前
颗树对样本
的预测值,
是第
颗树对样本
的预测值,
是第
棵树叶子节点的个数,
是第
颗树第
个叶子节点的数值,而我们模型的学习目标就是最小化公式1.3的数值,从而得到第t颗树:最优的所有
个叶子节点区域和每个叶子节点区域的最优解
。在此处,我们使用泰勒公式展开,来对公式1.3中的第一项进行二阶导数展开,展开后公式1.3变为如下:
在公式1.4中,,
,公式1.4中
是一个常量,因此对我们的优化目标没有影响,我们可以将该项删掉,此外为了便于公式1.4中第一项和第三项的合并,我们将公式1.4转换为以叶子节点
作为累加,可将上式转换为如下形式:
在公式1.5中,,
;公式1.5可以看作是一个关于
的一元二次函数,当第
颗树的结构已知时,我们能够计算出公式1.5的最小值在
,时取得,当我们的
取得最优值的时候,公式1.5可以转换为如下形式:
当我们在生成棵树的时候,每次选择划分节点的时候,我们都希望公式1.6的数值能够减少的更多一些,假设当前节点左右子树的一阶二阶导数和为
,
,
,
则我们期望最大化下式:
公式1.7就是我们在生成第颗树的时候,用来选择最优划分节点的标准。
至此我们完成了XGBoost优化目标函数的推导,基于此我们可以简单总结一下XGBoost的核心流程(此处暂不涉及缺失值处理以及分位数缩略草图等细节):当我们在学习一颗新树的时候,我们通过对每个特征每个特征值作为划分节点计算公式1.7的数值,每个节点的划分我们都选择使公式1.7取值最大的那个特征的特征值,不断分裂节点,直至公式1.7的最大取值小于0,则我们的新树就生成好了。
缺失值在实际的工作数据中是经常会遇到的,传统的许多算法都需要对缺失值进行预处理:比如使用各种方法进行缺失值的填充,而XGBoost能够自动的处理缺失值,在每颗树生成的时候,在选择以哪一个特征哪一个特征值作为划分节点时,会使用没有缺失值的样本对每个特征的特征值进行排序,然后遍历的对每个特征每个特征值作为划分节点,会自动的将缺失值样本,分别放在左叶子节点和右叶子节点,然后分别计算缺失值样本在左叶子节点和右叶子节点哪一个情况公式1.7的减少的大【因为要涉及到将缺失值的样本分别划到左叶子节点和右叶子节点,相当于计算公式1.7减少的算法流程要进行两次】,就选择哪一个特征的哪一个特征值作为最佳的划分节点。算法的详细情况如图2所述【原始论文中的流程是分别从小到大和从大到小对特征进行排序,然后分别将特征值样本划分到右叶子节点和左叶子节点,这样看起来会有点绕,实质就是我们传统的将特征值从小到大排序以后,遍历以所有特征值作为划分节点,第一轮计算是将缺失值样本划分为左叶子节点,第二轮计算就是将缺失值样本划分为右叶子节点】。

我们在2.1小节探讨分析了每棵树生成时候的核心流程,在每棵树生成的时候,最消耗时间的就是我们划分节点的选取,使用贪心算法遍历所有特征所有可能的候选值会消耗大量的时间,因此XGBoost提出了一种近似算法以及相应的加权分位数草图算法,近似算法的核心思想是:对每个特征不在遍历所有的特征值,而是将特征按照一定的规则找到几个关键的百分位数节点,这个规则就是加权分位数草图算法,加权分位数草图算法的流程及证明过程较复杂,在这里我们不在展开分析,该算法的详细流程以及证明过程可以参见论文附录【XGBoost: A Scalable Tree Boosting System】。
传统的GBDT在每颗树生成的时候,无法进行并行计算,而XGBoost实现了并行计算,这里的并行计算是指在生成每棵树的时候能够并行计算所有特征的划分节点。XGBoost中将排好序的数据存储在内存单元中,称之为block。每个block中的数据根据每列特征取值排序,并以压缩列(CSC)格式储存。这种输入数据布局只需要在训练前计算一次,可以在后续迭代中重复使用。
在贪婪算法中【选择最佳划分节点时,遍历所有特征所有可能的值】,我们将整个数据集存储在单个block中,并通过对预排序的数据进行线性扫描来实现分割点搜索。这样只需扫描一次block就可以得到所有特征所有候选分裂节点的统计信息。下图显示了如何将数据集转换成相应格式并使用block结构找到最优分割。

当使用近似算法【选择最佳划分节点时,只计算每个特征预先选取的几个百分位处的特征值】时,block结构也非常有用。在这种情况下,可以使用多个block,也可以实现并行计算。
XGBoost系统的一个目标是充分利用机器的资源来实现可扩展的学习。 除处理器和内存外,利用磁盘空间处理不适合主内存的数据也很重要。为了实现核外计算,我们将数据分成多个块并将每个块存储在磁盘上。在计算过程中,使用独立的线程将块预取到主存储器缓冲区是非常重要的,因为计算可以因此在磁盘读取的情况下进行。但是,这并不能完全解决问题,因为磁盘读取会占用了大量计算时间。减少开销并增加磁盘IO的吞吐量非常重要。 我们主要使用两种技术来改进核外计算。
Block Compression 我们使用的第一种技术是块压缩。该块从列方向压缩,并在加载到主存储器时通过独立的线程进行解压。这可以利用解压过程中的一些计算与磁盘读取成本进行交换。我们使用通用的压缩算法来压缩特征值。对于行索引,我们通过块的起始索引开始减去行索引,并使用16位整型来存储每个偏移量。这要求每个块有个样本,这也被证实是一个好的设置。在我们测试的大多数数据集中,我们实现了大约26%到29%的压缩率。
Block Sharding 第二种技术是以另一种方式将数据分成多个磁盘。为每个磁盘分配一个实现预取的线程,并将数据提取到内存缓冲区中。然后,训练线程交替地从每个缓冲区读取数据。当有多个磁盘可用时,这有助于提高磁盘读取的吞吐量。
至此,我们已经对XGBoost的主要内容进行了分析讨论,通过上述分析我们能够看到XGBoost在许多方面都进行了创新改进,这也是XGBoost在实际工作中表现优异的原因:在算法层面更精确的定义了优化目标函数,使得学习的目标更加准确;稀疏感知算法使得算法能够处理缺失值,从而使算法的稳健性更强大;加权分位数草图算法减少了候选划分节点的数量,从而提高了算法的运行效率;在系统设计层面,block结构实现了选择候选划分节点时的并行计算,从而大大提高了运行效率。
1、XGBoost: A Scalable Tree Boosting System—陈天奇
2、XGBoost算法原理小结—刘建平
3、XGBoost原论文阅读翻译—了不起的赵队
一、什么是MQTT协议MessageQueuingTelemetryTransport:消息队列遥测传输协议。是一种基于客户端-服务端的发布/订阅模式。与HTTP一样,基于TCP/IP协议之上的通讯协议,提供有序、无损、双向连接,由IBM(蓝色巨人)发布。原理:(1)MQTT协议身份和消息格式有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。MQTT传输的消息分为:主题(Topic)和负载(payload)两部分Topic,可以理解为消息的类型,订阅者订阅(Su
TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是
开门见山|拉取镜像dockerpullelasticsearch:7.16.1|配置存放的目录#存放配置文件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/config#存放数据的文件夹mkdir-p/opt/docker/elasticsearch/node-1/data#存放运行日志的文件夹mkdir-p/opt/docker/elasticsearch/node-1/log#存放IK分词插件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/plugins若你使用了moba,直接右键新建即可如上图所示依次类推创建
文章目录概念索引相关操作创建索引更新副本查看索引删除索引索引的打开与关闭收缩索引索引别名查询索引别名文档相关操作新建文档查询文档更新文档删除文档映射相关操作查询文档映射创建静态映射创建索引并添加映射概念es中有三个概念要清楚,分别为索引、映射和文档(不用死记硬背,大概有个印象就可以)索引可理解为MySQL数据库;映射可理解为MySQL的表结构;文档可理解为MySQL表中的每行数据静态映射和动态映射上面已经介绍了,映射可理解为MySQL的表结构,在MySQL中,向表中插入数据是需要先创建表结构的;但在es中不必这样,可以直接插入文档,es可以根据插入的文档(数据),动态的创建映射(表结构),这就
HTTP缓存是指浏览器或者代理服务器将已经请求过的资源保存到本地,以便下次请求时能够直接从缓存中获取资源,从而减少网络请求次数,提高网页的加载速度和用户体验。缓存分为强缓存和协商缓存两种模式。一.强缓存强缓存是指浏览器直接从本地缓存中获取资源,而不需要向web服务器发出网络请求。这是因为浏览器在第一次请求资源时,服务器会在响应头中添加相关缓存的响应头,以表明该资源的缓存策略。常见的强缓存响应头如下所述:Cache-ControlCache-Control响应头是用于控制强制缓存和协商缓存的缓存策略。该响应头中的指令如下:max-age:指定该资源在本地缓存的最长有效时间,以秒为单位。例如:Ca
如何用IDEA2022创建并初始化一个SpringBoot项目?目录如何用IDEA2022创建并初始化一个SpringBoot项目?0. 环境说明1. 创建SpringBoot项目 2.编写初始化代码0. 环境说明IDEA2022.3.1JDK1.8SpringBoot1. 创建SpringBoot项目 打开IDEA,选择NewProject创建项目。 填写项目名称、项目构建方式、jdk版本,按需要修改项目文件路径等信息。 选择springboot版本以及需要的包,此处只选择了springweb。 此处需特别注意,若你使用的是jdk1
前言上一篇我们简要讲述了粒子系统是什么,如何添加,以及基本模块的介绍,以及对于曲线和颜色编辑器的讲解。从本篇开始,我们将按照模块结构讲解下去,本篇主要讲粒子系统的主模块,该模块主要是控制粒子的初始状态和全局属性的,以下是关于该模块的介绍,请大家指正。目录前言本系列提要一、粒子系统主模块1.阅读前注意事项2.参考图3.参数讲解DurationLoopingPrewarmStartDelayStartLifetimeStartSpeed3DStartSizeStartSize3DStartRotationStartRotationFlipRotationStartColorGravityModif
VMware虚拟机与本地主机进行磁盘共享前提虚拟机版本为Windows10(专业版,不是可能有问题)本地主机为家庭版或学生版(此版本会有问题,但有替代方式)最好是专业版VMware操作1.关闭防火墙,全部关闭。2.打开电脑属性3.点击共享-》高级共享-》权限4.如果没有everyone,就添加权限选择完全控制,然后应用确定。5.打开cmd输入lusrmgr.msc(只有专业版可以打开)如果不是专业版,可以跳过这一步。点击用户-》administrator密码要复杂密码,否则不行。推荐admaiN@1234类型的密码。设置完密码,点击属性,将禁用解开。6.如果虚拟机的windows不是专业版,可
IK分词器本文分为简介、安装、使用三个角度进行讲解。简介倒排索引众所周知,ES是一个及其强大的搜索引擎,那么它为什么搜索效率极高呢,当然和他的存储方式脱离不了关系,ES采取的是倒排索引,就是反向索引;常见索引结构几乎都是通过key找value,例如Map;倒排索引的优势就是有效利用Value,将多个含有相同Value的值存储至同一位置。分词器为了配合倒排索引,分词器也就诞生了,只有合理的利用Value,才会让倒排索引更加高效,如果一整个Value不进行任何操作直接进行存储,那么Value和key毫无区别。分词器Analyzer通常会对Value进行操作:一、字符过滤,过滤掉html标签;二、分
题外话:抑郁场,开局一小时只出A,死活想不来B,最后因为D题出锅ura才保住可怜的分。但咱本来就写不到DB-LongLegs(数论)本题题解法一学自同样抑郁的知乎作者幽血魅影的题解,有讲解原理。法二来着知乎巨佬cup-pyy(大佬说《不难发现》呜呜)题意三种操作:向上走mmm步向右走mmm步给自己一次走的步数加111,即使得m=m+1m=m+1m=m+1问从(0,0)(0,0)(0,0)走到(a,b)(a,b)(a,b)的最小操作次数,值得注意的是操作三不可逆。解析假设我们最终一步的大小增长到mmm,那么在这个过程中我能以[1,m][1,m][1,m](当步数增长到该数时)之间的任何数字向上或