模型融合之stacking&blending原理及代码

目录

1 Stacking

1.1 概念

1.2 python实现

2 Blending

2.1 概念

2.2 python实现

3 Stacking和Blending对比

4 参考文献


模型融合的基本思想就是通过对多个单模型融合以提升整体性能。平常自己一般都使用最简单的方法,比如说对分类问题,采用voting,对回归问题,采用加权averaging。

今天简单介绍下stacking和blending。

1 Stacking

1.1 概念

Stacking模型本质上是一种分层的结构,这里简单起见,只分析二级Stacking。假设我们有3个基模型M1、M2、M3。

1. 基模型M1,对训练集train训练,然后用于预测train和test的标签列,将预测的训练集和测试集的结果(即预测出的y)分别作为P1,T1

 

对于M2和M3,重复相同的工作,这样也得到P2,T2,P3,T3。

2. 分别把P1,P2,P3以及T1,T2,T3合并,得到一个新的训练集和测试集train2,test2.

3. 再用第二层的模型M4训练train2,预测test2,得到最终的标签列。必须要注意的是,也是我一开始有点懵的地方。train2和test2里的特征其实是在第一层预测出的y的结果。

Stacking本质上就是这么直接的思路,但是这样肯定是不行的,问题在于P1的得到是有问题的,用整个训练集训练的模型反过来去预测训练集的标签,毫无疑问过拟合是非常非常严重的,因此现在的问题变成了如何在解决过拟合的前提下得到P1、P2、P3,这就变成了熟悉的节奏——K折交叉验证。我们以2折交叉验证得到P1为例,假设训练集为4行3列
将其划分为2部分

用traina训练模型M1,然后在trainb上进行预测得到preb3和pred4

在trainb上训练模型M1,然后在traina上进行预测得到pred1和pred2

然后把两个预测集进行拼接

对于测试集T1的得到,有两种方法。注意到刚刚是2折交叉验证,M1相当于训练了2次,所以一种方法是每一次训练M1,可以直接对整个test进行预测,这样2折交叉验证后测试集相当于预测了2次,然后对这两列求平均得到T1(接下来的代码是这么做的)。或者直接对测试集只用M1预测一次直接得到T1。

P1、T1得到之后,P2、T2、P3、T3也就是同样的方法。理解了2折交叉验证,对于K折的情况也就理解也就非常顺利了。所以最终的代码是两层循环,第一层循环控制基模型的数目,每一个基模型要这样去得到P1,T1,第二层循环控制的是交叉验证的次数K,对每一个基模型,会训练K次最后拼接得到P1,取平均得到T1。这下再把@Wille博文中的那张图片放出来就很容易看懂了。

该图是一个基模型得到P1和T1的过程,采用的是5折交叉验证,所以循环了5次,拼接得到P1,测试集预测了5次,取平均得到T1。而这仅仅只是第二层输入的一列/一个特征,并不是整个训练集。再分析接下来的代码也就很清楚了。也就是刚刚提到的两层循环。

Note:

(1)一个基模型通过交叉验证训练得到的P1( \hat{y} ) 只是train2中的一列特征,对测试集预测的结果T1只是test2中的一列特征。​

(2)对于得到的训练集train2,在第二层M4训练的时候,它的标签还是原来的y。

1.2 python实现

Stacking代码

该代码完全实现了上面的逻辑,通俗易懂。稍加改造就可以应用于自己的模型。


2 Blending

2.1 概念

Blending与Stacking大致相同,只是Blending的主要区别在于训练集不是通过K-Fold的CV策略来获得预测值从而生成第二阶段模型的特征,而是建立一个Holdout集。简单来说,Blending直接用不相交的数据集用于不同层的训练。

以两层的Blending为例,训练集划分为两部分(d1,d2),测试集为test。

  1. 第一层:用d1训练多个模型,将其对d2和test的预测结果作为第二层的New Features。
  2. 第二层:用d2的New Features和标签训练新的分类器,然后把test的New Features输入作为最终的测试集,对test预测出的结果就是最终的模型融合的值。

2.2 python实现

Blending代码


 

3 Stacking和Blending对比

Blending的优点在于:

1.比stacking简单(因为不用进行k次的交叉验证来获得stacker feature)

2.避开了一个信息泄露问题:generlizers和stacker使用了不一样的数据集

3.在团队建模过程中,不需要给队友分享自己的随机种子

而缺点在于:

1.使用了很少的数据(是划分hold-out作为测试集,并非cv)

2.blender可能会过拟合(其实大概率是第一点导致的)

3.stacking使用多次的CV会比较稳健

对于实践中的结果而言,stacking和blending的效果是差不多的,所以使用哪种方法都没什么所谓,完全取决于个人爱好。


4 参考文献

贝尔塔:【机器学习】模型融合方法概述

Ensemble Learning-模型融合-Python实现

  • 8
    点赞
  • 132
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个 stacking 模型融合的示例代码: 首先,我们需要导入必要的库和数据集: ``` python import pandas as pd import numpy as np from sklearn.model_selection import KFold from sklearn.metrics import mean_squared_error from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor from xgboost import XGBRegressor # 读取训练数据和测试数据 train_df = pd.read_csv('train.csv') test_df = pd.read_csv('test.csv') ``` 然后,我们定义一个函数来进行交叉验证,训练模型和预测: ``` python def run_model(model, train_X, train_y, test_X): model.fit(train_X, train_y) y_pred = model.predict(test_X) return y_pred ``` 接下来,我们定义一个 stacking 模型融合的函数: ``` python def stacking(models, train_X, train_y, test_X, n_fold): # 预测结果矩阵 train_pred = np.zeros((train_X.shape[0], len(models))) test_pred = np.zeros((test_X.shape[0], len(models))) kf = KFold(n_splits=n_fold, shuffle=True, random_state=42) for i, model in enumerate(models): # 预测测试数据 test_pred_i = np.zeros((test_X.shape[0], n_fold)) for j, (train_idx, val_idx) in enumerate(kf.split(train_X)): # 划分训练集和验证集 train_X_fold, train_y_fold = train_X[train_idx], train_y[train_idx] val_X_fold, val_y_fold = train_X[val_idx], train_y[val_idx] # 训练模型并预测验证集和测试集 y_val_pred_fold = run_model(model, train_X_fold, train_y_fold, val_X_fold) y_test_pred_fold = run_model(model, train_X_fold, train_y_fold, test_X) # 记录预测结果 train_pred[val_idx, i] = y_val_pred_fold test_pred_i[:, j] = y_test_pred_fold # 对测试集的预测结果取平均 test_pred[:, i] = test_pred_i.mean(axis=1) # 使用最终的模型对测试集进行预测 final_model = XGBRegressor() final_model.fit(train_pred, train_y) y_pred = final_model.predict(test_pred) return y_pred ``` 最后,我们定义一些模型并调用 stacking 函数进行模型融合: ``` python # 定义模型 rf_model = RandomForestRegressor(random_state=42) gbdt_model = GradientBoostingRegressor(random_state=42) xgb_model = XGBRegressor(random_state=42) # 进行 stacking 模型融合 models = [rf_model, gbdt_model, xgb_model] n_fold = 5 y_pred = stacking(models, train_X, train_y, test_X, n_fold) ``` 这就是一个简单的 stacking 模型融合的示例代码,你可以根据自己的数据和模型进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值