翻译链接:http://blog.csdn.net/a353833082/article/details/50768140
英文链接:http://mlwave.com/kaggle-ensembling-guide/
模型融合技术可以提高一系列机器学习任务的准确率。在这篇文章中我将会分享大家一些在kaggle比赛中常用的融合方法。
第一部分我们介绍利用提交的文件创建融合模型。第二部分我们通过堆栈泛化创建融合模型。我回答了为什么融合能够减少泛化误差。最后我列举了不同的融合方法以及他们的代码供你们去尝试。
最方便也是最基本的融合是通过将kaggle的提交文件进行融合。你只需要这些方法得到的预测结果,而不需要重新训练一个模型。这使得他成为一个快速的方法来融合已经存在的预测结果和队友的想法。
投票融合:
我们先看一下简单的少数服从多数投票融合。为什么模型融合减少了泛化误差并且为什么在不太相关的模型结果上会表现的更好。
错误校正编码:
在航天任务中信号能否正确传输是很重要的。如果我们有一个用二进制表示的信号如下:
1110110011101111011111011011。如果信号在传输过程中有一位发生了翻转,变成了1010110011101111011111011011。然后就造成了信号的失真。于是我们发明了校验码用来检测错误的编码。最简单的错误校正码是重复码:多次传递信号,然后做一个少数服从多数的投票。例如:
Original signal:
1110110011
Encoded:
10,3 101011001111101100111110110011
Decoding:
1010110011
1110110011
1110110011
Majority vote:
1110110011
信号失真是一种比较特殊的情况并且经常发生在局部。因此,多次投票依然出错的概率就更小了。只要信号失真的概率小于50%信号就是可以被修复的。
下面举一个机器学习的例子:
假设我们的测试集有10个样本。正确的标准应该全是1.然后我们有三个二分类器A,B,C。他们的准确率为70%。你可以把这些分类器看做一个伪随机数生成器。有70的概率生成1,30%的概率生成0.下面我们说明怎么用这些伪分类器获得78%的准确率。
对于一个少数服从多数的投票方法,我们用着三个分类器可以得到四种可能的结果:
All three are correct
0.7 * 0.7 * 0.7
= 0.3429
Two are correct
0.7 * 0.7 * 0.3
+ 0.7 * 0.3 * 0.7
+ 0.3 * 0.7 * 0.7
= 0.4409
Two are wrong
0.3 * 0.3 * 0.7
+ 0.3 * 0.7 * 0.3
+ 0.7 * 0.3 * 0.3
= 0.189
All three are wrong
0.3 * 0.3 * 0.3
= 0.027
我们看到在44%的情况下投票可以校正一个错误。这使得最终的准确率变成44%+34%=78%。
投票者的个数:
跟重复码相似,随着编码重复次数的增加对错误的校正能力也就增加。因此融合通常可以通过提高融合成员的个数来提升。
利用相似的数学推导我们可以得出,由五个准确率70%伪随机分类器可以将准确率提高到83%。
相关性:
当我们第一次参加2014年的KDD杯时,Marios Michailidis提出了一些奇怪的事情。他计算了我们所有提交的皮尔逊相关系数,然后选择一些表现好但又相互不太相关的模型。
通过多个结果的平均融合,我们获得了50名的进步。不相关的结果明显比相关的结果融合得来的要好。
在kaggle中的使用:森林覆盖类型预测
多数投票方法通常在评价度量要求硬预测结果的时候更有效。森林覆盖类型预测使用UCI森林覆盖类型数据集。这个数据集有54个属性和6个类别。我们创建了一个简单的初始模型。这个模型由500颗随机森林构成。然后我们创建了更多的模型并且选出其中表现最好的那个。对于这个任务,我们的模型选择发现ExtraTreesClassifier表现最好。
加权:
然后我们使用一个加权的大多数投票方法。为什么要加权呢?因为通常我们想要获得一个更好的模型在投票的时候有更大的权重。因此在我们的案例中我们把最好的模型的一次投票当做三次,其他四个模型的投票只当做一次。这么做的理由如下:这是唯一的方法避免被质量差的模型推翻质量好的模型的结果。
可以预计这样的融合可以修复一些好的模型的错误结果,然后获得一个更好的结果。
在kaggle中的使用:CIFAR-10图像中的物体检测
CIFAR-10是有一个多类分类问题,然后需要优化预测准确率。
我们的队伍领导者第一个发现如何重复利用一个好的模型。然后他利用30个卷积神经昂罗获得的提交结果进行投票。然后获得了0.01的提升。这使得结果超过了人类的分类准确率。
平均:
平均在一系列任务上有重要的作用。在分类和回归中,以及在不同的度量中如AUC,均方误差,和对数损失中都有重要作用。
平均可以减少过拟合。你希望在两个类之间获得一个平滑的分割平面。但是一个单一的模型的预测结果在边界上可能是粗糙的。
上图是来自kaggle比赛的一副图。黑色的先表现要比绿色的线要好。绿色的线从噪声中学习到了一些信息。通过平均技术我们获得了黑色的分割线。我们要知道我们的目标不是为了记住训练数据,而是为了预测未知的数据。
Kaggle中的使用:词包和爆米花包
这是一个对于电影情绪分析的一个比赛。在先前我们利用一个在线的感知器脚本获得了95.2的AUC。感知器是一个相当好的线性分类器。如果数据是线性可分的他保证能够找到一个分割平面。但是你必须意识到一个感知器找到一个分割平面就停止了学习,并不能保证这个分割平面对于新的数据也是有效的。因此我们初始化了五个感知器利用随机权重并且利用平均技术结合了他们的预测结果。然后我们获得了成绩的提升。上述结果也表明融合使你不需要学习某一个机器学习算法的详细原理。如果这个算法有效当然好,没什么效果也无所谓。融合若干个在交叉验证中表现差或者过拟合的模型也能够使你获得一些提高。
排序平均:
有时候平均多个模型可能会有一些问题。不是所有的预测模型都能够完美的标准化。有时候预测的结果可能会在低概率和高概率处过于集中,或者集中再一个比较小的范围内。一个极端的例子如下:
Id,Prediction
1,0.35000056
2,0.35000002
3,0.35000098
4,0.35000111
这样的一个预测如果使用AUC可能在线上会得到一个较好的分数。但是当与其他模型融合的时候它可能根本不会改变融合的结果。我们的策略是先把预测转换为排名,然后平均他们的排序。然后将平均后的结果规范化到0,1区间内,你就能够获得一个平滑的预测。
在kaggle中的应用:获得有价值顾客
排序平均在以AUC为优化目标的问题中表现不错。这个问题的目标是对顾客可能再次光临的可能性进行排序。我们的队伍首先利用一个multiple Vowpal Wabbit模型和一个R的GLM网来进行平均。然后我们使用排序平均来提高目标值。
平均预测结果文件是美好的也是很简单的。但是,他不是kaggler唯一的融合方法。
Netfilx:
Netflix组织并且推广了第一个数据科学的比赛。比赛者们在电影推荐问题中推动了融合技术的发展。因为这些方法太过复杂netflix并没有把这些方法用到实际产品中。然而一系列的文章和新鲜方法从这个比赛中诞生。例如:
Feature-Weighted Linear Stacking
Combining Predictions for Accurate Recommender Systems
The BigChaos Solution to the Netflix Prize
这些方法都是很有趣的,并且可以获得相关内容如果你想在kaggle的比赛中获得好的成绩。
堆栈(stacking)泛化:
堆栈泛化是由Wolpert在1992年提出的。Wolpert提出了没有免费午餐的理论。堆栈泛化的基本观点是利用一系列的基本分类器然后用另一个分类器来把他们的预测结果结合到一起。以此来减少泛化误差。
下面以2-fold堆栈为例:
1.将训练集分成两部分a,b
2.用a训练一个第一层次的模型然后用b预测。
3.在b上训练一个相同的模型然后用a预测。
4.最后用所有的数据来训练模型并且对测试集进行预测。
5.最后训练一个第二阶段的堆栈模型利用第一阶段模型得到的概率。
一个堆栈模型可以利用第一阶段的预测结果作为特征,然后单独进行训练。
混合:
Blending是由netflix获胜者提出来的一个词。他跟堆栈泛化很像。但是他会更简单而且有更低的信息泄露的风险。
通过Blending,不需要对训练集多次预测。你可以保留10%的训练集数据,然后堆积模型只需要在这一部分数据上训练。
Blending的几个好处:
1.比stack简单
2.泛化者和堆积者使用不同的数据
3.任何人可以往blender里边扔模型,然后让blender决定要不要保留这个模型
反对者认为:
1.你使用的数据少
2.最终的模型可能会对保留数据过拟合
3.你的交叉验证比堆栈更固定
至于这种方法的性能,两种方法可以给出相似的结果。
如果你不知道怎么选择,你可以两者都进行。创建堆栈融合利用堆栈泛化和无折预测。最后用一个保留的数据集进一步结合这些模型。
使用逻辑回归堆积:
使用逻辑回归堆积是一种更基本和传统的堆积方法。
When creating predictions for the test set, you can do that in one go, or take an average of the out-of-fold predictors. Though taking the average is the clean and more accurate way to do this, I still prefer to do it in one go as that slightly lowers both model and coding complexity.
特征加权线性堆叠:
特征加权线性堆叠利用模型的预测结果堆积工程化的原始特征。这样做的目的是为堆积模型中的基本模型学习一个确定的特征值。线性算法用来保证获得结果迅速和简单。