1. 引言
典型的集成学习方法有bagging, boosting以及随机森林,stacking也是一种集成学习方法。本文参考《数据挖掘导论》,简单回顾一下几种集成学习方法的要点。
2. 集成学习方法
一般而言,构建组合分类器的方法有以下几种:
(1)基于训练数据集的处理,如bagging和boosting
(2)基于输入特征的处理,如随机森林,以决策树为基分类器。
(3)基于类别号的处理,适用于类别较多的情况,通过将训练集划分成正交的两个子集,分别编码为0和1,然后通过二分法分别迭代两个子集,最后构建成一个组基分类器。通过统计基分类器的投票数来完成分类。如错误-纠正输出编码(error-correcting output coding, ECOC)方法就是这种方法一个例子
(4)基于学习的处理,在同一个训练数据集上多次执行算法可能得到不同的模型,通过多次执行训练生成多个基分类器
算法: 组合方法的一般流程 |
---|
输入:原始训练集,表示基分类器的个数,表示检验数据集 |
输出:组合基分类器和分类结果 |
1: for =1 to do |
2: 由创建训练集 |
3: 由构建基分类器 |
4:end for |
5:for 每一个检验样本 do |
6: |
7:end for |
2.1 Bagging
装袋(bagging)是一种根据均匀分布从数据集中重复抽样(有放回)的技术。通过有放回的抽样构建出个自助样本集,每个自助样本集与原始训练集一样大。然后分别在个自助样本集上训练出个基分类器,最后对所有检验样本进行投票判决分类,选取票数最多的一类作为预测输出。
(自助样本集中大约包含63%的原始训练数据,因为每一个样本抽到中的概率为,N足够大时这个概率收敛于.)
算法: 组合方法的一般流程 |
---|
输入:原始训练集,表示基分类器的个数,表示检验数据集 |
输出:组合基分类器和分类结果 |
1: for =1 to do |
2: 由创建训练集 |
3: 由构建基分类器 |
4:end for |
5:for 每一个检验样本 do |
6: ,其中\delta()为一个布尔函数 |
7:end for |
2.2 Boosting
提升方法中比较典型的几种算法就是Adaboost,Gradient Boost Tree,以及现在非常火热的xgboost。
2.2.1 Adaboost方法
Adaboost通过自适应地改变训练样本的分布,使得基分类器在迭代训练过程中更加关注很难分类的样本。对每一个样本都赋予了一个权值,每一轮迭代结束时都自动地调整样本的权值。为了简洁这里仅给出算法流程,具体细节可以参考李航《统计学习方法》,讲的非常详细。
算法:Adaboost算法 |
---|
1: //对数据集中所有样本都赋予相同的权重 |
2:令k表示提升轮次 |
3: for to do //开始k个轮次的迭代 |
4: 根据,通过对进行抽样产生训练集 //产生第i轮迭代中的数据集 |
5: 在训练集上训练分类器 //在第i轮的子集上产生第i轮的基分类器 |
6: 用分类器对数据集进行分类 |
7: ,计算加权误差 //利用当前所有样本所具有的权值来计算误差总和 |
8: if then //误差大于0.5,相当于比瞎猜还差,所以需要重新初始化权值,重新学习 |
9: |
10: 返回步骤4 |
11: end if |
12: //如果错误率还可以接受,那么就用错误率去计算一个权重衰减因子 |
13: 更新每个样本的权值: |
当时,; //预测正确时减小样本权值 |
当时,; //预测错误时加大样本权值 |
14:end for |
15: //利用集成的分类器对所有样本进行分类 |
在上述算法中,通过k个轮次的学习,实际上得到了k个基分类器,我们构建这些基分类器的线性组合就得到了最终的分类器。
2.2.2 GBDT方法
关于Gradient Boost Decision Tree,个人感觉更像是一种策略,利用上一轮的残差来继续学习。李航《统计学习方法》中先讲了提升树,然后讲了梯度提升,两者之间的差别就在于残差的表示:
提升树中的残差:
梯度提升的残差:
提升树的基本思想
提升树实际上也可以看作多个树的线性组合,通过多个轮次的提升得到最后的提升树。
用表示第k步得到的提升树;假设总共迭代了K个轮次,则有最终得到的决策树为:
上面式子中每次需要拟合得到的树都有一个参数需要确定,通过优化这个参数,我们才可以得到更理想的树。我们假设需要通过这个参数来确定损失函数,定义损失函数可以使问题更加一般化,变成一个算法框架(陈天奇大佬说的,我也觉得挺有道理,定量分析优化好像比启发式的学习更有理论上的说服力),于是我们先抽象出一个损失函数:
然后通过来优化它,这貌似也是机器学习里优化模型惯用的套路。
这里损失函数具体是什么还没有明确下来,《统计学习方法》中以平方误差作为了损失函数举例,后面会给出推导。但我们先顺着思路来继续看看提升树基本思想的最后一步——求残差。
利用这个残差就可以进行下一棵树的学习了。写到这里我也有点懵逼,树是怎么学习的呢?ok,这里讲的是提升方法,先把树是怎么学习的这个问题放在一边,它是另外一个问题,不要让他打搅我们的思路,暂且默认你知道树是怎么学习得来的。因此,这里总结一下提升方法的算法流程
提升树算法 |
---|
输入:训练集 |
输出:提升树 |
1:初始化 |
2:for do |
3: 计算残差 |
4: 拟合残差学习回归树,得到 |
5: 更新树 |
6:end for |
7:得到提升树 |
平方误差损失函数
上面提到了平方误差损失函数,这里给出式子:
再将代入后可以得到:
再次强调,这里的残差就是实际值和预测值之间的差值:
梯度提升方法中的残差
通过上面的描述,我们抽象出了一个损失函数,当损失函数是平方损失函数或者指数损失函数时,优化是比较容易的。但是对于更加一般化的损失函数来说优化并不容易,因此引入了梯度的概念,目的就是为了减少上一步中的残差,利用负梯度对模型进行优化。 梯度提升树中的残差就定义为了负梯度。
负梯度:
给出梯度提升树的算法流程
梯度提升树算法 |
---|
输入:训练集 |
输出:提升树 |
1:初始化 |
2:for do |
3: 计算残差 |
4: 拟合残差学习回归树,得到 |
5: 更新树 |
6:end for |
7:得到梯度提升树 |
xgboost方法
GBDT和xgboost的区别
转载一下知乎上的一个回答
作者:黄真川
链接:https://www.zhihu.com/question/41354392/answer/91371364
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
首先xgboost是Gradient Boosting的一种高效系统实现,并不是一种单一算法。xgboost里面的基学习器除了用tree(gbtree),也可用线性分类器(gblinear)。而GBDT则特指梯度提升决策树算法。
xgboost相对于普通gbm的实现,可能具有以下的一些优势:
- 显式地将树模型的复杂度作为正则项加在优化目标
- 公式推导里用到了二阶导数信息,而普通的GBDT只用到一阶
- 允许使用column(feature) sampling来防止过拟合,借鉴了Random Forest的思想,sklearn里的gbm好像也有类似实现。
4.实现了一种分裂节点寻找的近似算法,用于加速和减小内存消耗。
5.节点分裂算法能自动利用特征的稀疏性。
6.data事先排好序并以block的形式存储,利于并行计算
7.cache-aware, out-of-core computation,这个我不太懂。。
8.支持分布式计算可以运行在MPI,YARN上,得益于底层支持容错的分布式通信框架rabit。
参考资料:
chentq的slides http://homes.cs.washington.edu/~tqchen/pdf/BoostedTree.pdf
chentq的paper http://arxiv.org/abs/1603.02754
chentq在52cs上的中文博文 http://www.52cs.org/?p=429
微博上分享的xgboost导读和实战.pdf
参考这些大佬:
https://blog.csdn.net/niuniuyuh/article/details/76922210
http://www.cnblogs.com/LeftNotEasy/archive/2011/03/07/random-forest-and-gbdt.html
https://blog.csdn.net/lc013/article/details/56667157
https://www.zhihu.com/question/41354392
另外极力推荐这个大佬的主页 http://wepon.me/
https://blog.csdn.net/sb19931201/article/details/52557382讲xgboost挺不错的