模型融合可以说是一个取长补短的过程,我们先产生一组个体的学习器,之后通过某一种策略将它们给联合起来,可以达到加强模型的效果的。综合个体学习器的优势依次来降低误差、优化整体的模型性能,个体的准确率越高、多样性越大,模型的效果当然也就是越好的。
模型融合是比赛后期一个重要的环节,大体来说有如下的类型方式。
- 简单加权融合:
- 回归(分类概率):算术平均融合(Arithmetic mean),几何平均融合(Geometric mean);
- 分类:投票(Voting)
- 综合:排序融合(Rank averaging),log融合
- stacking/blending:
- 构建多层模型,并利用预测结果再拟合预测。
- boosting/bagging(在xgboost,Adaboost,GBDT中已经用到):
- 多树的提升方法
1、简单加权融合:
简单加权融合就是我们预测三个多个预测之后,我们多每一个预测数据进行加权,进行权重分配,也就是多组数求加权平均值,下面例子就是三个预测值,每一个进行1/3进行平均的加权
简单平均和加权平均是常用的两种比赛中模型融合的方式。其优点是快速、简单。
import numpy as np import pandas as pd from sklearn import metrics ## 生成一些简单的样本数据,test_prei 代表第i个模型的预测值 test_pre1 = [1.2, 3.2, 2.1, 6.2] test_pre2 = [0.9, 3.1, 2.0, 5.9] test_pre3 = [1.1, 2.9, 2.2, 6.0] # y_test_true 代表第模型的真实值 y_test_true = [1, 3, 2, 6] ## 定义结果的加权平均函数 def Weighted_method(test_pre1,test_pre2,test_pre3,w=[1/3,1/3,1/3]): Weighted_result = w[0]*pd.Series(test_pre1)+w[1]*pd.Series(test_pre2)+w[2]*pd.Series(test_pre3) return Weighted_result
各模型的预测结果计算MAE
MAE值平均绝对误差,范围[0,正无穷符号],越大误差越大
print('Pred1 MAE:',metrics.mean_absolute_error(y_test_true, test_pre1)) print('Pred2 MAE:',metrics.mean_absolute_error(y_test_true, test_pre2)) print('Pred3 MAE:',metrics.mean_absolute_error(y_test_true, test_pre3)) ## 根据加权计算MAE w = [0.3,0.4,0.3] # 定义比重权值 Weighted_pre = Weighted_method(test_pre1,test_pre2,test_pre3,w) print('Weighted_pre MAE:',metrics.mean_absolute_error(y_test_true, Weighted_pre))
Pred1 MAE: 0.1750000000000001 Pred2 MAE: 0.07499999999999993 Pred3 MAE: 0.10000000000000009 Weighted_pre MAE: 0.05750000000000027
## 定义结果的加权平均函数 def Mean_method(test_pre1,test_pre2,test_pre3): Mean_result = pd.concat([pd.Series(test_pre1),pd.Series(test_pre2),pd.Series(test_pre3)],axis=1).mean(axis=1) return Mean_result Mean_pre = Mean_method(test_pre1,test_pre2,test_pre3) print('Mean_pre MAE:',metrics.mean_absolute_error(y_test_true, Mean_pre))
## 定义结果的加权平均函数 def Median_method(test_pre1,test_pre2,test_pre3): Median_result = pd.concat([pd.Series(test_pre1),pd.Series(test_pre2),pd.Series(test_pre3)],axis=1).median(axis=1) return Median_result Median_pre = Median_method(test_pre1,test_pre2,test_pre3) print('Median_pre MAE:',metrics.mean_absolute_error(y_test_true, Median_pre)) # 平均值和中位数误差
Mean_pre MAE: 0.06666666666666693 Median_pre MAE: 0.07500000000000007
可以看出我们将不同result结合在一起,之后给他们一个简单的权重(比如中位数,平均值,分位数,自定义权重等)
一般来说这种方式只是一种上分技巧,想要达到某种程度应该还是有限的,毕竟局限性在那里
2、Stacking融合(回归)
stacking是一种分层模型集成框架。以两层为例,第一层由多个基学习器组成,其输入为原始训练集,第二层的模型则是以第一层基学习器的输出作为特征加入训练集进行再训练,从而得到完整的stacking模型。stacking的方法在各大数据挖掘比赛上都很风靡,模型融合之后能够小幅度的提高模型的预测准确度。
stacking可以说不一定是一个算法,他是融合的结果,以两层为例,第一层可以构成多个学习器(也就就是模型)得到预测结果之后,把这个预测结果作为新的特征,再去放到第二层学习器中为训练集,与真实值学习,可以得到结果,这样可能提高预测准确率的。其实也就是产生一个“预测”特征去预测特征。
from sklearn import linear_model def Stacking_method(train_reg1,train_reg2,train_reg3,y_train_true,test_pre1,test_pre2,test_pre3,model_L2= linear_model.LinearRegression()): model_L2.fit(pd.concat([pd.Series(train_reg1),pd.Series(train_reg2),pd.Series(train_reg3)],axis=1).values,y_train_true) Stacking_result = model_L2.predict(pd.concat([pd.Series(test_pre1),pd.Series(test_pre2),pd.Series(test_pre3)],axis=1).values) return Stacking_result ## 生成一些简单的样本数据,test_prei 代表第i个模型的预测值 train_reg1 = [3.2, 8.2, 9.1, 5.2] train_reg2 = [2.9, 8.1, 9.0, 4.9] train_reg3 = [3.1, 7.9, 9.2, 5.0] # y_test_true 代表第模型的真实值 y_train_true = [3, 8, 9, 5] test_pre1 = [1.2, 3.2, 2.1, 6.2] test_pre2 = [0.9, 3.1, 2.0, 5.9] test_pre3 = [1.1, 2.9, 2.2, 6.0] # y_test_true 代表第模型的真实值 y_test_true = [1, 3, 2, 6] model_L2= linear_model.LinearRegression() Stacking_pre = Stacking_method(train_reg1,train_reg2,train_reg3,y_train_true, test_pre1,test_pre2,test_pre3,model_L2) print('Stacking_pre MAE:',metrics.mean_absolute_error(y_test_true, Stacking_pre))
Stacking_pre MAE: 0.042134831460675204
可以发现模型结果相对于之前有进一步的提升,这是我们需要注意的一点是,对于第二层Stacking的模型不宜选取的过于复杂,这样会导致模型在训练集上过拟合,从而使得在测试集上并不能达到很好的效果。
3、 分类模型融合
3.1、Voting投票机制
Voting即投票机制,分为软投票和硬投票两种,其原理采用少数服从多数的思想。
3.2、Stacking和Blending融合:
stacking是一种分层模型集成框架。
以两层为例,第一层由多个基学习器组成,其输入为原始训练集,第二层的模型则是以第一层基学习器的输出作为训练集进行再训练,从而得到完整的stacking模型, stacking两层模型都使用了全部的训练数据。
- Blending与stacking的不同
stacking中由于两层使用的数据不同,所以可以避免信息泄露的问题。在组队竞赛的过程中,不需要给队友分享自己的随机种子。 - Blending
由于blending对将数据划分为两个部分,在最后预测时有部分数据信息将被忽略。同时在使用第二层数据时可能会因为第二层数据较少产生过拟合现象。
3.3、Blending
其实和Stacking是一种类似的多层模型融合的形式
其主要思路是把原始的训练集先分成两部分,比如70%的数据作为新的训练集,剩下30%的数据作为测试集。
在第一层,我们在这70%的数据上训练多个模型,然后去预测那30%数据的label,同时也预测test集的label。
在第二层,我们就直接用这30%数据在第一层预测的结果做为新特征继续训练,然后用test集第一层预测的label做特征,用第二层训练的模型做进一步预测
其优点在于
比stacking简单(因为不用进行k次的交叉验证来获得stacker feature)
避开了一个信息泄露问题:generlizers和stacker使用了不一样的数据集
缺点在于:
使用了很少的数据(第二阶段的blender只使用training set10%的量)
blender可能会过拟合
stacking使用多次的交叉验证会比较稳健
4、总结
- 简单平均和加权平均是常用的两种比赛中模型融合的方式。其优点是快速、简单。
- stacking在众多比赛中大杀四方,但是跑过代码的小伙伴想必能感受到速度之慢,同时stacking多层提升幅度并不能抵消其带来的时间和内存消耗,所以实际环境中应用还是有一定的难度,同时在有答辩环节的比赛中,主办方也会一定程度上考虑模型的复杂程度,所以说并不是模型融合的层数越多越好的。
- 当然在比赛中将加权平均、stacking、blending等混用也是一种策略,可能会收获意想不到的效果哦!
- 最后模型的融合在本次学习中,介绍了几种融合方法,使用融合可以很好的提高准确率这也是我们提高成绩的一大法宝。另外文章中有不足之处,请务必指出,一定迅速改正。谢谢
最后本次学习赛已经结束,在这次学习赛中学习到很多知识。打开结束,但是上分并未停止。