数学建模竞赛四类模型:预测、分类、优化与评价实战指南 简介数学建模竞赛常考四大模型总结PDF是一份面向建模参赛者与备赛学生的浓缩参考手册针对竞赛中最常用的预测、分类、优化、评价四类模型进行系统梳理帮助读者快速理解各模型的适用条件与选择思路。预测部分涵盖神经网络、灰色预测、时间序列、马尔科夫链、微分方程及Logistic回归等方法分类模型则介绍了贝叶斯分类、支持向量机、k-means/层次/FCM聚类、主成分分析与判别分析优化模型包括线性规划、非线性规划、整数规划、动态规划以及遗传算法、模拟退火、蚁群算法等现代优化算法评价模型汇总了模糊综合评价、层次分析法、熵权法、灰色关联评价等主流方案。全资料共1个PDF文件压缩包仅225KB目录式结构便于快速定位知识点。目前已有800人学习下载适合赛前冲刺复习、模型速查比对也可作为论文撰写时选择合适方法论的实用指南。1. 为什么竞赛论文的胜负手是这四类模型拿到数学建模竞赛赛题第一件事不是找代码、翻资料而是判断“这题到底在让你干什么”。把历年题目拆开看绝大多数赛题最终都能归到预测、分类、优化、评价这四类模型里区别只是换了个业务场景的外壳。一个反直觉的结论是拿奖的队伍往往不是模型最先进的而是模型选得准、步骤完整、每个参数都解释得清楚的队伍。这篇笔记把这四类模型放在一起讲清各自的适用边界、实现步骤和必调参数既适合第一次备赛的同学快速建立框架也适合有基础的人赛前当速查手册用。2. 预测模型先定基准再上复杂算法参数才有意义2.1 预测问题先归类回归、时序、灰色预测用哪个预测模型的难点不在算法而在判断数据形态。同样是“预测”数据形态不同用的模型完全不同弄错了再好的算法也白搭。我一般把竞赛里的预测问题分成三类第一类是给了多个特征变量去预测一个连续值比如用气温、湿度、风速预测电力负荷这是回归问题核心是找自变量和因变量之间的函数关系第二类是只有一个历史序列让预测下一期或未来几期的值比如逐月统计的销量数据这是时间序列问题核心是从序列自身的变化规律里提取趋势和周期第三类是数据非常少可能只有 5~8 个历史数据点或者数据本身灰度很高、来源不可靠这时候常用灰色预测 GM(1,1)它不需要大量样本对近似指数增长的数据效果还不错。问题类型数据形态样本量要求竞赛常见场景回归分析多特征 连续因变量几十条以上负荷预测、销量预测、价格预测时间序列单一历史序列至少 10~20 期流量预测、趋势外推灰色预测 GM(1,1)少量历史数据4 个以上即可小样本统计、初期数据预测选型的核心原则是先看样本量再看数据形态。样本量够、特征齐全优先回归只有一个序列且要预测长期趋势用时间序列数据短到没法建模才考虑灰色预测。不要把灰色预测当成万能工具它的数学假设很强数据波动一大就失效这一点后面细说。2.2 最小二乘回归的建模步骤与三个必调参数回归建模的路线比较固定先划分训练集和测试集再做标准化处理然后用线性回归或带正则化的岭回归训练最后用均方误差和残差图评估。下面这段代码是回归分析的最小可行模板。import numpy as np import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LinearRegression, Ridge from sklearn.metrics import mean_squared_error # 特征列和目标列按实际数据修改 X data[[temp, humidity, wind_speed]].values y data[load].values # 1) 先切分数据再做标准化避免信息泄露 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42 ) # 2) 标准化量纲差异大时必做 scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) # 只用transform不重新fit # 3) 训练模型特征数量多且共线性高时改用Ridge model LinearRegression() model.fit(X_train_scaled, y_train) # 4) 评估 y_pred model.predict(X_test_scaled) mse mean_squared_error(y_test, y_pred) print(fMSE: {mse:.4f})这段代码里有两个容易出问题的地方。第一train_test_split 的 test_size 参数一般取 0.2 或 0.3样本量小的时候可以适当降到 0.15但千万别为了“多训练几个样本”把测试集砍到几乎没有那样算出来的误差没有代表性。第二StandardScaler 必须先 fit 训练集再用同一个 scaler 去 transform 测试集如果对全部数据一起标准化再切分测试集的信息会漏进训练过程测试分数会虚高。这两个步骤的顺序就是对“数据泄露”的第一道防线。回归里还有一个必调参数是正则化强度。特征只有两三个的时候普通线性回归没问题特征到了几十个或者特征之间相关性强时用 Ridge 并调 alpha一般在 0.01 到 10 之间会更稳定。Ridge 的作用是收缩回归系数防止某个特征单独把预测结果带偏这就是为什么它在线性回归参数调优里几乎是必做的选项。2.3 时间序列与灰色预测什么时候值得用时间序列里最常用也最好解释的是简单指数平滑它的核心参数是平滑系数 α取值在 0 到 1 之间。α 越大模型越看重近期数据曲线越“灵敏”α 越小模型越平滑但会滞后于拐点。实际比赛里如果序列没有明显突变我一般先从 α0.3 起步再看预测值和实际值的残差决定是否调大。灰色预测 GM(1,1) 的步骤更固定适合数据点少于 10 个的场景。它的思想是把原始数据先累加让序列看起来具有指数趋势然后对累加序列做一阶线性拟合最后再累减还原。下面是一个自己实现的 GM(1,1) 计算过程不依赖额外的预测库。import numpy as np def gm11(data, n_pred3): # data: 一维数组至少4个非负数据点 data np.asarray(data, dtypefloat) n len(data) # 1) 累加生成序列 x1 x1 np.cumsum(data) # 2) 紧邻均值生成 z1去掉第一项 z1 (x1[:-1] x1[1:]) / 2 # 3) 构造B矩阵和y向量 B np.column_stack([-z1, np.ones(n - 1)]) y data[1:].reshape(-1, 1) # 4) 最小二乘估计发展系数a和灰作用量b params np.linalg.inv(B.T B) B.T y a, b params[0, 0], params[1, 0] # 5) 累减还原得到拟合并向后预测 x1_hat np.zeros(n n_pred) x1_hat[0] data[0] for k in range(1, n n_pred): x1_hat[k] (data[0] - b / a) * np.exp(-a * k) b / a pred np.diff(x1_hat) # 差分还原成原始量纲 return pred[:n_pred]这段代码的核心是第 4 步通过最小二乘估计发展系数 a 和灰作用量 b这两个参数会直接决定预测曲线是陡还是平a 的绝对值越大增长越快外推越不能走远。使用时有三个前提要注意数据必须非负数据内部需要近似指数增长否则累加序列拟合不准预测期数不要超过已知数据点的一半外推三期以上误差会迅速扩大。很多队伍把灰色预测当“万能预测”结果数据明显振荡也硬套 GM(1,1)预测曲线一条平滑线和实际踩出来的锯齿状完全对不上这在评委眼里就是没搞懂适用条件。3. 分类模型先跑统计判别再决定要不要机器学习3.1 分类问题的两种竞赛形态判别还是聚类分类问题在竞赛里有两种形态一种是有标签的有监督分类比如根据用户行为特征判断是否违约另一种是没有标签、需要把样本分组本质上属于聚类但很多题目会把它包装成“分类”来考常见处理是先聚类再给每类打标签。判断方法是看题目给不给已知类别给就是有监督不给就是聚类。方法的选择上统计学习方法和机器学习方法都有出场空间。Fisher 判别分析LDA是经典统计学方法样本量不大、变量相关性不高的时候表现不错而且论文里好解释逻辑回归是二分类的默认基线输出是概率适合需要说明各特征影响方向的场景支持向量机和随机森林更像“杀手锏”数据复杂、特征多时才值得上。网格搜索调 SVM 参数很费时间数据量不大时跑随机森林更省心。方法适用场景输出形式复杂度Fisher判别分析 LDA小样本、变量服从正态分布类别标签低逻辑回归二分类、需要解释特征方向概率低支持向量机 SVM中等样本、非线性边界类别标签中随机森林特征多、样本量大类别/概率中高3.2 用判别分析跑通第一个分类器LDA 实操Fisher 判别分析的基本思路是找一个投影方向让类间距离尽可能大、类内距离尽可能小。在 scikit-learn 里直接用 LinearDiscriminantAnalysis 就能跑完整的判别流程包括拟合、预测和评估。from sklearn.discriminant_analysis import LinearDiscriminantAnalysis from sklearn.model_selection import cross_val_score from sklearn.metrics import confusion_matrix, classification_report # X_feat: 特征矩阵, y_label: 类别标签 lda LinearDiscriminantAnalysis(solverlsqr, shrinkage0.1) # 交叉验证评估cv5表示5折 scores cross_val_score(lda, X_feat, y_label, cv5) print(fCV accuracy: {scores.mean():.3f}) # 训练并输出混淆矩阵 lda.fit(X_feat, y_label) y_pred lda.predict(X_feat) print(confusion_matrix(y_label, y_pred)) print(classification_report(y_label, y_pred))LDA 有两个参数值得说solver 和 shrinkage。solver 默认用 svd对小样本稳妥数据量在几十到几百之间、特征数少于样本数时用 lsqr 可以配合 shrinkage 做正则化防止协方差矩阵不稳定。cross_val_score 的 cv 参数一般取 5 或 10这里直接给出的是交叉验证平均准确率比单次切分的结果可信得多。LDA 的数学假设比较强要求各类别的协方差矩阵近似相等、特征近似服从正态分布。数据不满足这两个条件时判别分析的准确率会明显下降你会发现混淆矩阵里某几类总是被混在一起。遇到这种情况不需要强行调参直接转逻辑回归或 SVM 就好非要在一棵树上吊死就是浪费时间。3.3 支持向量机与随机森林的调参要点SVM 在竞赛里最常用的核是 RBF 高斯核它的表现主要由惩罚系数 C 和核系数 gamma 决定。C 越大模型越倾向把所有训练样本分对容易过拟合C 越小模型越保守但可能欠拟合。gamma 控制单个样本的影响范围gamma 太大决策边界会变成一个个孤岛sex 数据表现很尖刺gamma 太小边界又过于平滑。网格搜索里我一般让 C 在 0.1~100 之间按对数取gamma 在 0.001~1 之间取交叉验证选效果最好的一组。随机森林的调参方向完全不同主要关注 n_estimators 和 max_depth。n_estimators 也就是树的数量500 棵左右已经能覆盖大多数情况加太多只会增加计算时间对精度帮助有限max_depth 限制每棵树长多深太深会过拟合一般从 5 开始试。还有个容易忽略的参数是 class_weight当类别不平衡时设置成 balanced 能让少数类被更多人关注到否则模型会把所有样本都判给多数类准确率还挺高实际上一类完全没分出来这是典型的翻车现场。网格搜索本身也有一个隐蔽的坑如果在调参时把验证集也放进训练过程参数会对验证集过拟合最后在测试集上崩掉。我的习惯是先把数据切成训练、验证、测试三份网格搜索只在训练和验证之间进行所有参数确定后再用测试集做一次最终评估这个分数才是论文里能写的数据。4. 优化模型建模比求解更重要灵敏度是得分点4.1 优化建模三要素变量、目标、约束怎么抽优化模型的题目看起来五花八门实际上都是同一套模板告诉你一些资源限制让你在限制下追求某个目标最大或最小。做优化题的第一步不是写代码而是把题目翻译成数学语言说清楚三件事决策变量是什么目标函数是什么约束条件是什么。决策变量是你能控制的东西比如安排多少辆车、每条生产线生产多少件目标函数是你要优化那个量比如总成本、总利润约束条件则是题目里给的各种限制比如车辆数量上限、原材料库存、时间窗口。把这三件事写清楚之后优化模型基本就成型了。三者的完整程度直接决定求解结果能不能被评委认可。很多队伍写出一个目标函数就开始求解解出来的结果却明显违背题目的物理限制根源就是约束条件没写全。约束条件里最容易漏掉的就是变量的取值范围非负性、整数性、0-1 约束这些默认限制一旦不写上求解器就会给出明显不合理的答案。4.2 线性规划与整数规划的求解实操竞赛里最常见的优化模型是线性规划目标函数和约束都是线性的。在 scipy 里用 linprog 求解代码如下。from scipy.optimize import linprog # 例两种产品目标为总利润最大化等价于minimize(-利润) # min c^T x, s.t. A_ub x b_ub, A_eq x b_eq, bounds 限定变量范围 c [-5, -4] # 利润系数取负号因为linprog默认求最小值 A_ub [ [2, 1], # 原料约束2x1 x2 10 [1, 2] # 工时约束x1 2x2 8 ] b_ub [10, 8] bounds [(0, None), (0, None)] # 两个产量变量均非负 result linprog(c, A_ubA_ub, b_ubb_ub, boundsbounds, methodhighs) print(result.fun, result.x)这段代码有三个参数需要细看。methodhighs 是现在 scipy 里推荐的求解器数值稳定性比旧版 simplex 好很多值得固定使用。c 向量里的负号是初学者最容易踩的坑linprog 默认求最小值要求最大化利润时必须把目标系数全部取反。A_ub 和 b_ub 对应的是“小于等于”约束如果你的约束是“大于等于”需要先对整个不等式两边乘以 -1 转成小于等于这个符号问题一旦反了求解器要么直接报不可行要么给出和题意相反的结果。更进一步如果变量要求是整数linprog 就不适用了需要用 scipy.optimize.milp 或者整数规划专用求解器。整数规划比线性规划难求得多变量数量超过几十个时求解时间会明显上升。比赛的题目如果带“车辆数、人数、台数”这类离散量就涉及整数规划这时候建议先用连续解的松弛版本看看目标上界再切到整数求解心里有底后再跑完整模型。4.3 遗传算法与灵敏度分析的使用边界线性规划能解决的问题直接用求解器解决就好真正让遗传算法这类启发式算法出场的是非线性、非凸或组合爆炸问题。比如排班、路径规划这类问题变量组合数量大精确求解算不动只能靠遗传算法这类随机搜索方式找一个“够好”的解。遗传算法的参数属于典型的“黑匣子”试出来的种群大小一般取几十到几百迭代次数看收敛曲线交叉率 0.7~0.9变异率 0.01~0.1。这些数值没有绝对标准但要养成一个习惯每次运行固定随机种子否则同一个参数跑两次结果不一样论文里的数字没法复现。我一般用 random_state 固定种子并跑三次取最优这样既能控制随机性又能体现算法的稳定性。比求解更值得花时间的是灵敏度分析。所谓灵敏度分析就是把目标函数的系数或约束右侧的资源量扰动 ±10%看最优解和最优目标值会不会剧烈变化。这是一个刻意做的实验不用求解器也能做却很能说明模型的鲁棒性。比如资源约束的右侧值从 10 变成 11目标值只变了 1%说明结果对资源不太敏感如果变了 20%说明这个约束是瓶颈评委一看就知道你理解问题的结构。5. 评价模型权重是主观的但一致性检验让结论客观5.1 评价模型解决什么问题从权重到排序评价模型解决的是“多个候选方案、多个评价对象到底谁更好”的问题。竞赛里常见的出题方式是给你若干条河流、若干所学校、若干城市的指标数据让你做一个综合排名或选优。这类题目的本质不是预测也不是分类而是给定指标体系后确定权重再算出综合得分排序。核心三步是先定指标再定权重最后算综合得分。权重的确定是评价模型的分水岭。权重从哪里来决定了评价方法的选择。层次分析法 AHP 靠专家或自己主观打分优点是能处理没有历史数据的新问题缺点是主观性太强必须有数学检验支撑熵权法完全靠数据波动程度定权重指标数据变化越大权重越高完全客观但可能不符合实际重要性TOPSIS 不做权重而做距离排序适合指标量纲差异大的综合排名模糊综合评价用隶属度处理边界模糊的评价适合定性指标多的场景。5.2 层次分析法判断矩阵与一致性检验实操层次分析法的核心是构造两两比较的判断矩阵。比如三个指标 A、B、CA 比 B 重要多少A 比 C 重要多少B 比 C 重要多少这些比例填成一个 3×3 矩阵。然后计算权重通常用特征向量法同时必须做一致性检验确保你的打分没有出现“A 比 B 重要B 比 C 重要C 又比 A 重要”这种逻辑矛盾。下面用 numpy 实现权重计算和一致性检验。import numpy as np # 判断矩阵Aa_ij表示指标i比指标j的重要程度 A np.array([ [1, 3, 5], [1/3, 1, 2], [1/5, 1/2, 1] ]) # 1) 计算最大特征值和特征向量 eig_vals, eig_vecs np.linalg.eig(A) max_eig max(eig_vals.real).real # 取最大特征值对应的特征向量归一化为权重 idx np.argmax(eig_vals.real) w np.abs(eig_vecs[:, idx].real) w w / w.sum() # 2) 一致性检验CI越小越一致CR0.1时通过 n A.shape[0] CI (max_eig - n) / (n - 1) RI_dict {1:0, 2:0, 3:0.58, 4:0.90, 5:1.12, 6:1.24} RI RI_dict[n] CR CI / RI print(f权重: {w}) print(fCR: {CR:.4f})参数上只有一个地方需要特别注意RI 是查表得到的随机一致性指标不同阶数对应不同值3 阶矩阵 RI 是 0.584 阶是 0.90n 小于 3 时不需要检验一致性因为二阶矩阵一定是一致矩阵。CR 小于 0.1 才认为打分可以接受如果超了就回去调整判断矩阵里偏差最大的比值而不是强行改代码。AHP 的常见误区是用在指标特别多的场景。指标一多两两比较矩阵瞬间变成 8 阶、9 阶打分次数多到人根本没法保持一致CR 反复不通过。这时候我的做法是改用层次化处理同一维度下的指标先比较再比较维度之间的权重两层分别做一致性检验虽然工作量大了但每层矩阵阶数低逻辑矛盾容易修正评委看起来也更认可。5.3 熵权法与 TOPSIS客观权重怎么算熵权法不依赖人打分只用数据自身的信息量定权重。它的逻辑是某个指标的数值在所有样本里差异越大说明它区分能力越强理应给更大权重。下面代码演示了熵权法的完整计算。import numpy as np import pandas as pd # X: 样本×指标的数值矩阵已确认正向指标和负向指标 def entropy_weight(X, positive_cols, negative_cols): # 1) min-max标准化正向指标和负向指标用不同公式 X_norm np.zeros_like(X, dtypefloat) for i in range(X.shape[1]): if i in positive_cols: X_norm[:, i] (X[:, i] - X[:, i].min()) / (X[:, i].max() - X[:, i].min()) else: # 负向指标越小越好需转换方向 X_norm[:, i] (X[:, i].max() - X[:, i]) / (X[:, i].max() - X[:, i].min()) # 2) 计算每个样本在指标i上的比重 P X_norm / X_norm.sum(axis0, keepdimsTrue) # 防止log(0)给比重加上极小值 P np.clip(P, 1e-10, 1) # 3) 信息熵 e 和信息效用值 d m X.shape[0] e -1 / np.log(m) * np.sum(P * np.log(P), axis0) d 1 - e # 4) 权重归一化 w d / d.sum() return w熵权法的关键参数藏在标准化里。正向指标用“越大越好”的公式负向指标必须先转换方向否则权重会完全反掉论文里拍脑袋定了指标却忽视方向性的队伍非常多结果算出来的排名和直觉完全相反。min-max 标准化本身对离群值敏感如果某个指标存在明显的极端值可以先做截断处理再标准化。TOPSIS 法本身不计算权重而是要计算每个样本到正理想解和负理想解的距离最终用贴近度排序。它和熵权法往往是组合使用的先用自己的方法得到权重再用 TOPSIS 算排序。要注意的是组合使用时要解释两个方法各自承担的任务不能只说“用了熵权法TOPSIS”就完事评委想看到的是“为什么权重用客观赋权、排序用距离评价”的思路链条。6. 四大模型通用避坑清单从数据泄露到灵敏度分析的四条高频踩坑预测、分类、优化、评价四类模型看起来差别很大但翻车的原因高度重合集中在中途的四个环节上整理成清单方便赛前排查。第一条数据泄露。现象训练集准确率接近满分测试集分数掉一半。原因标准化、缺失值填充等预处理操作在切分数据之前对全量数据做了 fit。解决必须“先切分再预处理”标准化器只用训练集 fit测试集只做 transform。这一点在预测和分类题目里最常见也是评委问“你的测试集分数为什么这么高”时最容易露馅的地方。第二条优化模型约束条件方向写反。现象求解器报不可行或者最优解完全不符合物理意义。原因大于等于约束没有转换成 linprog 要求的小于等于格式A_ub 的行列对应关系写错。解决把每个约束先写成数学式再转成矩阵形式提交求解器前人为构造一个明显可行的解做验证。第三条评价模型权重来源说不清。现象评委问“这些权重为什么这么定”回答只有一句“根据经验”。原因主观权重没做一致性检验或用熵权法却没有说明为什么要用客观赋权。解决AHP 补 CR0.1 的一致性检验熵权法说明数据来源两类方法组合时补充组合比例的设定理由。第四条没有灵敏度分析或鲁棒性验证。现象论文结论是一组固定参数下的单一结果无法回应“参数稍变结论是不是就翻转”。原因只跑了一次最优解就写论文没做扰动实验。解决把目标函数系数和约束资源量扰动 ±10%对比最优解和最优值的变化幅度把这段分析放进论文的最后一部分这往往是评审印象提升最快的一步。最后分享一个我一直保留的习惯无论拿到哪类题目先写一个最笨的基线版本均值预测、多数类分类、贪心解都行然后把高级模型和基线对比。很多队伍预测题直接上 LSTM最后却被追问“为什么不用回归”而答不上来就是因为没有先回答“基线有多差你的模型进步了多少”。先跑基线再谈优化能避免大量徒劳的调参比任何模型技巧都省时间。希望帮到你。本文还有配套的精品资源点击获取