
1. 从E题聊起为什么这道题值得单独拿出来复盘华为杯研究生数学建模竞赛的E题历来是整张卷子里“看起来最像业务题、做起来最像工程题”的那一类。2026年的E题延续了这个传统——它不会给你一个纯粹的数学优化目标让你去推公式也不会像A题那样上来就是物理建模的硬骨头而是把一堆真实场景下的数据丢给你让你从里面挖出规律、建出模型、给出决策建议。说白了它考的不是你会不会解偏微分方程而是你能不能像一个真正的数据分析师那样把一团乱麻的数据理清楚然后讲出一个有说服力的故事。我之所以想单独把E题拿出来分享是因为这道题的“坑”特别有代表性。很多队伍拿到题目之后第一反应是套机器学习模型XGBoost、随机森林、LSTM往上堆结果发现特征工程没做好数据清洗没做干净最后模型跑出来的结果连自己都不敢信。还有的队伍在可视化上花了大量时间图表做得花里胡哨但评委一看就知道核心逻辑没跑通。E题的评分标准里数据预处理的合理性、模型选择的依据、结果的可解释性这三块占了大头而不是看你用了多高级的算法。这篇文章适合谁看如果你是第一次参加华为杯、对E题这种“数据驱动型”题目没有头绪那这篇内容可以帮你少走至少三天的弯路。如果你已经做过一两届但每次都在数据清洗和特征选择上卡壳那这里面的实操细节和避坑经验对你同样有用。我会从赛题拆解、数据预处理、特征工程、模型选型、可视化呈现、论文写作六个维度把E题的完整打法拆开来讲中间穿插我自己踩过的坑和总结出来的技巧。提示E题的官方数据通常包含多个CSV文件字段命名不规范、缺失值隐蔽、时间格式混乱是常态。不要指望拿到数据就能直接喂给模型前期的数据审计工作至少占整个赛程的40%。2. 赛题拆解E题到底在考什么能力2.1 从“业务问题”到“数学问题”的翻译过程E题的题干通常是一段业务场景描述比如“某平台需要根据用户行为数据预测流失风险”或者“某城市需要根据交通流量数据优化信号灯配时”。很多队伍一上来就开始想用什么模型这是典型的顺序错误。正确的做法是先把业务语言翻译成数学语言预测流失风险翻译过来就是“二分类问题目标变量是是否流失特征变量是用户行为指标”优化信号灯配时翻译过来就是“带约束的优化问题决策变量是各相位时长目标函数是平均等待时间最小化”。这个翻译过程决定了你后续所有工作的方向。我见过一个队伍题目要求“评估不同营销策略的效果”他们直接做了一个聚类分析把用户分成几群就交差了。问题是聚类只能告诉你“用户分几类”不能告诉你“哪种策略对哪类用户有效”。正确的做法应该是构建一个因果推断框架或者至少做一个A/B测试的统计分析。翻译错了后面全错。2.2 E题常见的三类问题结构根据我做过和看过的E题大致可以归为三类。第一类是预测类给你历史数据让你预测未来某个指标的值比如销量、流量、故障率。这类题的核心是时间序列建模或回归建模重点在于特征构造和验证集划分。第二类是分类类给你带标签的数据让你判断新样本属于哪一类比如信用评级、疾病诊断。这类题的核心是类别不平衡处理和模型可解释性。第三类是优化类给你约束条件和目标函数让你找最优解比如资源分配、路径规划。这类题的核心是问题建模的准确性和求解算法的效率。2026年E题我拿到手之后第一件事就是判断它属于哪一类。从题干描述和数据字段来看它更偏向“预测优化”的混合结构先根据历史数据预测某个关键指标再基于预测结果做资源分配决策。这种混合结构在近几年的E题里越来越常见因为它更贴近真实业务场景——业务决策从来不是单一任务而是“预测-决策”的链条。2.3 评分标准里的隐藏信号华为杯的评分标准虽然不会提前公布但从历年优秀论文的共性来看有几个信号非常明显。第一数据预处理的篇幅占比很高。优秀论文通常会用2-3页详细描述缺失值处理、异常值检测、数据标准化等步骤而不是一笔带过。第二模型对比是必须的。你不能只用一个模型跑出结果就完事至少要有2-3个基准模型的对比实验说明为什么最终选择了某个模型。第三结果的可解释性比精度更重要。一个准确率85%但能清楚解释每个特征贡献度的模型往往比准确率90%但黑箱的模型得分更高。注意E题不是算法竞赛评委更看重你的分析逻辑是否严密而不是你的模型是否刷新了SOTA。把精力花在“为什么这样做”上比花在“用什么高级模型”上回报率高得多。3. 数据预处理E题最容易被低估的40%工作量3.1 数据审计先看清楚你手里有什么拿到数据之后不要急着写代码。先做一轮完整的数据审计搞清楚以下几个问题每个文件有多少行多少列字段类型是什么缺失值比例是多少有没有重复记录时间字段的格式是否统一类别型字段的取值分布是什么样的我习惯用一段固定的Python代码来做初步审计大概长这样import pandas as pd import numpy as np def audit_data(df, name): print(f {name} ) print(fShape: {df.shape}) print(fColumns: {list(df.columns)}) print(fMissing ratio:\n{df.isnull().mean().sort_values(ascendingFalse)}) print(fDuplicates: {df.duplicated().sum()}) print(fDtypes:\n{df.dtypes}) print(fDescribe:\n{df.describe(includeall)}) # 对每个CSV文件调用 for file in [train.csv, test.csv, user_info.csv]: df pd.read_csv(file) audit_data(df, file)这段代码看起来简单但它能帮你快速定位问题。比如有一次我发现某个字段的缺失率高达70%但题干里根本没提这个字段后来才意识到这个字段是“可选填写”的直接删掉比强行填充更合理。3.2 缺失值处理不是所有缺失都该填缺失值处理是E题里最容易踩坑的地方。很多队伍一看到缺失值就无脑用均值填充或者中位数填充这是非常危险的做法。缺失值的处理方式取决于缺失机制完全随机缺失可以用均值/中位数填充随机缺失可以用模型预测填充非随机缺失则需要分析缺失原因甚至把“是否缺失”本身作为一个特征。举个例子如果用户收入字段有大量缺失而且缺失的用户大多是低活跃度用户那这个缺失就不是随机的。你直接填均值相当于给低活跃用户强行安了一个平均收入会严重扭曲数据分布。更好的做法是先分析缺失用户和非缺失用户在其它特征上的差异如果差异显著就把“收入是否缺失”作为一个二值特征加入模型同时用分组均值填充。# 分析缺失机制 df[income_missing] df[income].isnull().astype(int) print(df.groupby(income_missing)[[age, activity_score]].mean()) # 分组填充 df[income] df.groupby(income_missing)[income].transform( lambda x: x.fillna(x.median()) )3.3 异常值检测Z-score和IQR的适用场景异常值检测常用的方法有Z-score和IQR两种。Z-score假设数据服从正态分布适合处理近似正态的连续变量IQR不依赖分布假设适合处理偏态分布的数据。E题的数据往往混合了这两种情况所以我的做法是对每个连续变量先画直方图看分布正态的用Z-score偏态的用IQR。但要注意异常值不一定要删除。有些异常值是真实业务场景下的极端情况比如“双十一”当天的流量峰值你把它删了反而丢失了重要信息。正确的做法是先标记异常值分析它们的业务含义再决定是删除、截断还是保留。我通常会在论文里专门用一小节讨论异常值处理策略这本身就是加分项。3.4 时间字段处理E题的时间陷阱E题的数据里几乎必然包含时间字段而且格式往往不统一。有的用“2026-01-15”有的用“2026/1/15”有的用时间戳。第一步是统一格式第二步是提取时间特征年、月、日、星期、是否节假日、是否周末。这些衍生特征对预测类问题特别重要。df[date] pd.to_datetime(df[date], formatmixed) df[year] df[date].dt.year df[month] df[date].dt.month df[dayofweek] df[date].dt.dayofweek df[is_weekend] df[dayofweek].isin([5, 6]).astype(int)还有一个容易被忽略的点时间序列的排序。如果你的数据是按时间顺序排列的做交叉验证时不能用随机划分必须用时间序列划分TimeSeriesSplit否则会造成数据泄露模型在验证集上的表现会虚高。4. 特征工程决定E题上限的关键环节4.1 特征构造的三种思路特征工程是E题拉开差距的核心环节。同样的数据不同队伍构造出来的特征可能天差地别。我总结下来有三种思路统计聚合、业务衍生、交互组合。统计聚合是指对某个实体比如用户、商品、地区计算统计量比如均值、最大值、最小值、标准差、分位数。比如用户行为数据你可以计算每个用户的“近7天平均活跃时长”“近30天最大单次消费金额”等。业务衍生是指根据业务逻辑构造特征比如“消费金额/收入”得到消费率“点击次数/曝光次数”得到点击率。交互组合是指把两个或多个特征做运算比如“年龄×收入”“活跃度/注册天数”。4.2 特征选择过滤法、包裹法、嵌入法特征不是越多越好。E题的数据字段可能几十上百个但真正有用的可能只有十几个。特征选择方法有三类过滤法方差阈值、卡方检验、互信息、包裹法递归特征消除RFE、嵌入法Lasso回归、树模型的特征重要性。我通常先用过滤法快速筛掉方差极低或与目标变量相关性极低的特征再用嵌入法比如随机森林的feature_importances_做精细筛选。包裹法计算量大E题时间紧张的时候不建议用。from sklearn.ensemble import RandomForestClassifier rf RandomForestClassifier(n_estimators100, random_state42) rf.fit(X_train, y_train) importance pd.DataFrame({ feature: X_train.columns, importance: rf.feature_importances_ }).sort_values(importance, ascendingFalse) print(importance.head(20))4.3 类别不平衡E题分类问题的隐形杀手如果E题是分类问题类别不平衡几乎必然出现。比如“流失用户”可能只占总用户的5%“违约用户”可能只占3%。这时候如果你直接用准确率作为评价指标模型只要全部预测为“非流失”就能达到95%的准确率但这显然没有意义。处理类别不平衡的方法有重采样过采样少数类、欠采样多数类、合成采样SMOTE、调整类别权重class_weightbalanced、更换评价指标F1-score、AUC-ROC。我通常优先用调整类别权重的方法因为它不改变数据分布实现简单。如果效果不好再尝试SMOTE。from imblearn.over_sampling import SMOTE smote SMOTE(random_state42) X_resampled, y_resampled smote.fit_resample(X_train, y_train) print(fBefore: {y_train.value_counts()}) print(fAfter: {y_resampled.value_counts()})提示SMOTE只能在训练集上做绝对不能在测试集上做。否则测试集里混入了合成样本评估结果完全失真。这个坑每年都有队伍踩。4.4 特征缩放不是所有模型都需要特征缩放标准化、归一化对某些模型是必须的对另一些模型则无所谓。必须做缩放的模型KNN、SVM、神经网络、逻辑回归带正则化时。不需要做缩放的模型决策树、随机森林、XGBoost、LightGBM。E题里如果你用了多种模型做对比记得对需要缩放的模型单独处理不要一刀切。from sklearn.preprocessing import StandardScaler scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) # 注意fit只在训练集上做测试集用transform5. 模型选型与验证E题不是算法竞赛5.1 从基线模型开始不要一上来就上深度学习很多队伍觉得E题要用“高级”模型才能拿高分一上来就搭LSTM、Transformer。但E题的数据量通常不大深度学习很容易过拟合而且训练时间长、调参困难。我的建议是先跑一个逻辑回归或决策树作为基线看看效果如何。如果基线模型已经能达到不错的性能说明特征工程做到位了再尝试更复杂的模型看能否提升。基线模型还有一个好处它能帮你快速验证数据预处理和特征工程是否正确。如果逻辑回归跑出来AUC只有0.5那大概率是数据处理出了问题而不是模型不够复杂。5.2 树模型在E题中的统治地位从历年E题优秀论文来看XGBoost、LightGBM、随机森林是出现频率最高的模型。原因很简单E题的数据通常是表格型数据树模型在表格数据上的表现往往优于深度学习树模型能自动处理特征交互不需要太多人工构造树模型有特征重要性输出可解释性好。import lightgbm as lgb from sklearn.model_selection import cross_val_score model lgb.LGBMClassifier( n_estimators500, learning_rate0.05, max_depth6, num_leaves31, random_state42 ) scores cross_val_score(model, X_train, y_train, cv5, scoringroc_auc) print(fAUC: {scores.mean():.4f} (/- {scores.std():.4f}))5.3 交叉验证E题验证集划分的正确姿势交叉验证是评估模型泛化能力的标准方法但E题里要注意两点。第一如果是时间序列数据必须用TimeSeriesSplit不能用普通的KFold否则未来信息会泄露到训练集。第二如果是分组数据比如同一用户的多条记录必须用GroupKFold保证同一组的样本不会同时出现在训练集和验证集。from sklearn.model_selection import TimeSeriesSplit, GroupKFold # 时间序列 tscv TimeSeriesSplit(n_splits5) # 分组 gkf GroupKFold(n_splits5)5.4 超参数调优网格搜索还是贝叶斯优化超参数调优的方法有网格搜索、随机搜索、贝叶斯优化。网格搜索适合参数少、取值范围小的情况随机搜索适合参数多、计算资源有限的情况贝叶斯优化适合需要精细调优的情况但实现复杂度高。E题时间紧张我通常用随机搜索快速找到大致范围再在小范围内做网格搜索。from sklearn.model_selection import RandomizedSearchCV param_dist { n_estimators: [100, 300, 500, 800], learning_rate: [0.01, 0.05, 0.1], max_depth: [3, 5, 7, 9], num_leaves: [15, 31, 63] } search RandomizedSearchCV( model, param_dist, n_iter30, cv5, scoringroc_auc, random_state42, n_jobs-1 ) search.fit(X_train, y_train) print(search.best_params_)6. 可视化与论文呈现让评委一眼看懂你的逻辑6.1 可视化不是越多越好而是越准越好E题的论文里可视化图表是评委快速理解你思路的窗口。但很多队伍陷入了“图表越多越好”的误区放了十几张图结果每张图都没说清楚。我的原则是每张图都要有明确的表达目的。流程图用来说明技术路线热力图用来说明特征相关性折线图用来说明时间趋势散点图用来说明变量关系混淆矩阵用来说明分类效果。用ECharts或者Matplotlib都可以关键是配色要统一、标注要清晰、图例要完整。我习惯用一套固定的配色方案让整篇论文的图表风格一致看起来更专业。6.2 论文结构从摘要到结论的完整链条华为杯论文的结构通常是摘要、问题重述、问题分析、模型假设、符号说明、模型建立与求解、模型检验、灵敏度分析、模型评价与推广、参考文献、附录。E题的论文要特别注意问题分析和模型检验两部分。问题分析要展示你对业务问题的理解深度模型检验要展示你对模型可靠性的验证。摘要是最重要的部分评委可能只花5分钟看摘要就决定是否仔细阅读全文。摘要要包含问题背景一句话、每个问题的建模方法、主要结果、模型评价。不要写“本文研究了...”这种空话直接写“针对问题一本文构建了...模型得到...结果”。6.3 灵敏度分析E题加分项灵敏度分析是很多队伍忽略的环节但它恰恰是展示你模型鲁棒性的好机会。简单来说就是改变某个关键参数或输入变量观察模型输出如何变化。比如你做了一个预测模型可以分析“当训练集比例从70%变为80%时预测精度如何变化”或者“当某个特征的缺失率增加10%时模型性能下降多少”。# 简单的灵敏度分析示例 from sklearn.metrics import roc_auc_score results [] for train_size in [0.6, 0.7, 0.8, 0.9]: split_idx int(len(X) * train_size) X_tr, X_te X[:split_idx], X[split_idx:] y_tr, y_te y[:split_idx], y[split_idx:] model.fit(X_tr, y_tr) pred model.predict_proba(X_te)[:, 1] auc roc_auc_score(y_te, pred) results.append({train_size: train_size, auc: auc}) print(pd.DataFrame(results))7. 那些年我在E题上踩过的坑7.1 数据泄露最隐蔽也最致命的错误数据泄露是指训练集里包含了测试集的信息导致模型在验证集上表现虚高但实际预测时一塌糊涂。常见的泄露场景包括在划分训练测试集之前做了标准化、在特征选择时用了全部数据、时间序列数据用了随机划分。我踩过最惨的一次是先对全部数据做了PCA降维再划分训练测试集。结果模型在验证集上AUC 0.95实际提交后只有0.6。后来才发现PCA降维时用到了测试集的信息。注意所有数据预处理操作标准化、PCA、特征选择都必须在训练集上fit然后transform测试集。顺序绝对不能反。7.2 过拟合模型在训练集上完美在测试集上崩溃过拟合是E题里另一个高频问题。表现是训练集准确率99%验证集准确率70%。原因通常是模型太复杂、特征太多、训练数据太少。解决方法有减少模型复杂度降低树深度、减少叶子节点数、增加正则化L1/L2、增加训练数据如果可能、早停Early Stopping。# LightGBM早停 model lgb.LGBMClassifier(n_estimators2000, learning_rate0.05) model.fit( X_train, y_train, eval_set[(X_val, y_val)], eval_metricauc, callbacks[lgb.early_stopping(50)] )7.3 时间不够如何合理分配赛程华为杯通常给4-5天时间E题的工作量很大。我的时间分配建议是第一天完成数据审计和预处理第二天完成特征工程和基线模型第三天做模型调优和对比实验第四天做可视化和论文写作第五天查漏补缺和格式检查。千万不要前两天都在清洗数据最后一天才开始写论文那样肯定来不及。7.4 论文写作技术做得好也要写得好我见过很多队伍技术做得不错但论文写得一塌糊涂最后只拿了成功参赛奖。论文写作要注意逻辑清晰、图表规范、公式编号、参考文献格式统一。摘要要反复打磨最好找队友互相审阅。附录里的代码要加注释不要直接贴一大段没有说明的代码。8. 关于E题的一些个人体会做了几届华为杯E题之后我最大的感受是这道题考的不是你有多聪明而是你有多踏实。那些拿一等奖的论文往往不是用了最前沿的算法而是把数据清洗做得干干净净、把特征工程做得有理有据、把模型对比做得清清楚楚、把论文写得明明白白。E题没有标准答案但有一套清晰的评价逻辑你的分析是否严谨、你的结论是否有数据支撑、你的方案是否可落地。如果你正在准备2026年的华为杯我的建议是提前熟悉Pandas、Scikit-learn、LightGBM这几个工具找几道历年E题练手重点练习数据预处理和特征工程。比赛的时候不要贪多把一个问题做深做透比每个问题都浅尝辄止要好得多。最后论文的排版和格式一定要重视这是评委对你的第一印象。还有一个很实用的小技巧比赛期间每天结束时把当天的工作整理成一个小结包括做了什么、遇到什么问题、明天计划做什么。这样到了最后写论文的时候你不需要回忆直接翻小结就能快速组织内容。这个方法我用了三年每次都能帮我在最后一天省下至少三个小时。