Kaggle上分技巧——单模K折交叉验证训练+多模型融合

本文介绍了如何在Kaggle竞赛中使用K折交叉验证训练单个模型,并探讨了多模型融合的策略,包括平均融合、加权融合和stacking融合,以提高模型的泛化能力和性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、K折交叉验证训练单个模型

1.1 k 折交叉验证(K-Fold Cross Validation)原理

通过对 k 个不同分组训练的结果进行平均来减少方差,因此模型的性能对数据的划分就不那么敏感,经过多次划分数据集,大大降低了结果的偶然性,从而提高了模型的准确性。具体做法如下:

  • step1:不重复抽样将原始数据随机分为 k 份。
  • step2:每一次挑选其中 1 份作为验证集,剩余 k-1 份作为训练集用于模型训练。一共训练k个模型。
  • step3:在每个训练集上训练后得到一个模型,用这个模型在测试集上测试,计算并保存模型的评估指标,
  • step4:计算 k 组测试结果的平均值作为模型最终在测试集上的预测值,求k 个模型评估指标的平均值,并作为当前 k 折交叉验证下模型的性能指标。
    5折交叉验证建模应用

要注意的是:
(1)K折交叉验证适合大样本的数据集,在小样本数据集上就很难识别数据中的趋势,导致错误产生。
(2)K折交叉验证不适合包含不同类别的数据集。比如:若数据集有5类数据(ABCDE各占20%),抽取出来的也正好是按照类别划分的5类,第一折全是A,第二折全是B……这样划分的数据集建立的模型显然没什么意义。第一折训练的模型把样本全判为A、第二折训练的模型把样本全判为B…这种情况下,可以使用分层交叉验证 (Stratified k-fold cross validation)。sklearn.model_selection中有相关函数可以调用。StratifiedKFold

from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=5,shuffle=False,random_state=0)

(3)如果训练集不能很好地代表整个样本总体,分层交叉验证就没有意义了。这时候,可以使用重复交叉验证,即每次用不同的划分方式划分数据集,每次划分完后的其他步骤和K折交叉验证一样。(重复K折交叉验证可以提高模型评估的精确度,同时保持较小的偏差。)
下面这段代码就是重复两次划分数据集(n_repeats=2),每次数据集都进行5折交叉验证(n_splits=5)。

kf = RepeatedKFold(n_splits=5, n_repeats=2, random_state=None) 

1.2 代码

下面将交叉验证过程与模型训练过程融合在一起,编写成一个可以自动化处理的函数,可以保存为py文件,建模的时候直接调用。该函数需要输入训练集X,测试集X_test、训练集对应的标签列y,模型的最优参数组合字典params,还有已经划分好的K折样本folds,还有模型类型model_type(3个选择:LightGBM、Xgboost、Catboost,都是Kaggle中很常用的模型,如果想加入其他的可选择模型,在代码中再多增加一个if判断就可以)、决定是回归问题还是分类问题的eval_type。输出的是交叉验证中过程中几个小模型在训练集上得出的预测值oof(保存好之后可以用于stacking融合),几个小模型在测试集上的平均预测 predictions, 模型评估指标scores(回归问题用RMSE、分类问题用logloss)

def train_model(X, X_test, y, params, folds, model_type='lgb', eval_type='regression'):
    #生成一个和训练集样本量一样大的空数列,用来存放交叉验证中的小模型在训练集上的预测值,以后会在stacking中用到这些数据
    oof = np.zeros(X.shape[0])
    #存放测试集的预测结果
    predictions = np.zeros(X_test.shape[0])#
    scores = []
    #enumerate(folds.split(X, y))返回第i折的测试集索引trn_idx、验证集索引val_idx
    for fold_n, (trn_idx, val_idx) in enumerate(folds.split(X, y)):
        print('Fold', fold_n, 'started at', time.ctime())
        
        if model_type == 'lgb':
            #lightgbm要封装数据
            trn_data = lgb.Dataset(X[trn_idx], y[trn_idx])
            val_data = lgb.Dataset(X[val_idx], y
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值