模型融合中的stacking方法

2024-01-20 12:38
文章标签 方法 模型 融合 stacking

本文主要是介绍模型融合中的stacking方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文参考了Kaggle机器学习之模型融合(stacking)心得
stacking是用于模型融合的一个大杀器,其基本思想是将多个模型的结果进行融合来提高预测率。,理论介绍有很多,实际的例子比较少,本文将其实例化,并给出详细的代码来说明具体的stacking过程是如何实现的。stacking理论的话可以用下面的两幅图来形象的展示出来。
在这里插入图片描述
在这里插入图片描述
结合上面的图先做一个初步的情景假设,假设采用5折交叉验证:
训练集(Train):训练集是100行,4列(3列特征,1列标签)。
测试集(Test):测试集是30行,3列特征,无标签。
模型1:xgboost。
模型2:lightgbm。
模型3:贝叶斯分类器

第一步

对于模型1来说,先看训练集:
采用5折交叉验证,就是要训练5次并且要预测5次。先把数据分成5份,每一次的训练过程是采用80行做训练,20行做预测,经过5次的训练和预测之后,全部的训练集都已经经过预测了,这时候会产生一个100 × \times × 1的预测值。暂记为P1。

接下来看一看测试集:
在模型1每次经过80个样本的学习后,不光要预测训练集上的20个样本,同时还会预测Test的30个样本,这样,在一次训练过程中,就会产生一个30 × \times × 1的预测向量,在5次的训练过程中,就会产生一个30 × \times × 5的向量矩阵,我们队每一行做一个平均,就得到了30 × \times × 1的向量。暂记为T1。

模型1到此结束。接下来看模型2,模型2是在重复模型1的过程,同样也会产生一个训练集的预测值和测试集的预测值。记为P2和T2。这样的话,(P1,P2)就是一个100 × \times × 2的矩阵,(T1,T2)就是一个30 × \times × 2的矩阵。

第二步

第二步是采用新的模型3。其训练集是什么呢?就是第一步得到的(P1,P2)加上每个样本所对应的标签,如果第一步的模型非常好的话,那么得到的P1或者P2应该是非常接近这个标签的。有人可能就会对测试集用求平均的方式来直接(T1+T2)/2,或者带权重的平均来求得结果,但是一般是不如stacking方法的。
将(P1,P2)作为模型3训练集的特征,经过模型3的学习,然后再对测试集上的(T1,T2)做出预测,一般就能得到较好的结果了。

python实现

模型1采用xgboost,模型2采用lightgbm,模型3用贝叶斯分类器。

xgboost

##### xgb
xgb_params = {'eta': 0.005, 'max_depth': 10, 'subsample': 0.8, 'colsample_bytree': 0.8, 'objective': 'reg:linear', 'eval_metric': 'rmse', 'silent': True, 'nthread': 4}#xgb的参数,可以自己改
folds = KFold(n_splits=5, shuffle=True, random_state=2018)#5折交叉验证
oof_xgb = np.zeros(len(train))#用于存放训练集的预测
predictions_xgb = np.zeros(len(test))#用于存放测试集的预测for fold_, (trn_idx, val_idx) in enumerate(folds.split(X_train, y_train)):print("fold n°{}".format(fold_+1))trn_data = xgb.DMatrix(X_train[trn_idx], y_train[trn_idx])#训练集的80%val_data = xgb.DMatrix(X_train[val_idx], y_train[val_idx])#训练集的20%,验证集watchlist = [(trn_data, 'train'), (val_data, 'valid_data')]clf = xgb.train(dtrain=trn_data, num_boost_round=20000, evals=watchlist, early_stopping_rounds=200, verbose_eval=100, params=xgb_params)#80%用于训练过程oof_xgb[val_idx] = clf.predict(xgb.DMatrix(X_train[val_idx]), ntree_limit=clf.best_ntree_limit)#预测20%的验证集predictions_xgb += clf.predict(xgb.DMatrix(X_test), ntree_limit=clf.best_ntree_limit) / folds.n_splits#预测测试集,并且取平均print("CV score: {:<8.8f}".format(mean_squared_error(oof_xgb, target)))

这样我们就得到了训练集的预测结果oof_xgb这一列,这一列是作为模型3训练集的第一个特征列,并且得到了测试集的预测结果predictions_xgb。

lightgbm

lightgbm和xgboost相似,在此把代码写一下。

##### lgb
param = {'num_leaves': 120,'min_data_in_leaf': 30, 'objective':'regression','max_depth': -1,'learning_rate': 0.01,"min_child_samples": 30,"boosting": "gbdt","feature_fraction": 0.9,"bagging_freq": 1,"bagging_fraction": 0.9 ,"bagging_seed": 11,"metric": 'mse',"lambda_l1": 0.1,"verbosity": -1}#模型参数,可以修改
folds = KFold(n_splits=5, shuffle=True, random_state=2018)#5折交叉验证
oof_lgb = np.zeros(len(train))#存放训练集的预测结果
predictions_lgb = np.zeros(len(test))#存放测试集的预测结果for fold_, (trn_idx, val_idx) in enumerate(folds.split(X_train, y_train)):print("fold n°{}".format(fold_+1))trn_data = lgb.Dataset(X_train[trn_idx], y_train[trn_idx])#80%的训练集用于训练val_data = lgb.Dataset(X_train[val_idx], y_train[val_idx])#20%的训练集做验证集num_round = 10000clf = lgb.train(param, trn_data, num_round, valid_sets = [trn_data, val_data], verbose_eval=200, early_stopping_rounds = 100)#训练过程oof_lgb[val_idx] = clf.predict(X_train[val_idx], num_iteration=clf.best_iteration)#对验证集得到预测结果predictions_lgb += clf.predict(X_test, num_iteration=clf.best_iteration) / folds.n_splits#对测试集5次取平均值print("CV score: {:<8.8f}".format(mean_squared_error(oof_lgb, target)))

这样我们得到了模型3训练集的又一个特征oof_lgb,还有测试集的又一个特征predictions_lgb 。

贝叶斯分类器

# 将lgb和xgb的结果进行stacking(叠加)
train_stack = np.vstack([oof_lgb,oof_xgb]).transpose()#训练集2列特征
test_stack = np.vstack([predictions_lgb, predictions_xgb]).transpose()#测试集2列特征
#贝叶斯分类器也使用交叉验证的方法,5折,重复2次,主要是避免过拟合
folds_stack = RepeatedKFold(n_splits=5, n_repeats=2, random_state=2018)
oof_stack = np.zeros(train_stack.shape[0])#存放训练集中验证集的预测结果
predictions = np.zeros(test_stack.shape[0])#存放测试集的预测结果#enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
for fold_, (trn_idx, val_idx) in enumerate(folds_stack.split(train_stack,target)):#target就是每一行样本的标签值print("fold {}".format(fold_))trn_data, trn_y = train_stack[trn_idx], target.iloc[trn_idx].values#划分训练集的80%val_data, val_y = train_stack[val_idx], target.iloc[val_idx].values#划分训练集的20%做验证集clf_3 = BayesianRidge()clf_3.fit(trn_data, trn_y)#贝叶斯训练过程,sklearn中的。oof_stack[val_idx] = clf_3.predict(val_data)#对验证集有一个预测,用于后面计算模型的偏差predictions += clf_3.predict(test_stack) / 10#对测试集的预测,除以10是因为5折交叉验证重复了2次mean_squared_error(target.values, oof_stack)#计算出模型在训练集上的均方误差
print("CV score: {:<8.8f}".format(mean_squared_error(target.values, oof_stack)))

这篇关于模型融合中的stacking方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/626043

相关文章

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

SQL Server安装时候没有中文选项的解决方法

《SQLServer安装时候没有中文选项的解决方法》用户安装SQLServer时界面全英文,无中文选项,通过修改安装设置中的国家或地区为中文中国,重启安装程序后界面恢复中文,解决了问题,对SQLSe... 你是不是在安装SQL Server时候发现安装界面和别人不同,并且无论如何都没有中文选项?这个问题也

Java Thread中join方法使用举例详解

《JavaThread中join方法使用举例详解》JavaThread中join()方法主要是让调用改方法的thread完成run方法里面的东西后,在执行join()方法后面的代码,这篇文章主要介绍... 目录前言1.join()方法的定义和作用2.join()方法的三个重载版本3.join()方法的工作原

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分

Spring Boot从main方法到内嵌Tomcat的全过程(自动化流程)

《SpringBoot从main方法到内嵌Tomcat的全过程(自动化流程)》SpringBoot启动始于main方法,创建SpringApplication实例,初始化上下文,准备环境,刷新容器并... 目录1. 入口:main方法2. SpringApplication初始化2.1 构造阶段3. 运行阶

Olingo分析和实践之ODataImpl详细分析(重要方法详解)

《Olingo分析和实践之ODataImpl详细分析(重要方法详解)》ODataImpl.java是ApacheOlingoOData框架的核心工厂类,负责创建序列化器、反序列化器和处理器等组件,... 目录概述主要职责类结构与继承关系核心功能分析1. 序列化器管理2. 反序列化器管理3. 处理器管理重要方

Python错误AttributeError: 'NoneType' object has no attribute问题的彻底解决方法

《Python错误AttributeError:NoneTypeobjecthasnoattribute问题的彻底解决方法》在Python项目开发和调试过程中,经常会碰到这样一个异常信息... 目录问题背景与概述错误解读:AttributeError: 'NoneType' object has no at

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数

Java中Arrays类和Collections类常用方法示例详解

《Java中Arrays类和Collections类常用方法示例详解》本文总结了Java中Arrays和Collections类的常用方法,涵盖数组填充、排序、搜索、复制、列表转换等操作,帮助开发者高... 目录Arrays.fill()相关用法Arrays.toString()Arrays.sort()A

Nginx安全防护的多种方法

《Nginx安全防护的多种方法》在生产环境中,需要隐藏Nginx的版本号,以避免泄漏Nginx的版本,使攻击者不能针对特定版本进行攻击,下面就来介绍一下Nginx安全防护的方法,感兴趣的可以了解一下... 目录核心安全配置1.编译安装 Nginx2.隐藏版本号3.限制危险请求方法4.请求限制(CC攻击防御)