集成学习方法(组合分类器)

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的实现,可能具有以下的一些优势:

  1. 显式地将树模型的复杂度作为正则项加在优化目标
  2. 公式推导里用到了二阶导数信息,而普通的GBDT只用到一阶
  3. 允许使用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挺不错的

你可能感兴趣的:(集成学习方法(组合分类器))