模型融合方式:
· 均值法Averaging:适用于回归类算法,将每个评估器的输出做平均,类似于Bagging中回归的做法。
· 投票法Voting: 适用于分类算法,将每个评估器的输出进行投票, 类似于Bagging中分类的做法
· 堆叠法Stacking: 使用一个/多个算法在训练集上输出的某种结果作为下一个算法的训练数据。
· 改进堆叠法Blending: 一种特殊的stacking, 使用一个/多个算法在验证集上输出的某种结果作为下一个算法的训练数据。
一 投票法Voting:
1 五大类投票方法
(1)相对多数投票
只要有一个类别占比较多即可
(2)绝对多数投票
要求至少有50%或者以上的分类器都输出了同一类别,否则拒绝预测。
(3)硬投票
将不同类别的出现次数进行计数,出现次数最多的类别就是投票结果。
(4)软投票
将不同类别下的概率进行加和,概率最高的类别就是投票结果。基于概率的软投票可以衡量投票的置信程度, 某一类别下的概率越高, 说明该模型对该类别的预测结果越有信心。
(5)加权投票
加权投票是在投票过程中赋予不同分类器权重的投票,具体表现在:
· 对于硬投票,加权投票可以改变每一个分类器所拥有的票数。
· 对于软投票,加权投票可以改变每一个分类器所占的权重,令概率的普通加和变成加权求和。
2 模型融合流程(分类问题)
(1)建立基于交叉验证的benchmark、做模型选择
在模型融合前,需将可能有用的算法简单运行一次,从中调选出表现较好的算法作为融合的基础。找到单一算法可以实现的最好分数来作为benchmark,然后将融合后的模型与benchmark进行比较。
(2)构建多组分类器, 进行融合
进行投票或者平均融合后,结果反而没有单个算法好,可能是以下原因:
1. 评估器之间的学习能力/模型表现差异太大。 在融合中,一个表现很差的模型会拉低整个融合模型的上限,尤其是回归类算法,所以应当剔除差得模型。
2. 评估器在类型上过于相似。比如都是树模型、都是Boosting算法,如果平均/投票的评估器都一致,那融合模型最终得出的结果也会与单个评估器一致。
3. 对评估器进行了过于精密的调优。经过粗略调优的评估器融合能够提升模型表现, 但如果对评估器进行过于精密的调优, 可能会让融合后的算法处于严重过拟合的状态。
3 构建多样性
在模型融合中,独立性被称为多样性,评估器之间的差别越大、彼此之间就越独立,因此评估器越多样,独立性就越强。
以下方法,用来让评估器变得更多样,让评估器之间相互独立:
· 训练数据多样性: 完成多组有效的特征工程,使用不同的特征矩阵训练不同的模型。但如何找出多组有效的特征工程是难题。
· 样本多样性: 使用相同的特征矩阵, 但每次训练时抽样出不同的样本子集进行训练。
· 特征多样性: 使用相同特征矩阵, 但每次训练时抽样出不同的特征子集进行训练。
· 随机多样性/训练多样性: 使用相同的算法,但使用不同的随机数种子(会导致使用不同的特征、样本、起点)、或使用不同的损失函数、使用不同的不纯度下降量等。
· 算法多样性: 增加类型不同的算法,如集成、树、概率、线性模型相混合。
二 堆叠法Stacking
1 Stacking基本思想
Stacking集模型效果好、可解释性强、适用复杂数据
Stacking由两层组成,分别为level 0和level 1,level 0中包含一个或多个强学习器,而level 1只能包含一个学习器。在训练过程中,level 0先进行训练,level 0中的每个算法会输出相应的预测结果(验证集),将这些预测结果拼凑成新特征矩阵,再输入level 1的算法进行训练。融合模型最终输出的预测结果就是level 1的学习器输出的结果。
在训练过程中,level 0输出的预测结果一般如下排布:
注意:
level 0上的学习器是复杂度高、学习能力强的学习器,如继承算法。而level 1上的学习器是可解释性强、较为简单的学习器,如决策树、线性回归、逻辑回归等。
有这样的要求是因为level 0上的算法目的是找出原始数据与标签的关系、建立原始数据与标签之间的假设,因此需要强大的学习能力。level 1上的算法的职责是融合个体学习器做出的假设、并且最终输出融合模型的结果,相当于在寻找“最佳融合规则”。
2 Stacking细节问题
(1)要不要对融合的算法进行精密的调参?
个体学习器粗调,元学习器精调,如果不过拟合的话,可以两类学习器都精调
(2)个体学习器算法要怎么样选择才能最大化stacking的效果?
控制过拟合、增加多样性、注意算法整体的运算时间。
(3)个体学习器可以是复杂度较低的算法吗?元学习器可以是Xgboost这种复杂度很高的算法吗?
都可以,以模型效果为准。
(4)level 0和level 1的算法可不可以使用不同的损失函数?
可以,不同的损失函数衡量的是类似的差异,不过不同的损失对于差异的敏感性不同,尽量使用相似的损失函数。
(5)level 0和level 1的算法可不可以使用不同的评估指标?
必须使用相同的模型评估指标
3 Stacking中的交叉验证
(1)元学习器的特征矩阵的两个问题:
· 元学习器的特征矩阵中的特征一定很少
特征矩阵中的特征数就等于个体学习器的个数
·元学习器的特征矩阵中样本量也不太多
因为元学习器的特征矩阵为level 0在验证集上的输出结果,验证集的样本量有限
因此可使用交叉验证来造特征矩阵
对任意个体学习器来说,假设执行5折交叉验证,会将训练数据分成5份,并按照4份训练、1份验证的方式总共建立5个模型,训练5次,注意每个学习器都要执行一次5折交叉验证,注意是一个学习器分别执行这5次验证,并不是正常的迭代训练执行,因此不会泄露数据。
某个 个体学习器的训练过程如下图所示:
个体学习器最终输出的列为上图中的5个预测结果拼接:
最终,任意个体学习器的输出的预测值数量 = 样本量
数据量够大,使用过多的交叉验证折数并不会带来好处,更可能让训练时间降低。
4 Stratified K折交叉验证
Stratified K折验证会考虑标签中每个类别占比的交叉验证,每次训练时交叉验证会保证
原始标签中的类别比例 = 训练标签的类别比例 = 验证标签的类别比例。
5 特征太少的解决方案
sklearn中StackingClassifier的参数stack_method(这个参数只用于分类问题,因为回归问题输出的只能是标签):
正常情况下,一个个体学习器只能输出一列的预测结果,但如果把输出的结果类型更换为概率值、置信度等内容,输出结果的结构就可以从一列扩展为多列。
这个操作由参数stack_method控制,stack_method里面可以输入四种字符串:
"auto","predict_proba","decision_function","predict"
· predict_proba 是输出概率值
对n分类,输出样本的真实标签为[0,1,2,3…n]的概率,一共n列
· decision_function 是每个样本点到分类超平面的距离,可以衡量置信度
对n分类,输出样本的真实标签为[0,1,2,3…n]的置信度,一共n列
· predict 输出具体的预测标签
对任何分类形式,输出算法在样本上的预测标签,一列
6 Stacking融合的训练/测试流程
*测试流程:
(1)细节问题:
· 最终输出预测结果的是元学习器,直觉上来说测试数据集或许应该被输入到元学习器当中。然而,元学习器是使用新特征矩阵进行预测的,新特征矩阵的结构与规律都与原始数据不同。所以元学习器不可能接受从原始数据中分割出来的测试数据,正确的做法应该是让测试集输入level 0的个体学习器。
· level 0 的个体学习器们在训练过程中做的是交叉验证,而交叉验证只会输出验证结果,不会留下被训练的模型。因此在level 0中没有可以用于预测的、已经训练完毕的模型。
解决方法:
训练时,在交叉验证完成后,使用全部训练数据对所有个体学习器进行训练,为测试做好准备
stacking的测试:
1.将测试集输入level 0的个体学习器,分别在每个个体学习器上预测出相应结果,拼接起来作为标签。
2.将新特征矩阵放入元学习器进行预测。
因此在stacking中,不仅要对个体学习器完成全部交叉验证,还需要在交叉验证结束后,重新使用全部训练数据来训练所有的模型。
需要注意:想要对原生代码下的模型进行融合,必须自己手写融合过程。
三 改进后的堆叠法: Blending
Blending在训练过程中,level 0输出的是验证集的结果,并没有做K折交叉验证,即level 1的特征矩阵就是验证集对应的大小,学习的东西少一些,模型抗过拟合能力越强。(数据量庞大的情况下可用)
数据量很小的情况下,stacking和blending都无法有效使用,实际中,stacking的应用比blending广泛。