
1. 从单模瓶颈到集成提效Task5 模型融合到底在解决什么问题做过数据竞赛的人都有一个共同的体感前面四个任务辛辛苦苦调参、做特征、跑交叉验证单模分数卡在某个位置死活上不去排行榜上却总有人比你高那么一截。这一截差距很多时候不是模型本身有多玄学而是融合策略在起作用。Task5 的模型融合本质上就是回答一个问题——当你手里已经有好几个各有所长、各有短板的模型时怎么把它们捏成一个比任何一个单模都稳、都强的结果。我先说清楚这个任务适合谁看。如果你已经跑通了前面几个 Task手里有至少两到三个模型的预测结果或者 OOF 预测但对融合的理解还停留在把几个结果平均一下的阶段那这篇内容就是给你写的。如果你连单模都还没跑稳建议先回去把基线做扎实融合是锦上添花不是雪中送炭——这一点我在实际比赛里踩过太多次坑后面会细讲。模型融合的核心价值用一句话概括降低方差、对冲偏差。单个模型对某类样本可能特别准对另一类样本可能错得离谱而不同模型因为结构、特征、随机种子的差异它们的错误往往不是完全重叠的。融合做的事情就是让这些不重叠的错误互相抵消同时保留各自不重叠的正确。这背后是集成学习最朴素的直觉但真正落地时细节决定成败。关键词里虽然没有明确给出但从标题DwX天池-Task5 模型融合可以推断这是一个典型的数据竞赛场景下的融合任务。天池类比赛的 Task 划分通常遵循数据探索→特征工程→单模建模→调参优化→模型融合的递进逻辑Task5 处在收尾阶段意味着前面的工作已经沉淀出了可用的模型资产。这个阶段最忌讳的就是推倒重来正确的姿势是在已有结果上做增量。我见过太多人在这一步犯同一个错误把融合当成再训一个大模型。结果时间花了一大半分数还不如简单加权平均。融合的精髓不在于模型多复杂而在于多样性和权重分配这两个杠杆。接下来我会把这两个杠杆拆开讲透再给出可以直接抄作业的实操流程。2. 融合之前必须先想明白的三件事2.1 你的模型之间到底多样在哪里很多人一上来就问用什么融合方法最好这个问题本身就问错了。融合效果的上限在模型训练阶段就已经被决定了——如果你的三个模型都是 XGBoost只是随机种子不同那融合收益极其有限如果一个是树模型、一个是神经网络、一个是线性模型那融合空间就大得多。多样性来源可以分几个层次我按性价比从高到低排多样性来源具体做法融合收益实现成本算法类型不同树模型 神经网络 线性/距离模型高中特征子集不同不同模型喂不同特征组合中高低超参数差异同一算法不同深度/正则强度中低随机种子不同同算法同参数换 seed低极低数据采样不同Bagging、不同折划分中中我的经验是优先保证算法类型和特征子集的多样性种子多样性只作为最后的补充。在资源有限的情况下与其把 XGBoost 调参调到极致不如分出一部分精力训一个结构差异大的模型哪怕它单模分数低一两个千分位融合时也可能带来惊喜。这里有个反直觉的点单模分数略低但错误模式不同的模型往往比单模分数高但错误模式雷同的模型更有融合价值。判断错误模式是否雷同最直接的办法是看模型间的预测相关系数。相关系数高于 0.98 的两个模型融合基本等于没融。2.2 OOF 预测为什么是融合的命根子如果你只记住这篇内容里的一件事那就是融合的权重必须在 OOFOut-Of-Fold预测上确定绝不能用测试集预测去拟合权重。原因很简单。测试集没有标签你没法直接评估融合权重的好坏。如果你用训练集预测in-sample prediction去拟合权重模型会过拟合训练集权重会偏向那些在训练集上背答案背得好的模型而这些模型在测试集上往往表现平平。OOF 预测的巧妙之处在于每个样本的预测都来自没见过这个样本的模型所以它模拟了模型在真实未知数据上的表现。具体来说做 5 折交叉验证时每一折用 4 折训练、1 折预测把 5 折的预测拼起来就得到了覆盖全量训练样本的 OOF 预测。这个过程必须和单模训练时的折划分完全一致否则 OOF 和测试集预测的分布会对不上融合权重就会失真。注意折划分的随机种子一定要固定并记录。我踩过的坑是单模训练时用了 seed42 的 5 折融合时手滑用了 seed2024结果 OOF 和测试预测的对应关系错位融合分数不升反降排查了大半天才发现是折不一致。2.3 融合不是越多越好新手容易陷入模型越多越强的幻觉恨不得把十几个模型全塞进去。实际上当模型数量超过一定阈值后边际收益急剧下降而过拟合 OOF 的风险却在上升。尤其是当你用 Stacking 这类学习型融合时模型太多、样本不够第二层学习器很容易把 OOF 上的噪声也学进去。我的建议是控制在 3 到 6 个模型之间优先选那些单模分数靠前、且彼此相关性低的。如果非要加更多先用简单的加权平均筛一遍把贡献为负或接近零的模型剔掉再进入复杂融合。3. 从加权平均到 Stacking融合方法的选型逻辑3.1 简单平均与加权平均别小看这个基线很多人觉得简单平均太 low直接跳过。但我要说简单平均是所有融合方法的基线你必须先跑它。原因有两个一是它不需要任何拟合不存在过拟合风险二是如果复杂方法跑出来还不如简单平均那说明你的融合流程有问题而不是方法不够高级。简单平均就是把各模型的预测直接取均值。对于分类任务可以是对概率取均值再取 argmax也可以是对类别投票。加权平均则是给每个模型一个权重权重之和为 1。权重的确定方法有几种基于单模分数的权重单模 AUC 越高权重越大简单粗暴但有效。网格搜索在 OOF 上搜索权重组合适合模型数量少2-3 个的情况。优化算法用 scipy 的 minimize 或专门的优化库在 OOF 上最小化损失函数。我实测下来当模型数量在 3 个以内时网格搜索权重最稳超过 3 个网格搜索维度爆炸改用优化算法或者直接上 Stacking。3.2 Stacking 的两层结构到底怎么搭Stacking 是融合里的重武器结构上分两层第一层是若干个基模型第二层是一个元学习器meta-learner。第一层的 OOF 预测作为第二层的输入特征第二层在 OOF 上训练最终对测试集做预测。这里有几个关键决策点我逐个说元学习器选什么经验法则是元学习器要简单。逻辑回归、线性回归、浅层决策树是首选。为什么因为第二层的训练数据就是第一层的 OOF 预测样本量等于训练集大小特征数等于基模型数量。如果元学习器太复杂比如再来一个深度网络它会把第一层模型在 OOF 上的过拟合模式也学进去导致泛化变差。我见过有人用 GBDT 做元学习器结果比逻辑回归还差就是这个原因。第二层要不要加原始特征一般不加。加了会让元学习器倾向于依赖原始特征而非基模型的预测削弱融合的意义。除非你的基模型都很弱原始特征能提供额外信息才考虑少量加入。第二层的验证怎么做必须用交叉验证。如果直接在全部 OOF 上训练元学习器再用它预测测试集你无法评估融合后的真实效果。正确做法是在 OOF 上再做一次 K 折得到融合后的 OOF 评估分数这个分数才是你判断融合是否有效的依据。3.3 Blending 与 Stacking 的取舍Blending 可以理解为简化版 Stacking它不搞 K 折而是从训练集里切出一块 holdout 集基模型在剩余数据上训练在 holdout 上预测元学习器用 holdout 预测训练。Blending 的优点是简单、不易泄露缺点是浪费了 holdout 那部分训练数据且元学习器的训练样本变少容易过拟合。在小数据集上Blending 的数据浪费问题会被放大优先选 Stacking在大数据集上两者差距不大Blending 更省事。我个人的习惯是只要数据量允许一律上 Stacking因为它的 OOF 机制让每一份数据都参与了基模型训练信息利用更充分。4. 一套可直接复现的融合实操流程4.1 环境与数据准备假设你已经有了若干模型的 OOF 预测和测试集预测格式是 numpy 数组或 DataFrame。我建议统一整理成如下结构# oof_preds: shape (n_models, n_train_samples) # test_preds: shape (n_models, n_test_samples) # y_train: shape (n_train_samples,)如果任务是二分类确保所有模型输出的是概率而非硬标签。概率保留了更多信息融合效果通常更好。先把所有 OOF 预测拼成一个矩阵计算模型间的相关系数矩阵import numpy as np import pandas as pd corr_matrix pd.DataFrame(oof_preds).T.corr() print(corr_matrix)相关系数高于 0.98 的模型对考虑只保留其中一个。这一步能帮你快速砍掉冗余模型。4.2 加权平均的网格搜索实现对于 3 个模型的情况权重搜索可以这样写from scipy.optimize import minimize from sklearn.metrics import roc_auc_score def neg_auc(weights, oof_preds, y_true): weights np.abs(weights) weights weights / weights.sum() blended np.average(oof_preds, axis0, weightsweights) return -roc_auc_score(y_true, blended) n_models oof_preds.shape[0] init_weights np.ones(n_models) / n_models res minimize(neg_auc, init_weights, args(oof_preds, y_train), methodNelder-Mead) best_weights np.abs(res.x) / np.abs(res.x).sum() print(最优权重:, best_weights) print(融合 OOF AUC:, -res.fun)这里用np.abs是为了防止优化过程中出现负权重。负权重在理论上有时能提升拟合但极易过拟合实战中我一般禁用。4.3 Stacking 的完整代码骨架from sklearn.linear_model import LogisticRegression from sklearn.model_selection import StratifiedKFold def stacking(oof_preds, test_preds, y_train, n_splits5, seed42): # oof_preds: (n_models, n_train) # test_preds: (n_models, n_test) X_meta oof_preds.T # (n_train, n_models) X_test_meta test_preds.T # (n_test, n_models) skf StratifiedKFold(n_splitsn_splits, shuffleTrue, random_stateseed) meta_oof np.zeros(len(y_train)) meta_test np.zeros(X_test_meta.shape[0]) for train_idx, val_idx in skf.split(X_meta, y_train): clf LogisticRegression(C1.0, max_iter1000) clf.fit(X_meta[train_idx], y_train[train_idx]) meta_oof[val_idx] clf.predict_proba(X_meta[val_idx])[:, 1] meta_test clf.predict_proba(X_test_meta)[:, 1] / n_splits print(Stacking OOF AUC:, roc_auc_score(y_train, meta_oof)) return meta_oof, meta_test注意meta_test是每一折元学习器对测试集预测的平均这样能降低单折元学习器的方差。4.4 融合结果的验证与提交拿到融合后的 OOF 分数后和单模分数对比。如果融合分数没有明显提升比如提升小于 0.001先别急着提交回头检查模型间相关性是否过高OOF 和测试预测是否来自同一套折划分元学习器是否过拟合对比元学习器的 OOF 分数和训练分数确认无误后用融合后的测试集预测生成提交文件。如果比赛允许多次提交建议保留单模最优和融合两个版本用排行榜反馈做最终决策。5. 那些年我在融合上踩过的坑5.1 折划分不一致导致的假提升这是最隐蔽的坑。单模训练用了一套折融合时 OOF 来自另一套折两者对不上。表现是融合 OOF 分数虚高但提交后排行榜分数反而下降。排查方法检查每个模型的 OOF 预测是否严格对应同一份 y_train 顺序折的随机种子是否一致。5.2 元学习器过拟合 OOF用复杂元学习器时它在 OOF 上的分数可能很高但测试集上崩掉。判断信号是元学习器的训练分数远高于 OOF 分数。解决办法换更简单的元学习器加正则化或者减少基模型数量。5.3 概率未校准导致的权重失真不同模型的概率输出尺度可能不同。比如逻辑回归输出的概率分布比较平缓而 GBDT 输出的概率容易集中在 0 和 1 附近。直接加权平均时尺度大的模型会主导结果。解决办法融合前对每个模型的概率做校准如 Platt scaling 或 Isotonic regression或者改用 rank 平均。5.4 忽略类别不平衡下的融合评估如果正负样本极不平衡AUC 可能不是最佳评估指标。此时融合权重的优化目标要换成 F1、Recall 或业务相关指标。我见过有人一味优化 AUC结果融合后 Recall 掉得厉害实际业务价值反而下降。6. 融合之后还能做什么融合不是终点。拿到融合结果后还有几个方向可以继续挖一是伪标签。用融合后的测试集预测挑高置信度的样本打上伪标签加入训练集重新训练基模型再融合。这在半监督场景下往往能再涨一点。二是模型蒸馏。如果融合模型太复杂不便部署可以训一个小模型去拟合融合模型的输出把集成的能力压缩到单模里。三是特征层面的融合。把不同模型学到的特征表示拼接起来再训一个模型。这在深度学习场景下更常见。我个人在实际操作中的体会是融合的收益80% 来自模型多样性20% 来自融合方法。与其在融合算法上反复折腾不如回头把基模型的多样性做扎实。另外永远保留一份简单加权平均的结果作为兜底复杂方法跑崩了也不至于交白卷。最后分享一个小技巧把每次融合的权重、OOF 分数、提交分数记在一个表格里几轮下来你就能摸出这套数据上什么样的模型组合最吃香这个经验比任何教程都值钱。