之前主要介绍单机器学习算法的理解和使用,实际场景多使用集成学习即组合的挖掘算法以达到最优效果,集成学习有2种:Boosting和Bagging,前者通过多个串行的弱学习器得到强学习器(GBDT、XoostGB、LightGBM),后者通过并行的多个决策树投票实现最优模型(随机森林RF),在竞赛中一般直接使用集成学习,因为可以最大程度地保证模型性能;
真实场景和竞赛一般直接采用集成算法,因为单个算法就像现实中的单个决策者容易造成误差,集成算法通过抽样数据/特征或者刻意减少模型误差率的策略最大程度地降低最终模型误差,分2种:① 弱学习器间存在强依赖关系,必须串行生成的序列化方法,代表:Boosting;② 弱学习器间不存在强依赖关系,可同时生成的并行化方法,代表:Bagging和随机森林(Random Forest),可以参考sklearn中文社区:集成学习算法详细
一、Bagging和随机森林
Bagging装袋法集成学习,通过抽样样本/数据集并行地训练弱学习器,策略函数是均方差最小化,训练得到系列弱学习器后再使用某种结合策略(投票或者求平均机制)形成模型结果,随机森林即是通过有放回地抽样数据/特征来构建并行决策树形成准确率较高的模型,算法流程如下:
Bagging使用随机采样(bootsrap)从训练集里面有放回地抽样固定m个样本,抽取T次,每次抽取的m个样本的内容不同,对于1个样本在随机采样中被采集到的概率是1/m,不被采集到的概率为1−1/m,如果T次采样都没有被采集的概率是(1−1/m)^T,当T→∞时,(1−1m)^m→1/e≃0.368。也就是说bagging的每轮随机采样中,训练集中大约有36.8%的数据没有被采样,对于这部分大约36.8%的没有被采样到的数据称为袋外数据(Out Of Bag, 简称OOB),这些数据没有参与训练集模型的拟合,因此可以用来检测模型的泛化能力。
和Adaboost一样,bagging对于弱学习器没有限制,常用决策树和神经网络,同时bagging的结合策略也较简单,分类问题使用简单投票法,得到最多票数的类别或者类别之一为最终的模型输出,回归问题使用简单平均法对T个弱学习器得到的回归结果进行算术平均得到最终的模型输出,由于Bagging算法采样训练模型,因此泛化能力强,对于降低模型的方差很有作用。
随机森林(Random Forest)是Bagging的进化版,类似于GBDT使用CART决策树作为弱学习器,其次RF对决策树选取部分特征的最大基尼系数特征作为分类依据,除上面2点,RF和普通的bagging算法没什么不同;
二、Boosting和GBDT、XGBoost、LightGBM
Boosting算法策略是先用初始权重训练出一个弱学习器1,根据弱学习的学习误差率更新训练样本的权重,使得之前弱学习器学习误差率高的训练样本点的权重变高,使得这些误差率高的点在后面的弱学习器中得到更多的重视,然后基于调整权重后的训练集来训练弱学习器,如此重复直到弱学习器数达到事先指定的数目T,最终将这T个弱学习器通过集合策略进行整合,得到最终的强学习器,其解决4个问题:① 如何计算学习误差率? ②如何得到弱学习器权重系数? ③如何更新样本权重? ④使用何种结合策略?
GBDT是以决策树为基学习器的迭代算法,注意GBDT里的决策树都是回归树而不是分类树,Boost是”提升”的意思,一般Boosting算法都是一个迭代的过程,每一次新的训练都是为了改进上一次的结果。GBDT的核心就在于:每一棵树学的是之前所有树结论和的残差,这个残差就是一个加预测值后能得真实值的累加量。比如A的真实年龄是18岁,但第一棵树的预测年龄是12岁,差了6岁,即残差为6岁。那么在第二棵树里我们把A的年龄设为6岁去学习,如果第二棵树真的能把A分到6岁的叶子节点,那累加两棵树的结论就是A的真实年龄;如果第二棵树的结论是5岁,则A仍然存在1岁的残差,第三棵树里A的年龄就变成1岁,继续学习;
参考:详细描述
XGBoost华盛顿大学的算法:① 对GBDT是加了剪枝,控制了模型的复杂程度;② 增加基分类选型;③ 能够支持并行;
-
# xgb参数
-
params = {
-
'booster':
'gbtree',
-
'min_child_weight':
100,
-
'eta':
0.02,
-
'colsample_bytree':
0.7,
-
'max_depth':
12,
-
'subsample':
0.7,
-
'alpha':
1,
-
'gamma':
1,
-
'silent':
1,
-
'objective':
'reg:linear',
-
'verbose_eval':
True,
-
'seed':
12
-
}
LightGBM:微软开源算法,是XGBoost的改进版,关于XGboost的不足之处主要有:① 每轮迭代时,都需要遍历整个训练数据多次。如果把整个训练数据装进内存则会限制训练数据的大小;如果不装进内存,反复地读写训练数据又会消耗非常大的时间;② 预排序方法的时间和空间的消耗都很大;
LightGBM 基于直方图的稀疏特征优化,减少并行的通信开销,同时数据分割复杂度更低一些;
-
# lgb的参数
-
params = {
-
'task':
'train',
-
'boosting_type':
'gbdt',
# 设置提升类型
-
'objective':
'regression',
# 目标函数
-
'metric': {
'l2',
'auc'},
# 评估函数
-
'num_leaves':
31,
# 叶子节点数
-
'learning_rate':
0.05,
# 学习速率
-
'feature_fraction':
0.9,
# 建树的特征选择比例
-
'bagging_fraction':
0.8,
# 建树的样本采样比例
-
'bagging_freq':
5,
# k 意味着每 k 次迭代执行bagging
-
'verbose':
1
# <0 显示致命的, =0 显示错误 (警告), >0 显示信息
-
}
转载:https://blog.csdn.net/yezonggang/article/details/112675370