XGB算法梳理

1、算法原理

1.1、定义树的复杂度

对于f的定义做一下细化,把树拆分成结构部分q叶子权重部分w。下图是一个具体的例子。结构函数q把输入映射到叶子的索引号上面去,而w给定了每个索引号对应的叶子分数是什么。 

定义这个复杂度包含了一棵树里面节点的个数,以及每个树叶子节点上面输出分数的L2模平方。当然这不是唯一的一种定义方式,不过这一定义方式学习出的树效果一般都比较不错。下图还给出了复杂度计算的一个例子。 

注:方框部分在最终的模型公式中控制这部分的比重 

在这种新的定义下,我们可以把目标函数进行如下改写,其中I被定义为每个叶子上面样本集合I_{j}=\left \{ i|q(x_{i}=j) \right \}

这一个目标包含了TT个相互独立的单变量二次函数。我们可以定义

最终公式可以化简为

通过对求导等于0,可以得到

然后把最优解代入得到:

1.2、打分函数计算示例

Obj代表了当我们指定一个树的结构的时候,我们在目标上面最多减少多少。我们可以把它叫做结构分数(structure score)

1.3、枚举不同树结构的贪心法

贪心法:每一次尝试去对已有的叶子加入一个分割

对于每次扩展,我们还是要枚举所有可能的分割方案,如何高效地枚举所有的分割呢?我假设我们要枚举所有x < a 这样的条件,对于某个特定的分割a我们要计算a左边和右边的导数和。

我们可以发现对于所有的a,我们只要做一遍从左到右的扫描就可以枚举出所有分割的梯度和GL和GR。然后用上面的公式计算每个分割方案的分数就可以了。

观察这个目标函数,大家会发现第二个值得注意的事情就是引入分割不一定会使得情况变好,因为我们有一个引入新叶子的惩罚项。优化这个目标对应了树的剪枝, 当引入的分割带来的增益小于一个阀值的时候,我们可以剪掉这个分割。大家可以发现,当我们正式地推导目标的时候,像计算分数和剪枝这样的策略都会自然地出现,而不再是一种因为heuristic(启发式)而进行的操作了。

参考:https://www.cnblogs.com/zhouxiaohui888/p/6008368.html

2、损失函数

XGBoost用于监督学习问题(分类和回归)。监督学习的常用目标函数是:
通常目标函数包含两部分:训练误差和正则化
            obj(\theta)=L(\theta)+\Omega (\theta)

其中L是损失函数,度量模型预测与真实值的误差。

在实际的业务场景下,我们往往需要自定义损失函数。常见的损失函数有:

平方损失函数:

L(\theta)=\sum_{i}(y_{i}-\hat{y}_{i})^{2}

logistic损失函数:

L(\theta)=\sum_{i}[y_{i}ln(1+e^{-\hat{y}_{i}})+(1-y_{i})ln(1+e^{\hat{y}_{i}})]
3、分裂结点算法

基于空间切分去构造一颗决策树是一个NP难问题,我们不可能去遍历所有树结构,因此,XGBoost使用了和CART回归树一样的想法,利用贪婪算法,遍历所有特征的所有特征划分点,不同的是使用上式目标函数值作为评价函数。具体做法就是分裂后的目标函数值比单子叶子节点的目标函数的增益,同时为了限制树生长过深,还加了个阈值,只有当增益大于该阈值才进行分裂。
4、正则化

xgboost使用了如下的正则化项:

\Omega(f)=\gamma T+\frac{1}{2}\lambda \sum_{j=1}^{T}w_{j}^{2}

注意:这里出现了γ和λ,这是xgboost自己定义的,在使用xgboost时,你可以设定它们的值,显然,γ越大,表示越希望获得结构简单的树,因为此时对较多叶子节点的树的惩罚越大。λ越大也是越希望获得结构简单的树。
5、对缺失值处理

xgboost模型却能够处理缺失值,模型允许缺失值存在。

原始论文中关于缺失值的处理将其看与稀疏矩阵的处理看作一样。在寻找split point的时候,不会对该特征为missing的样本进行遍历统计,只对该列特征值为non-missing的样本上对应的特征值进行遍历,通过这个技巧来减少了为稀疏离散特征寻找split point的时间开销。在逻辑实现上,为了保证完备性,会分别处理将missing该特征值的样本分配到左叶子结点和右叶子结点的两种情形,计算增益后选择增益大的方向进行分裂即可。可以为缺失值或者指定的值指定分支的默认方向,这能大大提升算法的效率。如果在训练中没有缺失值而在预测中出现缺失,那么会自动将缺失值的划分方向放到右子树。
6、优缺点

与GBDT相比,xgBoosting有以下进步:

1)GBDT以传统CART作为基分类器,而xgBoosting支持线性分类器,相当于引入L1和L2正则化项的逻辑回归(分类问题)和线性回归(回归问题);

2)GBDT在优化时只用到一阶导数,xgBoosting对代价函数做了二阶Talor展开,引入了一阶导数和二阶导数;

3)当样本存在缺失值是,xgBoosting能自动学习分裂方向;

4)xgBoosting借鉴RF的做法,支持列抽样,这样不仅能防止过拟合,还能降低计算;

5)xgBoosting的代价函数引入正则化项,控制了模型的复杂度,正则化项包含全部叶子节点的个数,每个叶子节点输出的score的L2模的平方和。从贝叶斯方差角度考虑,正则项降低了模型的方差,防止模型过拟合;

6)xgBoosting在每次迭代之后,为叶子结点分配学习速率,降低每棵树的权重,减少每棵树的影响,为后面提供更好的学习空间;

7)xgBoosting工具支持并行,但并不是tree粒度上的,而是特征粒度,决策树最耗时的步骤是对特征的值排序,xgBoosting在迭代之前,先进行预排序,存为block结构,每次迭代,重复使用该结构,降低了模型的计算;block结构也为模型提供了并行可能,在进行结点的分裂时,计算每个特征的增益,选增益最大的特征进行下一步分裂,那么各个特征的增益可以开多线程进行;

8)可并行的近似直方图算法,树结点在进行分裂时,需要计算每个节点的增益,若数据量较大,对所有节点的特征进行排序,遍历的得到最优分割点,这种贪心法异常耗时,这时引进近似直方图算法,用于生成高效的分割点,即用分裂后的某种值减去分裂前的某种值,获得增益,为了限制树的增长,引入阈值,当增益大于阈值时,进行分裂;

然而,与LightGBM相比,又表现出了明显的不足:

1)xgBoosting采用预排序,在迭代之前,对结点的特征做预排序,遍历选择最优分割点,数据量大时,贪心法耗时,LightGBM方法采用histogram算法,占用的内存低,数据分割的复杂度更低;

2)xgBoosting采用level-wise生成决策树,同时分裂同一层的叶子,从而进行多线程优化,不容易过拟合,但很多叶子节点的分裂增益较低,没必要进行跟进一步的分裂,这就带来了不必要的开销;LightGBM采用深度优化,leaf-wise生长策略,每次从当前叶子中选择增益最大的结点进行分裂,循环迭代,但会生长出更深的决策树,产生过拟合,因此引入了一个阈值进行限制,防止过拟合。

7、应用场景

后续补上。
8、sklearn参数

后续实际操作了再补上吧。

9、LightGBM
微软出了个LightGBM,号称性能更强劲,速度更快。简单实践了一波,发现收敛速度要快一些,不过调参还不6 ,没有权威。看了GitHub上的介绍以及知乎上的一些回答,大致理解了性能提升的原因。 
主要是两个:①histogram算法替换了传统的Pre-Sorted,某种意义上是牺牲了精度(但是作者声明实验发现精度影响不大)换取速度,直方图作差构建叶子直方图挺有创造力的。(xgboost的分布式实现也是基于直方图的,利于并行)②带有深度限制的按叶子生长 (leaf-wise) 算法代替了传统的(level-wise) 决策树生长策略,提升精度,同时避免过拟合危险。

参考:

https://www.zhihu.com/question/51644470/answer/130946285
https://github.com/Microsoft/LightGBM/wiki/Features
https://ye980226.github.io/XGB.html

https://blog.youkuaiyun.com/sb19931201/article/details/52557382

### XGBoost分类算法介绍 XGBoost(Extreme Gradient Boosting)是一种可扩展的、分布式的梯度提升库,由陈天奇等人开发。它在传统梯度提升算法的基础上进行了一系列优化,具有高效、灵活且可扩展的特点,在各类机器学习竞赛和实际应用中都取得了很好的效果。XGBoost不仅可以用于分类问题,还能处理回归和排序等任务。在分类问题中,它能够处理二分类和多分类问题,输出样本属于各个类别的概率。 ### 原理 XGBoost基于梯度提升框架,其核心思想是通过迭代训练一系列的弱分类器(通常是决策树),并将它们组合成一个强分类器。具体步骤如下: - **初始化**:首先初始化一个常量作为初始预测值,通常是所有样本标签的均值。 - **迭代训练**:在每一轮迭代中,XGBoost会训练一个新的决策树,该决策树的目标是拟合前一轮迭代模型的残差。残差是指样本的真实标签与前一轮模型预测值之间的差值。为了找到最优的决策树结构,XGBoost使用了一种贪心算法,通过枚举所有可能的分割点,选择能够最大程度降低目标函数的分割点。 - **目标函数**:XGBoost的目标函数由两部分组成,即损失函数和正则化项。损失函数用于衡量模型的预测值与真实标签之间的差异,常见的损失函数有对数损失函数(用于分类问题)和平方损失函数(用于回归问题)。正则化项用于控制模型的复杂度,防止过拟合,它包括树的叶子节点数量和叶子节点的权重的平方和。 - **模型融合**:每一轮训练得到的决策树会乘以一个学习率(也称为步长),然后累加到前一轮的模型中,得到当前轮的模型。学习率的作用是控制每一轮迭代的步长,避免模型过拟合。 ### 应用 - **金融领域**:用于信用风险评估,根据客户的个人信息、信用历史等特征,预测客户是否会违约;也可用于欺诈检测,识别异常的交易行为。 - **医疗领域**:疾病诊断,根据患者的症状、检查结果等数据,判断患者是否患有某种疾病;还可用于疾病预后预测,预测患者的治疗效果和生存情况。 - **电商领域**:商品推荐,根据用户的浏览历史、购买记录等信息,向用户推荐可能感兴趣的商品;用户流失预测,预测用户是否会流失,以便采取相应的营销策略。 ### 使用方法 以下是使用Python和Scikit - learn接口的XGBoost库进行分类任务的示例代码: ```python import xgboost as xgb from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # 加载数据集 iris = load_iris() X = iris.data y = iris.target # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 创建XGBoost分类器 model = xgb.XGBClassifier(objective='multi:softmax', num_class=3, learning_rate=0.1, n_estimators=100, max_depth=3) # 训练模型 model.fit(X_train, y_train) # 预测 y_pred = model.predict(X_test) # 计算准确率 accuracy = accuracy_score(y_test, y_pred) print(f"Accuracy: {accuracy}") ``` 在上述代码中,首先加载了鸢尾花数据集,并将其划分为训练集和测试集。然后创建了一个XGBoost分类器,设置了目标函数为`multi:softmax`用于多分类问题,指定类别数量为3。接着使用训练集对模型进行训练,最后使用测试集进行预测,并计算预测的准确率。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值