简介这份资料面向备战“泰迪杯”全国数据挖掘挑战赛的高校学生与指导教师系统梳理了竞赛背景、题型分类、参赛流程与评分标准帮助参赛者快速建立对赛事的整体认知。压缩包内仅含1个docx文档体积约88KB内容以文字讲解为主便于随时查阅与整理笔记。文档围绕数据挖掘全流程展开涵盖Python、R、MATLAB等基础工具Pandas、NumPy、Scikit-learn、XGBoost、TensorFlow等常用库以及缺失值处理、异常值检测、特征选择、降维、监督与无监督学习、时间序列分析等核心知识点。往届真题解析部分以2022年A题城市轨道交通客流预测为例展示从数据预处理、时间特征提取到ARIMA、LSTM、时空图神经网络建模的完整思路并附代码片段与优秀方案示例。此外还整理了常见问题解决方案、学习资源推荐、历届赛题汇总与常用术语表已有66人学习适合希望系统备赛、提升实战能力的读者参考。1. 从一份“泰迪杯数据挖掘竞赛学习资料”说起它到底能帮你解决什么如果你正在准备数据挖掘类竞赛或者想找一个能把数据预处理、特征工程、模型构建、结果分析串起来的实战参照这份“泰迪杯数据挖掘竞赛学习资料”大概率能省掉你不少翻帖子的时间。它不是一个空泛的竞赛介绍而是把赛题类型、评分标准、技术栈、往届真题解析和可运行代码片段打包到了一起。适合谁第一次参赛、不知道从哪下手的同学做过一两次但总在特征工程和模型融合上翻车的老手以及想用真实赛题练手、补齐机器学习工程链路的从业者。最直接的价值是你拿到的不只是“要学什么”而是“别人怎么拆题、怎么选模型、怎么把代码跑通”。2. 竞赛评分标准拆解为什么你的模型分数高却拿不到奖2.1 评分权重背后的真实优先级这份资料里写得很清楚泰迪杯的评分通常分四块数据处理能力占20%分析方法选择占25%结果质量占30%报告质量占25%。很多人第一反应是“结果质量最高那我猛调模型就行了”。但实际参赛过的都知道结果质量只占30%而且这30%里还包含模型稳定性和泛化能力不是单纯刷准确率。更关键的是数据处理和分析方法加起来占了45%这意味着评委在看你报告的前半部分时就已经在判断你有没有拿奖的潜质了。我一般会建议把评分标准当成一个反向检查清单。比如“数据清洗与预处理质量”这一项不是说你用了多少种插补方法而是你有没有说清楚为什么选这个阈值、异常值判定依据是什么、缺失值机制是随机缺失还是非随机缺失。这些在报告里写清楚比多跑几个模型管用。2.2 从评分标准反推技术路线资料里给了一个很实用的思路优先尝试经典可靠的方法适度创新避免过度复杂化。这句话听起来像废话但结合评分标准看就很有意思了。分析方法选择占25%其中“方法的合理性与创新性”是并列的。也就是说你用XGBoost加特征工程拿到不错的结果只要逻辑自洽并不比硬上图神经网络分数低。反而如果模型太复杂、解释不清楚报告质量那25%会丢分。常见做法是先用LightGBM或XGBoost跑一个基线把特征重要性输出出来再决定要不要上深度学习。如果基线已经能解释大部分方差深度学习更多是锦上添花不是雪中送炭。下面这段代码就是典型的基线加特征重要性分析适合在初赛阶段快速判断数据里有没有强信号。import pandas as pd import numpy as np import lightgbm as lgb from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error # 假设 df 是已经做过基础清洗的数据框target 是预测目标列 X df.drop(columns[target, id, timestamp]) y df[target] # 时间序列类赛题不能随机划分这里用前80%做训练后20%做验证 split_idx int(len(df) * 0.8) X_train, X_val X.iloc[:split_idx], X.iloc[split_idx:] y_train, y_val y.iloc[:split_idx], y.iloc[split_idx:] # 基线模型不做复杂调参先看特征重要性 model lgb.LGBMRegressor( n_estimators500, learning_rate0.05, num_leaves31, subsample0.8, colsample_bytree0.8, random_state42 ) model.fit( X_train, y_train, eval_set[(X_val, y_val)], eval_metricrmse, callbacks[lgb.early_stopping(50), lgb.log_evaluation(100)] ) # 输出特征重要性按增益排序 importance pd.DataFrame({ feature: X_train.columns, gain: model.booster_.feature_importance(importance_typegain) }).sort_values(gain, ascendingFalse) print(importance.head(20))这段代码的逻辑是用LightGBM快速建立一个可解释的基线early_stopping防止过拟合feature_importance按增益排序能直接告诉你哪些特征在起作用。参数上num_leaves31是默认值数据量小的时候可以降到15左右learning_rate0.05配合500棵树是比较稳的组合如果验证集RMSE还在降可以加到1000但要把学习率降到0.02。跑完这一步你至少知道该往哪个方向做特征交叉而不是盲目试模型。3. 往届真题的技术路线复现从客流预测到异常检测3.1 城市轨道交通客流预测的时空建模思路资料里2022年A题是城市轨道交通客流预测优秀方案用了时空图神经网络加注意力机制。这个方案听起来复杂但拆开看就是三件事把地铁网络建成图、用GCN捕捉空间依赖、用LSTM或TCN捕捉时间依赖。如果你不想一上来就写STGCN可以先用“站点聚类LightGBM”做一个简化版。具体做法是先根据站点历史客流曲线做K-means聚类把站点分成几类然后把类别作为类别特征喂给LightGBM。这样既利用了空间信息又不用写图卷积。from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler # 构造站点日客流曲线矩阵行是站点列是各小时平均客流 station_profiles df.pivot_table( indexstation_id, columnshour, valuespassenger_count, aggfuncmean ).fillna(0) # 标准化后聚类k根据轮廓系数选一般3到6类 scaler StandardScaler() profiles_scaled scaler.fit_transform(station_profiles) kmeans KMeans(n_clusters4, random_state42, n_init10) station_profiles[cluster] kmeans.fit_predict(profiles_scaled) # 把聚类结果合并回原始数据作为新特征 df df.merge( station_profiles[cluster].reset_index(), onstation_id, howleft )这段代码的关键参数是n_clusters不要拍脑袋定。我一般会跑一遍轮廓系数选0.3以上的k值。另外aggfuncmean是按小时取平均如果数据里有工作日和周末差异应该分开聚类再合并。这个特征构造方式在客流预测类赛题里很常见比直接扔原始站点ID给模型要稳。3.2 用电异常检测的两种落地路径2019年A题是电力用户行为分析与用电异常检测资料里给了孤立森林和自编码器两种方案。这两个方法的选择取决于你的数据标注情况。如果没有标签孤立森林是首选因为它不需要假设数据分布对高维数据也友好。如果有少量标签自编码器可以通过重建误差做半监督学习。实际比赛中我一般会两个都跑然后用投票法融合。from sklearn.ensemble import IsolationForest from sklearn.preprocessing import StandardScaler import numpy as np # 特征矩阵每行是一个用户某段时间的用电统计量 features df[[mean_load, std_load, peak_ratio, valley_ratio, load_factor]] scaler StandardScaler() features_scaled scaler.fit_transform(features) # contamination 根据业务经验设一般0.01到0.05之间 iso IsolationForest( n_estimators200, contamination0.02, max_samplesauto, random_state42 ) iso.fit(features_scaled) # decision_function 返回异常分数越小越异常 anomaly_score iso.decision_function(features_scaled) anomaly_label iso.predict(features_scaled) # -1 为异常1 为正常 df[anomaly_score] anomaly_score df[anomaly_label] anomaly_label这里contamination是最关键的参数。设大了误报多设小了漏报多。我的经验是先按业务预期设一个值比如电力异常通常不超过2%然后看异常分数分布如果-1的样本在分数直方图上明显左偏说明阈值合理。另外max_samplesauto在数据量大时会自动采样如果数据超过1万行可以手动设成256或512来加速。3.3 大气污染时空预测的插值可视化2018年B题涉及污染物时空分布资料里用了griddata做空间插值。这个技术点在很多可视化类赛题里都能复用。核心逻辑是你有若干个监测站点的坐标和污染物浓度想画出整个城市的污染分布图。griddata支持cubic、linear、nearest三种插值方式cubic最平滑但可能过冲linear最稳但边缘生硬。我一般先用linear看整体趋势再用cubic出图。import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import griddata # station_locations: N x 2 的经纬度数组 # pollution_values: N 个站点的污染物浓度 x station_locations[:, 0] y station_locations[:, 1] z pollution_values # 生成插值网格 xi np.linspace(x.min(), x.max(), 200) yi np.linspace(y.min(), y.max(), 200) xi, yi np.meshgrid(xi, yi) # cubic 插值如果报错就换 linear zi griddata((x, y), z, (xi, yi), methodcubic) plt.figure(figsize(10, 8)) plt.contourf(xi, yi, zi, levels20, cmapRdYlBu_r) plt.colorbar(labelPM2.5 (ug/m3)) plt.scatter(x, y, cblack, s30, marker^, labelMonitoring Station) plt.legend() plt.title(Spatial Distribution of PM2.5) plt.xlabel(Longitude) plt.ylabel(Latitude) plt.tight_layout() plt.savefig(pollution_map.png, dpi300)这段代码里levels20控制等值线的密度太多会糊太少会丢细节。cmapRdYlBu_r是反向的红黄蓝红色代表高污染符合直觉。如果插值结果出现明显的同心圆伪影说明站点太稀疏这时候应该改用linear或者加一个mask把无数据区域盖掉。4. 避坑与排查参赛者最容易翻车的五个地方4.1 数据泄漏验证集分数高得离谱现象本地交叉验证RMSE只有0.1提交后线上分数差了一个数量级。原因特征里混入了未来信息比如用全量数据算的均值编码、或者时间序列里做了随机划分。解决时间序列必须按时间切分类别编码只能在训练集上拟合然后映射到验证集。我一般会写一个检查函数确保验证集的每个特征分布和训练集没有系统性偏移。4.2 缺失值处理不当把信号当噪声填了现象填充缺失值后模型效果反而下降。原因缺失值本身可能携带信息比如某些传感器故障导致的缺失直接填均值等于抹掉了这个信号。解决先做缺失值模式分析如果缺失比例超过30%且非随机考虑把“是否缺失”作为一个二值特征加进去而不是直接填充。4.3 模型过拟合训练集完美验证集崩盘现象训练集准确率99%验证集只有70%。原因模型太复杂、特征太多、样本太少或者用了默认参数没做正则化。解决先降模型复杂度比如把XGBoost的max_depth从10降到5加min_child_weight和gamma。如果还不行做特征选择把重要性低于阈值的特征砍掉。4.4 报告图表不可读评委看不懂等于没做现象技术报告里堆了十几张图但每张图都没有标题、坐标轴标签和图例。原因只顾着跑模型忽略了报告也是评分的一部分。解决每张图必须有标题、坐标轴含义、单位、图例。折线图不要超过5条线柱状图按数值排序热力图加数值标注。这些细节在报告质量那25%里很拉分。4.5 答辩被问倒说不清为什么选这个模型现象答辩时评委问“为什么用LSTM不用Transformer”答不上来。原因只跑了代码没理解模型假设和适用边界。解决准备一个“模型选择对照表”把候选模型的假设、优缺点、在你的数据上的表现列出来。比如LSTM适合中等长度序列、参数量可控Transformer适合长序列但需要更多数据。能说清楚取舍比模型本身多先进更重要。5. 把资料用出最大价值我的复现习惯和一条硬规矩这份资料里往届真题的代码片段是分散的直接复制粘贴跑不通是常态。我的习惯是先建一个统一的目录结构把每个赛题的数据、代码、报告分开然后写一个config.yaml管理路径和参数。这样换赛题的时候只需要改配置不用动代码逻辑。另外资料里提到的时空图神经网络、ConvLSTM这些不要一上来就硬啃。我一般会先跑通一个简化版比如用站点聚类代替图卷积用滑动窗口加LightGBM代替ConvLSTM确认数据里有时空信号之后再上复杂模型。还有一个硬规矩每次跑完模型必须把验证集预测结果和真实值按时间画出来。如果模型在高峰期预测偏低、低谷期预测偏高说明它没学到周期性这时候加时间特征比换模型有用。下面这个检查脚本我每次都会跑一遍。import matplotlib.pyplot as plt # y_val 是验证集真实值y_pred 是模型预测值 # timestamps 是对应的时间索引 plt.figure(figsize(14, 5)) plt.plot(timestamps, y_val, labelActual, alpha0.8, linewidth1.5) plt.plot(timestamps, y_pred, labelPredicted, alpha0.8, linewidth1.5, linestyle--) plt.xlabel(Time) plt.ylabel(Passenger Count) plt.title(Validation Set: Actual vs Predicted) plt.legend() plt.grid(alpha0.3) plt.tight_layout() plt.savefig(validation_check.png, dpi200) plt.show() # 计算分时段误差看模型在哪些时段表现差 residual y_val - y_pred hourly_mae pd.DataFrame({ hour: timestamps.hour, abs_error: np.abs(residual) }).groupby(hour)[abs_error].mean() print(hourly_mae.sort_values(ascendingFalse).head(5))这段代码的价值在于它不告诉你模型好不好它告诉你模型在哪里不好。hourly_mae排在前面的时段就是你需要补特征的地方。比如早高峰误差大就加“是否早高峰”的哑变量深夜误差大就加“是否节假日”的交互项。从那以后我每次提交前都强制走一遍这个检查至少能避免“模型看起来还行但一提交就翻车”的情况。希望帮到你。本文还有配套的精品资源点击获取