xgboost 一般多少棵树_通俗易懂XGBoost原理及计算公式

对于xgboost的理解一直处在半知不解的情况,知道这个东西,大致知道这个原理;

但是让自己说一遍的它的原理的时候,发现根本说不出什么:它就是一个一棵树,用boost的方式串行,让模型上下相关联,关联的方式是用残差。

那具体是怎么构建这棵树的呢?怎么通过残差进行上下关联?怎么计算目标函数的?

带着这个问题查了资料,看到了一篇真的通俗易懂的文章,而且很深入。

王改改:【通俗易懂】XGBoost从入门到实战,非常详细​zhuanlan.zhihu.com
2e9cfc2a75c84b82b81be5fb01ef23c2.png

通过自己的理解,再咀嚼后,记录此笔记。

一、进入模型前的简单案例

在上一篇文章中的案例,通俗的讲解了思路:

训练出第一个模型,计算其预测结果及残差;

92087656fd71bdc5b17162f223c69c8f.png

然后再以当前模型的残差,作为下一个模型的实际输出,将其与下一个模型的预测结果作对比,得出这个模型的残差;

9b6f170ac851dfcd288a37ad3bddd3da.png

再迭代到下一个......(看案例中的图更容易理解)

3b1b37845f6848c45f6d4fd9b34097ef.png

最终的输出结果是所有模型的预测结果之和

18ca91d7970fa685aa8eb8ace6665ab5.png

这个案例解决了我在看其他人写xgboost案例时看不懂的地方,其他地方写的都是以家庭中每个人的那个作为案例。我看的时候完全不知道它到底想干嘛,最后为什么又是把所有结果加起来,直到我看到了这位作者后才真正直到原理。

二、构建损失函数

个人在学习机器学习和深度学习的时候,除了要了解原理,另外最重要的就是要重点知道该算法的损失函数是怎么计算的!这是每个算法的核心。

假设我们已经训练了

棵树,对于第
个样本的最终预测值是等于:

其中

表示样本特征,
表示第
棵树对样本
的预测结果,最后把这些值都相加在一起就得到了最终的结果

再结合真实的结果label是

,就可以构建损失函数(到当前
棵树累计的损失函数):

其中

表示损失函数,常见的损失函数都可以用,像MSE、交叉熵cross entropy等;

后一项是用来控制复杂度的,类似于l1,l2正则,可以防止过拟合。

对于目标函数我们可以再拆开,类似于动态规划的思想,

拆成与上一个相关联的公式

这其中就是将

变成和上一个相关的
变成了
,这两个公式前面一项都是之前计算好的,已知的,所以可以看作是优化如下的损失函数,使其最小:

通过泰勒展开近似损失函数

泰勒展开式为:

将损失函数套用上泰勒展开,

对应
对应
对应
;

即可得

代入损失函数即可得:

再重复一遍,当前目标函数是训练第

颗树时的函数,
这一项是在计算
棵树为止的预测结果的损失累加值,而这些在计算第
颗树时,其实都是已知的,不参与优化过程。所以上式的
都是已知的。后两项可以分别用
表示,再优化后,损失函数只需优化如下式子即可:

如上所说,

是已知的,现在要优化函数的话,需要把
参数化。

定义树的复杂度

一颗树的复杂度可以用叶节点个数和节点值计算得:

给两个都乘上一个超参数,用来控制他们,

是为了后续方便求导计算:

最终可以再优化得到:

最后得:

我们知道

最小值的点为:

所以,所以当树的结构固定,也就是说

固定的话,在中括号中的最佳
为:

带入到
中可得,
当前树结构下的最佳的目标函数值:

其中

表示
,都是已知的,和一阶导,二阶导对应的。

三、构建树的形状

在得到了损失函数,就可以开始构建树了,那怎么构建树呢?贪心算法!

没错,先计算当前树的损失函数,再穷举出所有可能性,然后计算所有穷举后的损失函数,然后取损失函数降的最多的那棵树最为当前树的形状,然后再重复......直到损失函数减少的不够多的时候,我们可以设个阈值,就可以停下来!

「卓拾书非卓师叔」

作者:卓师叔,爱书爱金融的NLPer

了解更多和AI、金融相关的知识,请关注公众号:卓拾书非卓师叔

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来解答你的问题。 首先,让我们来看看二叉的遍历方式。二叉的遍历方式有三种:前序遍历、中序遍历和后序遍历。 - 前序遍历:先访问根节点,再访问左子,最后访问右子。 - 中序遍历:先访问左子,再访问根节点,最后访问右子。 - 后序遍历:先访问左子,再访问右子,最后访问根节点。 而在XML解析中,我们可以将XML文件看作一棵,它的每个节点都有自己的标签、属性和内容。因此,在解析XML文件时,我们也可以采用类似于二叉的遍历方式来遍历XML。 具体来说,我们可以使用tinyxml2库中的函数来遍历XML。以下是一个简单的示例代码,演示如何遍历XML中的所有节点: ``` #include "tinyxml2.h" #include <iostream> using namespace tinyxml2; void TraverseXML(XMLElement* element) { if (element == nullptr) { return; } // 访问当前节点 std::cout << "Node name: " << element->Name() << std::endl; // 访问当前节点的属性 const XMLAttribute* attribute = element->FirstAttribute(); while (attribute != nullptr) { std::cout << "Attribute name: " << attribute->Name() << ", value: " << attribute->Value() << std::endl; attribute = attribute->Next(); } // 访问当前节点的内容 std::cout << "Node value: " << element->GetText() << std::endl; // 遍历当前节点的子节点 XMLElement* child = element->FirstChildElement(); while (child != nullptr) { TraverseXML(child); child = child->NextSiblingElement(); } } int main() { XMLDocument doc; doc.LoadFile("example.xml"); XMLElement* root = doc.FirstChildElement(); TraverseXML(root); return 0; } ``` 这段代码中,我们首先定义了一个TraverseXML函数,用于遍历XML中的所有节点。该函数的参数是一个XMLElement指针,表示当前节点。在函数内部,我们首先访问了当前节点的标签、属性和内容,然后遍历了当前节点的所有子节点。 在主函数中,我们首先使用XMLDocument类的LoadFile函数来加载XML文件,然后获取XML的根节点,并将其作为参数传递给TraverseXML函数,从而遍历整个XML。 希望这个通俗易懂的讲解能够帮助你理解如何使用tinyxml2遍历所有节点。如果你还有其他问题,可以随时问我哦!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值