xgboost算法详细介绍(通过简单例子讲述)

本文深入解析XGBoost算法,一种高效的梯度提升框架,适用于大规模数据集。通过实例详细阐述XGBoost如何通过集成弱学习器形成强分类器,优化结构化损失函数并减少过拟合风险。


作者才疏学浅,如有错误还请指正,谢谢!

boost算法简介

Boost 是一种将弱分离器??(?)组合起来形成强分类器 F(?) 的算法框架

“弱分类器”的分类能力不强,但它又比随机选的效果稍微好点,类似于“臭皮匠”。
“强分类器”具有很强的分类能力,也就是把特征扔给它,他能分的比较准确,算是“诸葛亮”一类的。
如果直接可以建立一个强分类器,那弱分类器实际上就是多余的,但是,这世上“绝顶聪明的诸葛亮”少之又少,反而,在某方面有才华的人很多。于是,Boost选择了用三个臭皮匠去顶诸葛亮。

集成学习的任务

集成学习的主要手段就是反复训练多个模型,并将这些模型通过一定方式组合在一起,形成一个高性能的强大的集成模型。在Boosting算法体系中一般采用迭代串行的形式生成一系列模型,然后将这些模型进行线性加权相加,得到最终集成学习器。假设已经迭代到m-1次,得到的集成模型为
在这里插入图片描述
在下一次迭代中,我们要训练,它应该是让新生成的集成模型在训练集上损失最小的模型
在这里插入图片描述

XGBoost简介

xgboost 的全称是eXtreme Gradient Boosting,由华盛顿大学的陈天奇博士提出,在Kaggle的希格斯子信号识别竞赛中使用,因其出众的效率与较高的预测准确度而引起了广泛的关注。

XGBoost的思想

如果boost算法每一步的弱预测模型生成都是依据损失函数的梯度方向,则称之为梯度提升(Gradient boosting),XGBoost算法是采用分步前向加性模型,只不过在每次迭代中生成弱学习器后不再需要计算一个系数,模型形式如下:
在这里插入图片描述
XGBoost算法通过优化结构化损失函数(加入了正则项的损失函数,可以起到降低过拟合的风险)来实现弱学习器的生成,并且XGBoost算法没有采用搜索方法,而是直接利用了损失函数的一阶导数和二阶导数值,并通过预排序、加权分位数等技术来大大提高了算法的性能。

通过算法流程图举一个例子详解xgboost树的生成

在这里插入图片描述

我们举一个预测学生考试分数的例子,给定若干个学生属性(比如天赋,每天学习时间,是否恋爱等),通过一个决策树A,我们可以看到,一个通过天赋属性的预测结果:天赋高的人分数+90,天赋低的人+60,通过一个决策树B,可以看到每天学习时间<10小时会使得考试分数收到-5的影响,但是影响不大,以此类推可以通过学生的属性推断其分数情况。XGboost就是这样一个不断生成新的决策树A,B,C,D…的算法,最终生成的决策树算法就是树A+B+C+D+…的和的决策树。
在这里插入图片描述

1.首先我们初始化三个样例的考试成绩预测值为0,属性为(天赋高、不恋爱、每天学习时间有16个小时),(天赋低、不恋爱、每天学习时间有16个小时),(天赋高、不恋爱、每天学习时间有6个小时),真实成绩分别为100,70,86分。

在这里插入图片描述
在这里插入图片描述
其中Tt为叶结点数,wj为j叶子结点权重,?和λ为预先设计超的参数。

在引入了正则化项后,算法会选择简单而性能优良的模型,损失函数中右端的正则化项
只是用来在每次迭代中抑制弱学习器 fi(x)过拟合的,并不参与最终模型的集成。另外XGBoost 要求L函数至少是二阶连续可导的凸函数。
在这里插入图片描述
在这里插入图片描述

Xgboost系统的每次迭代都会构建一颗新的决策树,决策树通过与真实值之间残差来构建,(天赋高、不恋爱、每天学习时间有16个小时)的大学霸考了100分,(天赋低、不恋爱、每天学习时间有16个小时)的小学霸考了70分,(天赋高、不恋爱、每天学习时间有6个小时)的小天才考了86分,那么三位同学通过第一个决策树后预测结果分别为90分,60分,和90分,在构建第二颗决策树时就会考虑残差(100-90=10),(70-60)=10,(86-90=-4)来构建一颗新的树(具体建树过程之后会讲到),我们通过最小化残差学习到一个通过学习时间属性来构建的决策树的得到90+5,60+5,90-5的预测值,再继续通过(100-95=5)(70-65)(86-85)的残差构建下一个决策树,以此类推,当迭代次数达到上限或是残差不再减小是停止,就得到一个拥有多个(迭代次数)决策树的强分类器。当然分类器是需要考虑更多样本的,我们可以把新加入的决策树fi(x)看作是在N维空间(因为有N个样本)中p(m)相对于点p(m-1)的增量。
当然怎样得到一颗新的树呢?接着看第三个步骤

3.计算损失函数对于每个样本预测值的导数

为什么要计算导数信息呢? ——XGBoost的精髓所在下面我们看一个关于目标函数的简单等式变换:
目标函数:在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们可以看到目标函数就这样被转换成了关于g_i和h_i的函数,最终的目标函数只依赖于每个数据点的在误差函数上的一阶导数和二阶导数。这么写的原因很明显,由于之前的目标函数求最优解的过程中只对平方损失函数时候方便求,对于其他的损失函数变得很复杂,通过二阶泰勒展开式的变换,这样求解其他损失函数变得可行了。所以 XGBoost 是直接先求损失函数在该点处的泰勒近似值,然后通过最小化该近似损失函数值来训练弱学习器?? (??)。

4.根据导数的信息建立一颗新的决策树

这里求导数的的过程或者说求导的意义让笔者‘百思不得其解’,因为树模型是阶跃的,阶跃点是不可导的,所以求导就没意义了。
之后笔者查阅了xgboost的源代码,发现源代码对优化函数求导使用了一个简便的算法代替:

def log_reg(y_hat ,y):
       p = 1.0/(1.0+ np.exp(-y_hat))
       g = p – y.get_lable()
       h= p * (1.0-p)
       return g,h

就是这么简单~~
所以树模型(回归树)可以通过导数信息寻找最优分裂点。

怎样通过导数建立树呢,我们可以把目标函数进行如下改写,其中j被定义为每个叶子上面样本集合。它将一个样本x 映射到一个相对应的叶子节点,那么可以写成如下形式
在这里插入图片描述
这一个目标包含了个相互独立的单变量二次函数。我们可以定义
在这里插入图片描述
在这里插入图片描述
wj就是新建立的树叶子的权值,通过计算对w求偏导=0得:
在这里插入图片描述
带入目标函数得:
在这里插入图片描述
假设我们从一个初始的节点(根节点)开始, I 表示该节点上所有样本的索引集,现在我们要对该节点进行分裂,设 IL,IR分别为分裂后左右子节点中样本的索引集,并且有I=IL∪IR 。那么根据上式我们可以计算出分裂前后第 m个树模型的损失函数值减小量为
在这里插入图片描述
这个公式跟我们决策树算法遇到的信心增益或基尼值增量的公式是一个道理。XGBoost 就是利用这个公式计算出的值作为分裂条件,在每一个节点的分裂中寻找最优的分裂和属性和分裂点。这样我们就能顺利地得到我们在第m 轮迭代中所需要的最优的模型fm(x)。

设有ABCDE五个学生,学习时间分别为16,12,8,6,4小时,通过计算不同分割方法的增益值来确定哪个分割是否是最优分割。我们生成如下一个决策树,决策树的增益值就是通过带入p = 1.0/(1.0+ np.exp(-y_hat)); g = p – y.get_lable();h= p * (1.0-p),计算每个节点的gi和hi,带入如下信息增益公式。注意引入的分割带来的增益小于一个阀值的时候,我们可以剪掉这个分割。
在这里插入图片描述
在这里插入图片描述

5.利用新的决策树预测样本值,并累加到原来的值上

在这里插入图片描述
在这里插入图片描述

xgboost的简单应用:根据诊断措施预测糖尿病的发病(Kaggle竞赛 )

数据集有如下几个属性:
在这里插入图片描述
部分数据集如下:
在这里插入图片描述
代码如下(数据pima-indians-diabetes.csv可以在网上下载)

from numpy import loadtxt
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from xgboost import plot_importance
from matplotlib import pyplot
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")

X = dataset[:,0:8]
Y = dataset[:,8]
seed = 7
test_size = 0.33
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=test_size, random_state=seed)
model = XGBClassifier()
eval_set = [(X_test, y_test)]
model.fit(X_train, y_train, early_stopping_rounds=10, eval_metric="logloss", eval_set=eval_set, verbose=True)
y_pred = model.predict(X_test)
predictions = [round(value) for value in y_pred]
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))
model.fit(X, Y)
plot_importance(model)
pyplot.show()

通过计算不同属性参与节点的分类个数可以看出对糖尿病发病情况影响最重要的属性是BMI。
在这里插入图片描述

<think>嗯,用户让我介绍一下XGBoost以及它和GBDT的区别,还要详细算法步骤。首先,我需要回忆一下XGBoost的基本概念。XGBoost应该是一种梯度提升算法,属于集成学习中的Boosting方法。对吧?那GBDT也是梯度提升决策树,所以它们都属于Gradient Boosting的框架,但XGBoost可能有一些改进。 首先,我应该先解释XGBoost是什么,它的全称是eXtreme Gradient Boosting,对吧?由陈天奇等人开发,主要特点是高效、灵活,而且应用广泛,比如在Kaggle竞赛中表现很好。然后和GBDT的区别,可能需要比较它们在目标函数、正则化、树结构生成方式、缺失值处理等方面的不同。 接下来,算法步骤需要详细展开。XGBoost的目标函数包括损失函数和正则化项,正则化可能包括叶子节点的权重和树的复杂度。在每一步迭代中,会添加一个新的树来拟合前一轮的残差。然后,泰勒展开可能被用来近似目标函数,比如用到一阶导和二阶导。树的分裂准则可能和GBDT不同,XGBoost可能用增益计算来决定如何分裂节点,比如增益公式是怎样的? 然后,关于区别部分,GBDT通常用一阶导数,而XGBoost用了二阶导数,这样可能更精准。正则化方面,XGBoost加入了正则项来控制模型复杂度,防止过拟合,而GBDT可能没有显式的正则化。树的分裂算法上,XGBoost可能用了预排序(pre-sorted)或者直方图的方法,还有并行计算优化。另外,缺失值的处理,XGBoost可以自动学习如何处理缺失值,而GBDT可能需要预处理。 需要确认这些区别是否正确,比如是否GBDT真的没有正则化,或者是否有其他不同点。比如,XGBoost还支持不同的基学习器,不仅是决策树,但通常默认是树。而GBDT通常用CART树。另外,XGBoost在工程实现上做了优化,比如块结构、缓存优化等,这些可能也是区别点。 详细介绍算法步骤的时候,可能要分点说明:目标函数的构建、泰勒展开近似、树结构确定、分割节点选择、正则化项的具体形式,比如L1和L2正则。还有如何通过增益计算来决定是否分裂,以及如何剪枝。 用户可能需要了解XGBoost为什么比GBDT更好,所以在介绍区别时要强调性能、速度、准确度等方面的优势。另外,可能需要注意用户是否具备一定的机器学习基础,是否需要解释梯度提升的基本概念,但用户可能已经知道GBDT,所以重点放在两者的比较上。 有没有遗漏的关键点呢?比如,XGBoost还支持行采样和列采样,类似于随机森林,这也是防止过拟合的一种方法。而GBDT通常没有这样的采样机制。或者XGBoost的并行处理能力,虽然Boosting是串行的,但XGBoost在特征选择时可以并行,比如在寻找最佳分裂点的时候,利用多线程进行计算,这加快了训练速度。 算法步骤部分需要详细分解,比如每一步如何计算预测值,如何计算梯度,如何生成树结构,如何更新模型。可能还需要提到XGBoost如何处理缺失值,比如自动决定将缺失值分到左子树还是右子树。 哦,对了,XGBoost的目标函数具体形式应该是损失函数加上正则化项。比如,对于回归问题,损失函数可能是平方误差,正则化项是γ乘以叶子节点数加上λ乘以权重平方和的一半。这可能影响树的生成过程,因为分裂时的增益计算会考虑这些正则化项。 在具体步骤中,可能包括初始化预测值,然后迭代地添加树,每次迭代中计算梯度(一阶导)和Hessian(二阶导),根据这些统计量生成新的树结构,找到最佳的分裂点,然后更新模型。分裂节点的增益计算可能类似于 (G_L^2)/(H_L + λ) + (G_R^2)/(H_R + λ) - (G^2)/(H + λ) - γ,其中G和H是梯度和二阶导数的总和,γ是复杂度参数。如果增益大于0,则分裂,否则不分裂。 最后,需要确保比较部分清晰列出XGBoost和GBDT的不同之处,可能分点列出,比如正则化、导数阶数、工程优化、缺失值处理等。这样用户能一目了然。 总结一下,回答的结构应该是先介绍XGBoost,然后详细步骤分点说明,接着比较两者的区别,最后可能给出应用场景或优势。需要确保技术细节准确,同时语言通俗易懂,避免过于晦涩的数学公式,但必要的公式可能需要出现,比如增益的计算公式,以显示其严谨性。</think>### 一、XGBoost 简介 **XGBoost**(eXtreme Gradient Boosting)是一种基于梯度提升框架(Gradient Boosting)的高效机器学习算法,由陈天奇于2016年提出。它通过集成多个弱学习器(通常为决策树)逐步优化模型预测,广泛应用于分类、回归和排序任务,尤其在Kaggle竞赛中表现突出。 --- ### 二、XGBoost 算法步骤详解 #### 1. **目标函数设计** XGBoost的目标函数包含两部分: - **损失函数**(如均方误差、交叉熵)衡量预测值与真实值的差异。 - **正则化项**(控制模型复杂度,防止过拟合): \[ \Omega(f_t) = \gamma T + \frac{1}{2} \lambda \sum_{j=1}^T w_j^2 \] 其中 \(T\) 是叶子节点数,\(w_j\) 是叶子权重,\(\gamma\) 和 \(\lambda\) 是超参数。 #### 2. **泰勒展开近似** 在第 \(t\) 轮迭代中,对目标函数进行二阶泰勒展开,将优化目标转化为: \[ \text{Obj}^{(t)} \approx \sum_{i=1}^n \left[ g_i w_{q(x_
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值