前言:XGBoost原理上跟普通GBDT一样,都属于集成算法中的boost类。boost的原理可以看我的另外两篇介绍集成学习的文章,这里不多赘述。所以这篇文章主要在XGB与普通GBDT不同之处进行讨论。
1.损失函数
XGB的损失函数是支持自定义的,只要满足二阶可导即可。
XGB的损失函数除了拟合上一轮残差部分,还自带了两个损失项以减少树模型复杂度:
先讨论简单的,正则化部分:
系数:这里的γ和λ,你可以设定它们的值,显然,γ越大,表示越希望获得结构简单的树,因为此时对较多叶子节点的树的惩罚越大。λ越大也是越希望获得结构简单的树。
惩罚内容:是该轮构建树的叶子结点树,标识该结点上的值(值指的是回归树,分类树上则对应类别)。我理解的意义在于,建立新树过程中,不希望有某个分支突然学到“真理”,学习应该是循序渐进的,突然学得那么“精确”容易过拟合。比如一男子,50岁,第一个叶节点根据性别就猜对了男子50岁,后面都没有残差了,这显然不够科学。所以需要加入此正则化部分,1是可以使模型趋于简单,2可以避免过拟合。
再看头疼一点的,误差函数项,
为了好理解,先以平方误差(MSE)为例,和都是已知项,上式可以转化为:
这个函数,是不是熟悉多了?因为和都是已知项,所以这就是一个优雅的二次函数了,为什么说二次函数比较优雅,后面会提到。但是很多情况下,损失函数并不是平方误差这么简单,那就用泰勒展开,只保留到二次项。泰勒公式就不细说了(反正我也说不通...),泰勒展开后,上式会变成这样:
其中:
忽略损失函数中的第一个自变量(别忘了上面说的“在第t步,是真实值,即已知”,不影响后续目标函数对的偏导计算),做下一一对应:
● 泰勒二阶展开f 里的x对应目标函数里的
● f 里的对应目标函数的
● 从而f 对x求导数时,对应为目标函数对求偏导
这里有必要再明确一下,和的含义。怎么理解呢?现有t-1棵树是不是?这t-1棵树组成的模型对第i个训练样本有一个预测值是不是?这个与第i个样本的真实标签肯定有差距是不是?这个差距可以用这个损失函数来衡量是不是?现在和的含义已经清楚了,而且,更重要的是,和与当前要建立的树无关啊,可以分布运行啊,所以速度快啊。所以,上面的式子还可以进一步简化为(把常数项去掉)
这时,目标函数只依赖于每个数据点在误差函数上的一阶导数和二阶导数。
记住这个式子,再看其中的,虽然知道它是个什么东西,但是总觉得怪怪的是不是,怎么去得到这个呢?
下面是决策树的另一种表达方式:
式中:表示某个叶子结点上的值则是一种映射关系,表示把映射到哪个叶子结点上,这样一来,我们上面的损失函数就又可以表示成:
直接把,从样本遍历转化为从叶子结点遍历了有没有?这个公式还是有点难懂,那么如果我们再变换一下呢?
这个公式,问你怎么求使得损失函数最小?当然是 啊!(初中二次函数知识)
这个表示一个树的结构的好坏,只与树结构有关系。下面这张图,相信大家都在各种介绍XGB的文章里见到过,这里不多做介绍,只是辅助理解。
2.寻找最优的结构
以判断一个人是否喜欢计算机游戏为例子。最简单的树结构就是一个节点的树。我们可以算出这棵单节点的树的好坏程度obj*。假设我们现在想按照年龄将这棵单节点树进行分叉,我们需要知道:
1、按照年龄分是否有效,也就是是否减少了obj的值
2、如果可分,那么以哪个年龄值来分。
为了回答上面两个问题,我们可以将这一家五口人按照年龄做个排序。如下图所示:
从左向右遍历每个年龄,可以得到两个区域,然后计算:
这个就类似于信息增益,增益越大,那么就越小,而这个是控制每次分裂的增益最小值的,如果增益小于,就不切分。对每个节点递归得调用这个方法,就可以得到一个新的树。
3.特点
Xgboost可以有效地防止过拟合并且各种支持分布式/并行,所以一般传言这种大杀器效果好(集成学习的高配)+训练效率高(分布式),与深度学习相比,对样本量和特征数据类型要求没那么苛刻,适用范围广。而且具有深度学习没有的一些特性比如模型的可解释性、输入数据的不变性、更易于调参等。
4.应用场景
XGBoost以其较高的准确率,又可以局部分布式训练,可以说能用GBDT的都可以用XGBoost来试试,训练得比较快,时间省下来多调调参也是好的。
5.调参实践
https://github.com/zzzzzzhang/Datawhale_learn/blob/master/XGBoost_cloud.py
参考
【1】http://www.julyedu.com/question/big/kp_id/23/ques_id/2590
【2】https://blog.csdn.net/github_38414650/article/details/76061893
【3】https://blog.csdn.net/qq_34562093/article/details/78880975