赞
踩
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
4.subsample 和 colsample_bytree
集成模型Boosting补完计划第三期了,之前我们已经详细描述了AdaBoost算法模型和GBDT原理以及实践。通过这两类算法就可以明白Boosting算法的核心思想以及基本的运行计算框架,余下几种Boosting算法都是在前者的算法之上改良得到,尤其是以GBDT算法为基础改进衍生出的三种Boosting算法:XGBoost、LightGBM、CatBoost。大家应该都对XGBoost算法模型熟悉但是对GBDT模型一无所知,看过之前GBDT的读者应该对GBDT模型有了一个很清楚的认知,对于理解XGBoost算法有一定的基础。
XGBoost在各种数据挖掘、预测和分类任务中取得了极高的准确率和性能。是目前应用最广泛的机器学习算法之一。可以说,XGBoost的快速发展和广泛应用,推动了机器学习算法的进一步发展和优化,为人工智能技术的普及和应用打下了坚实的基础。那么此篇文章我将尽力让大家了解并熟悉XGBoost模型算法框架,保证能够理解通畅以及推演顺利的条件之下,尽量不使用过多的数学公式和专业理论知识。以一篇文章快速了解并实现该算法,以效率最高的方式熟练使用此方法。
博主专注建模四年,参与过大大小小数十来次数学建模,理解各类模型原理以及每种模型的建模流程和各类题目分析方法。此专栏的目的就是为了让零基础快速使用各类数学模型以及代码,每一篇文章都包含实战项目以及可运行代码。博主紧跟各类数模比赛,每场数模竞赛博主都会将最新的思路和代码写进此专栏以及详细思路和完全代码。希望有需求的小伙伴不要错过笔者精心打造的专栏。
以下是整篇文章内容。
这里通过简述的发展史可以得到我们可以通过python调用此算法,而且也可以通过调用GPU提高了算法的计算速度。由此可见XGBoost算法的受欢迎程度。
XGBoost是一种基于梯度提升决策树(Gradient Boosting Decision Tree,GBDT)的机器学习算法,旨在优化和加速GBDT的训练过程,并提高模型的准确性和泛化能力。
我们拿这个XGBoost与其他GBDT的算法进行对比:
算法差异点 | GBDT | XGBoost | LightGBM | CatBoost |
弱学习器 | CART回归树 | 1.CART回归树 2.线性学习器 3.Dart树 | Leaf-wise树 | 对称树 |
寻找分裂点 | 贪心算法 | 近似算法 | 直方图算法 | 预排序算法 |
稀疏值处理 | 无 | 稀疏感知算法 | EFB(互斥特征捆绑) | 无 |
类别特征 | 不直接支持,可自行编码后输入模型 | 同GBDT | 直接支持,GS编码 | 直接支持,Ordered TS编码 |
并行支持 | 不可以 | 可以 | 可以 | 可以 |
XGBoost的算法原理较于GBDT算法的改进包括以下几个方面:
XGBoost采用泰勒展开式(Taylor expansion)来近似损失函数,其中损失函数可以是回归问题中的均方误差(MSE)或分类问题中的交叉熵(cross-entropy)。XGBoost通过二阶泰勒展开式考虑了损失函数的一、二阶导数,从而提高了模型的预测精度。
XGBoost使用贪心算法来选择最优的分裂点(split point),即使得损失函数最小的分裂点。在寻找最优分裂点的过程中,XGBoost通过对特征值进行排序来加速计算,同时引入了直方图(histogram)和近似算法(approximate algorithm)来进一步提高计算效率。
XGBoost采用与CART决策树类似的剪枝策略,通过设定叶子节点的最小权重和最大深度来控制模型的复杂度,并避免过拟合。剪枝策略可以在模型训练过程中或之后进行。
XGBoost还采用正则化方法来控制模型的复杂度,避免过拟合。具体来说,XGBoost支持两种正则化方法:L1正则化和L2正则化。通过调节正则化参数的值,可以实现对模型复杂度的灵活控制。
XGBoost还引入了学习率(learning rate)的概念,用于控制每次迭代时模型参数的更新幅度,避免过拟合。学习率通常设置为小于1的值,例如0.1或0.01。
为了避免过拟合和提高模型的训练效率,XGBoost还支持提前停止(early stopping)功能。该功能会在训练过程中监测验证集的损失函数,当连续若干次迭代中验证集的损失函数没有下降时,就停止训练,避免过拟合和浪费计算资源。
在了解了XGBoost与GBDT算法差距之后我们不妨和学习GBDT算法一样整体来一遍清楚哪些计算节点增加了新的处理。
首先基础的流程还是和GBDT一致的:
将所有样本的权重设置为相等的值,建立一个初始模型作为基准模型,可以设置为简单的平均值或者是中位数,而XGBoost中加入了正则项,用来控制基学习器树的结构,目标函数定义如下:
例如建立一个弱分类器,c即为平均值。但是我们在每次迭代的过程中添加一个新函数:
也就是t个模型的预测值等于前t个模型的预测值+当前正在训练第t个模型的预测值。
那么上述公式简化为:
我们可以讲上述公式变换:
首先将算法模型带入取代,将后面基学习器树的复杂度进行拆分,拆成前t-1棵树的复杂度加上当前模型树的复杂度,又因为我们当时正在训练第t棵树,所以针对于前k棵树都是常量,所以现在我们的目标函数又可以写成:
这里我们考虑平方损失,此时目标函数又可以变形为:
根据上面我们就构造好了目标函数,但是为了将其进行简化,我们将其进行泰勒二阶展开
泰勒二阶展开式一般形式如下:
此时我们定义,.
目标函数利用泰勒展开式就可以变成:
其中
因为我们的和都是和前个学习器相关,所以都为常数,那么简化后的目标函数就为:
那么得到了想要的目标函数,我们现在就需要将树引入到我们的目标计算函数中,去取代和,我们依旧参照GBDT的计算原理和过程,也就是XGBoost的预测原理。
使用
对于决策树的例子大家可以参考我的上篇文章:
一文速学-GBDT模型算法原理以及实现+Python项目实战
这里不再复述,仅讲XGBoost改动,我们知道单独的使用GBDT模型,容易出现过拟合,在实际应用中往往使用 GBDT+LR的方式做模型训练。一般情况下,我们的树模型越深越茂密那么复杂度越高,或者叶子节点值越大模型复杂度越高。
在XGBoost算法的实现中,是采用下式来衡量模型复杂度的:
其中代表叶子节点个数,:各个叶子节点值的求和,:超参数,控制惩罚程度。
那么我们将原目标函数的和给取代掉:
那么此时我们定义在叶子结点中的实例的集合为:
计算损失函数时是以样本索引来遍历的总共n个样本,计算所有叶子节点样本的损失可以为:
所以此时目标函数就可以写为:
大家如果能看到这里已经差不多能将此目标函数推导出来了,但是这里我们还需要获得最优叶子结点的值,也就是最小值。此时我们需要将上述公式再度变换:
此时目函数就为是一个二次函数,对于二次函数这里补充一个大家或许真的的知识点,也就是得到这个函数的最小值。我们需要先求导去零得到极值点的x,再带入原方程。
那么对其求导很容易得到,当时对应方程的值为.
接着我们定义:
那么目标函数就为:
那么到这一步目标函数最优结构就确定了,但是针对于一棵树,模型的结构可能有很多种,此刻我们需要选择最优树结构,XGBoost算法采用的动态规划为贪心算法,去构建一颗最优的树。
不知道大家看到现在还有几个愿意看下去贪心算法构建最优树的,但是XGBoost算法的计算原理就是如此,要了解其计算过程这点是绕不过的,该学习了解的还是得下点功夫。
贪心算法的模板下面给出:
而对于树模型的优劣程度我们是根据信息增益来判断的,也就是使用熵来进行评估不确定度,CART中使用的是基尼系数的概念。对于XGBoost算法来说我们比较的大小差距就可拟作信息增益。
我们是要获得最大信息增益,就需要遍历所以特征计算增益,选取增益大的进行切分构造树模型。
根据这个原理我们就可以构造一棵使目标函数最小的树模型,然后按照这个逻辑,一次构造K棵树,然后最终将所有的树加权就是我们最终的模型:
讲到现在XGBoost已经讲完损失函数和分裂点选择两个核心的变动,还有另外四个改进,暂时先不作很深入的讲解,剪枝策略就详细介绍在RF算法中,正则化和提前停止策略我将会在下一篇详细讲述。下面进入实战实现环节。
或许大家觉得公式推导很繁琐,但是如果不做以上推导的话,无论是面试还是答辩无法证实你确实会使用XGBoost算法,而且面对XGBoost算法调优以及参数改进都是比较困难的。而且XGBoost一般直接使用自带的XGBoost库Python编程就好了,很少自行构造XGBoost树,大家可以参照我上篇文章GBDT流程一样构造XGBoost算法结构树。
对于贷款违约预测这个比较经典的课题,我们很容易拿到现成的数据,对于建模来讲,我们最缺的就是数据,而阿里天池提供了一份开源贷款违约数据,大家直接下载即可。
那么我们就开始实现逐步进行建模。
赛题以预测用户贷款是否违约为任务,数据集报名后可见并可下载,该数据来自某信贷平台的贷款记录,总数据量超过120w,包含47列变量信息,其中15列为匿名变量。为了保证比赛的公平性,将会从中抽取80万条作为训练集,20万条作为测试集A,20万条作为测试集B,同时会对employmentTitle、purpose、postCode和title等信息进行脱敏。
Field | Description |
---|---|
id | 为贷款清单分配的唯一信用证标识 |
loanAmnt | 贷款金额 |
term | 贷款期限(year) |
interestRate | 贷款利率 |
installment | 分期付款金额 |
grade | 贷款等级 |
subGrade | 贷款等级之子级 |
employmentTitle | 就业职称 |
employmentLength | 就业年限(年) |
homeOwnership | 借款人在登记时提供的房屋所有权状况 |
annualIncome | 年收入 |
verificationStatus | 验证状态 |
issueDate | 贷款发放的月份 |
purpose | 借款人在贷款申请时的贷款用途类别 |
postCode | 借款人在贷款申请中提供的邮政编码的前3位数字 |
regionCode | 地区编码 |
dti | 债务收入比 |
delinquency_2years | 借款人过去2年信用档案中逾期30天以上的违约事件数 |
ficoRangeLow | 借款人在贷款发放时的fico所属的下限范围 |
ficoRangeHigh | 借款人在贷款发放时的fico所属的上限范围 |
openAcc | 借款人信用档案中未结信用额度的数量 |
pubRec | 贬损公共记录的数量 |
pubRecBankruptcies | 公开记录清除的数量 |
revolBal | 信贷周转余额合计 |
revolUtil | 循环额度利用率,或借款人使用的相对于所有可用循环信贷的信贷金额 |
totalAcc | 借款人信用档案中当前的信用额度总数 |
initialListStatus | 贷款的初始列表状态 |
applicationType | 表明贷款是个人申请还是与两个共同借款人的联合申请 |
earliesCreditLine | 借款人最早报告的信用额度开立的月份 |
title | 借款人提供的贷款名称 |
policyCode | 公开可用的策略_代码=1新产品不公开可用的策略_代码=2 |
n系列匿名特征 | 匿名特征n0-n14,为一些贷款人行为计数特征的处理 |
这里借用一下贷款违约预测学习笔记submarineas博主 的图片
数据展示:
使用pandas进行数据分析,也就是查看数据中的空缺值,重复值和异常值,以及相对应的数据描述。
import pandas as pd
df=pd.read_csv("train.csv")
test=pd.read_csv("testA.csv")
基本数据情况:
df.shape
(800000, 47)
test.shape
(200000, 46)
df.info() <class 'pandas.core.frame.DataFrame'> RangeIndex: 800000 entries, 0 to 799999 Data columns (total 47 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 id 800000 non-null int64 1 loanAmnt 800000 non-null float64 2 term 800000 non-null int64 3 interestRate 800000 non-null float64 4 installment 800000 non-null float64 5 grade 800000 non-null object 6 subGrade 800000 non-null object 7 employmentTitle 799999 non-null float64 8 employmentLength 753201 non-null object 9 homeOwnership 800000 non-null int64 10 annualIncome 800000 non-null float64 11 verificationStatus 800000 non-null int64 12 issueDate 800000 non-null object 13 isDefault 800000 non-null int64 14 purpose 800000 non-null int64 15 postCode 799999 non-null float64 16 regionCode 800000 non-null int64 17 dti 799761 non-null float64 18 delinquency_2years 800000 non-null float64 19 ficoRangeLow 800000 non-null float64 20 ficoRangeHigh 800000 non-null float64 21 openAcc 800000 non-null float64 22 pubRec 800000 non-null float64 23 pubRecBankruptcies 799595 non-null float64 24 revolBal 800000 non-null float64 25 revolUtil 799469 non-null float64 26 totalAcc 800000 non-null float64 27 initialListStatus 800000 non-null int64 28 applicationType 800000 non-null int64 29 earliesCreditLine 800000 non-null object 30 title 799999 non-null float64 31 policyCode 800000 non-null float64 32 n0 759730 non-null float64 33 n1 759730 non-null float64 34 n2 759730 non-null float64 35 n3 759730 non-null float64 36 n4 766761 non-null float64 37 n5 759730 non-null float64 38 n6 759730 non-null float64 39 n7 759730 non-null float64 40 n8 759729 non-null float64 41 n9 759730 non-null float64 42 n10 766761 non-null float64 43 n11 730248 non-null float64 44 n12 759730 non-null float64 45 n13 759730 non-null float64 46 n14 759730 non-null float64 dtypes: float64(33), int64(9), object(5)
df[df.duplicated()==True]#打印重复值
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
float64
46 n14 759730 non-null float64
dtypes: float64(33), int64(9), object(5)
#### 查看重复值:
df[df.duplicated()==True]#打印重复值
![](https://img-blog.csdnimg.cn/dbc36ec403844207b8a04bbe4700a395.png) [外链图片转存中...(img-ZywYaO19-1715722894648)] [外链图片转存中...(img-9K3xyeTZ-1715722894648)] **网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。** **[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)** **一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。