简介:面向数学建模竞赛参赛者的模型方法速查PDF,系统归纳预测、分类、优化、评价四大常考模型,适合备赛阶段快速定位解题思路与赛前冲刺强化。压缩包内为单个PDF文件,大小约225KB,按四大部分组织目录,并在每部分给出模型原理、应用场景和优缺点提醒。内容覆盖较全:预测部分包含神经网络、灰色预测、线性回归、时间序列、马尔科夫链、微分方程与逻辑回归,并强调神经网络需大量数据与数据清洗、灰色预测适合小样本等关键要点;分类部分涉及贝叶斯、支持向量机、K均值、层次聚类、模糊聚类、主成分与判别分析;优化部分梳理线性规划、整数规划、动态规划、排队论及遗传算法、模拟退火、蚁群算法等现代优化算法;评价部分则列出模糊综合评价、层次分析法、熵权法、灰色关联评价、包络分析等常用工具。目前已有800人学习下载,对需要快速构建完整模型体系、提升竞赛实战效率的读者有参考价值。
1. 数学建模竞赛常考四大模型全景:预测、分类、优化、评价各解决什么问题
数学建模竞赛里最常被翻牌的,就是预测模型、分类模型、优化模型和评价模型这四类。预测模型回答未来会到多少;分类模型回答样本属于哪一类;优化模型在约束下找最赚的排法;评价模型给多个候选方案排个优劣次序。不少同学一口气背几十个算法,拿到题仍然发懵,关键不是记不住公式,而是没有先分析题里要的是哪类问题。这里从四类模型中各挑最稳定的代表作,把建模步骤、软件操作和参数边界一起讲清,适合正在备赛、想按题下菜而不是背算法的人。
2. 预测模型:数据不足用GM(1,1),数据充足先上SPSS回归
2.1 数据量少于20也能做趋势:灰色预测GM(1,1)的最小建模流程
竞赛题经常只给7个点、12个点,不带季节项,还偏要预测三期之后的值。数据这么少,回归容易过拟合,神经网络又谈不上训练,我这里最常用的是GM(1,1)灰色预测。它的核心思想是先把乱序数列做一次累加生成,让序列呈现近似指数形态,再用一阶线性微分方程去拟合,最后做累减还原回原始量纲。
建模步骤分五步走:
- 级比检验。计算级比λ(k)=x_{k-1}/x_k,全部落在区间(e^{-2/(n+1)}, e^{2/(n+2)})内,说明数列适合GM(1,1)。
- 累加生成。新序列y_k = sum_{i=1}^{k}x_i。
- 构造均值序列。z_k = (y_k + y_{k-1})/2,用于拟合微分方程中的背景值。
- 最小二乘求参数。令微分方程dy/dt + a y = b,通过累加序列与均值序列联立解出发展系数a和灰作用量b。
- 累减还原。先给出累加序列预测,再逐个做差分得到原始量纲的预测值。
参数上重点关注发展系数a。一般经验是-a小于0.3才适合做中长期预测;-a超过0.5,说明数据本身增速太快,GM(1,1)只能报短期值,硬往外推三期容易整体偏移。级比检验不通过时,常见做法是先对原始数据做对数变换或开平方,再做一次级比检验;仍不通过,就让题目改用趋势外推或曲线拟合,不是所有数列都吃这套灰色模型。
我一般不会手算到最后一位。手算只用来给评委展示推导过程,正式结果用Excel或者MATLAB的一段小脚本跑。常见做法是:先累加,再构造均值序列,再用最小二乘公式求参数。MATLAB脚本关键也就十几行,重点在把累加序列和还原序列两个循环写对,写错了结果会整个相位偏移。
2.2 用SPSS跑通一元线性回归分析:菜单操作、输出表读法与R²的边界
数据量到了30个以上且有明显趋势,我更倾向于做一元线性回归,而不是直接上复杂模型。SPSS操作很直接:分析→回归→线性,把因变量拖进去,自变量拖进去,统计里勾选估算值、置信区间、模型拟合,点击确定,结果会出一组核心表。这些表要按顺序读:
- 模型摘要表:先看R²与调整后R²。R²特别高不代表模型好,尤其样本量小、变量多的时候,调整后R²更能说明真实拟合度。
- 方差分析表:看F检验的Sig.。小于0.05才认为自变量解释力足够,大于0.05时这回归基本没有建模意义。
- 系数表:看非标准化系数B、标准化系数Beta和各自Sig.。B用于写回归方程,Beta用于比较各变量强度。
多元回归时还要补一张共线性诊断输出,方差膨胀因子VIF超过10就说明变量之间高度相关,需要删变量或者考虑岭回归。
我也经常用Python跑同样的分析,等价代码如下,适合放在报告附录里复现:
from statsmodels.formula.api import ols import pandas as pd df = pd.read_csv('traffic.csv', encoding='utf-8') model = ols('tonnage ~ vehicle_count', data=df).fit() print(model.summary())这段代码把因变量tonnage和自变量vehicle_count的线性回归一步跑出来。model.summary()输出表与SPSS类似,包含R²、F值、t统计量。要换多元方程,直接把右侧改成'metric ~ factor1 + factor2'即可。需要注意:ols默认带截距项,如果你先对数据做了标准化,截距的含义就变了,写解释时不要照搬原方程。
把R²从0.72硬顶到0.96这个操作,我在模拟项目X里见过不少次。方法是不断往右边加相关变量,训练集R²高,但换验证集测试立刻掉回去。SPSS里有一个更负责任的操作:在线性回归对话框里打开保存→预测值/残差,把残差列导出来画散点图。如果残差出现曲线弯曲,说明欠了一个二次项;如果残差随位置越变越宽,则是方差不齐。这些判断比单纯追求R²更有价值。
2.3 预测模型的验证:残差、RMSE和数据泄漏的坑
预测模型写进论文之前,先做三件事:残差检查、RMSE计算、按时间切分的验证集。残差检查的习惯是,把预测值和真实值相减得到残差数组err,先看均值是否接近0,再用sqrt(sum(err.^2))计算RMSE,最后用plot把残差散点画出来,并设置axis范围,避免个别样本拉坏视觉判断。残差中若还有明显趋势或周期性,说明模型没有把序列结构提取干净,这时回到特征端而不是盲目换模型。
MAPE是另一个常用指标,一般控制在10%以内算比较稳;超过20%就要回头检视数据是否有突变点或样本量是否太小。数据泄漏这个坑最隐蔽。很多人先把全量数据的均值、标准差算好,再切训练集和测试集,此时测试集已经混合了整体统计信息,预测指标会异常漂亮。正确顺序永远是先切分,再独立计算每段的归一化参数。
时间序列还有一层:如果序列有明显季度或年度周期,且样本量覆盖超过两个周期,可以考虑季节分解或加入周期性虚拟变量。只有样本量几百、特征之间非线性明显时,才轮到LSTM这类深度学习模型上场。竞赛现场调LSTM成本很高,小样本慎用,这也是我在预测模型章节反复强调的边界。
3. 分类模型:感知机、Logistic回归到集成学习,分堆边界怎么确定
3.1 感知机与Logistic回归:从线性分界面到概率化分类
分类题的特征是“判断、识别、判别类别”。最朴素的分类器是感知机,把样本代入w·x+b,符号决定类别,好写但结果只有正负,没有概率。比赛里我通常拿感知机当基准线,先确认数据线性是否可分,再换Logistic回归进入正式建模。
Logistic回归输出的是p = σ(w·x+b),可以把得分映射到0到1的概率。它带来的不仅仅是概率值,还有后续的ROC曲线、最优阈值选择。很多同学把阈值固定在0.5,忽略了样本不平衡时0.5往往并不是最佳切割点。我会用f1-score当选择标准,在验证集上扫一遍阈值,找到让少数类和多数类平衡的那个点。
线性可分只是理想情况,数据一旦呈团状交错,Logistic回归的边界就开始对付不过来。此时可以升级到带RBF核的SVM,也可以直接上集成学习。升级之前先用标准化和相关性过滤噪音,是我通常会做的事。特征尺度差好几个数量级时,核函数的距离计算全被大尺度变量统治,调参意义不大。
3.2 K-means与层次聚类:无监督分类的参数怎么定
赛题如果没有标签,只给一堆客户特征或城市指标,就要用无监督方法聚类。K-means流程人人会背:指定k,初始化中心,把样本归到最近中心,重新算中心,循环到目标函数不再变化。真正让新手焦虑的是k选多少。我一般把k从2跑到10,记录每个k的轮廓系数,再配合肘部图看SSE下降趋势。某个k之后SSE下降明显变缓,同时轮廓系数到达峰值前后,这个k就是备选值。
K-means对距离尺度很敏感,用前必须做z-score标准化。常见的翻车现场是没有标准化就聚类,结果变量量纲大的组完全支配距离计算,画出来像聚类了,其实是按量纲分了层。除了K-means,我还习惯补一个层次聚类做交叉验证。层次聚类不需要预设k,先画树状图,切割阈值取到长分支距离最大的那条线,得到分类数,再用这个k回去跑K-means,两套结果一致时,结论才算有说服力。
K-means在Python里几行就能跑。我先用pandas读入数据,删掉明显不成指标的特征列,再做标准化,然后指定随机种子和初始化次数:
from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler import pandas as pd df = pd.read_csv('customer_feature.csv') X = df.drop(columns=['city_id']) X_scaled = StandardScaler().fit_transform(X) km = KMeans(n_clusters=4, random_state=42, n_init=10).fit(X_scaled) df['cluster'] = km.labels_注意n_init参数。旧版本只跑一次初始化,结果每次运行都可能变化;固定random_state并设置n_init=10后,模型会在10个初始点里选目标函数最小的结果。比赛报告里写参数时也好交代,不至于让评委复现时发现结果对不上。
3.3 集成学习与SVM:单模型打不赢时的现场升级策略
当题目要求把数据分成多个类别,而且单模型验证时打不赢,再考虑SVM或集成学习。SVM的优势是核函数能把样本映射到高维找分割面,但参数敏感,尤其是RBF核的gamma和C。gamma过大容易过拟合,C过大会把容忍噪音的空间压缩掉。我在比赛中会先用Logistic回归的准确率当基线,然后跑随机森林和SVM,比较准确率、召回率、f1各项,再用验证集确认不是某次随机采样带来的好运。
集成学习里,随机森林对缺失值容忍度高、训练也快,适合在数据不够规整的时候先用。XGBoost这类提升树的拟合能力强但容易过拟合,一般要配早停和较浅的树深度。数据量只有几百时,我不推荐一上来就调XGBoost的复杂参数,先用随机森林更稳。
多分类问题上一处容易翻车:有人把类别拆成多个一对多二分类器,再手动综合,结果复杂度和误差都变大。常见做法是用随机森林或多项Logistic回归直接输出多类概率,省去手工拼装。分类模型最终要在论文里给出混淆矩阵,别只贴一个Accuracy,混淆矩阵能暴露哪两类在特征空间里真正难分。
4. 优化模型:线性规划、灵敏度分析与启发式,最优解怎么做扎实
4.1 线性规划与整数规划:建模、求解器与可行域检查
优化类赛题的特征非常明显:在若干约束下,目标函数最大化或最小化。典型如物流派车、任务分配、生产排产。第一步永远是把自然语言翻译成决策变量、目标函数、约束条件,翻译错了后面求解器再强也是白搭。
我用Python的scipy.optimize.linprog给你一个最小可跑的案例。最大化3x + 5y,约束是x≤4,y≤6,x+y≤7,变量非负:
from scipy.optimize import linprog c = [-3, -5] # linprog默认求最小,最大化要取负 A = [[1, 0], [0, 1], [1, 1]] b = [4, 6, 7] bounds = [(0, None), (0, None)] result = linprog(c, A_ub=A, b_ub=b, bounds=bounds, method='highs') print(result)参数说明里最容易写反的是c的符号。注释里写清楚“默认求最小,所以最大化目标取负”能避免现场改半天。A_ub对应的是小于等于约束,如果题目给的是“至少不低于”,要左右同时乘-1转成小于等于格式,或者改用A_eq做等式约束。
当决策变量要求整数或0-1变量时,直接用linprog会有问题,常见做法是换成scipy.optimize.milp或python-mip库。把连续解四舍五入当整数解是经典翻车行为:四舍五入后很容易越出约束边界,表面看差别不大,实际解已经不可行。
建模时还有两个习惯:一是先画二维约束图看可行域是否为空,二是把变量少的版本跑通后再扩大到全量。两变量线性规划可以先手画约束线,直观判断凸域形状;抛开这个,代码里逐步注释约束也能看出哪个约束制造了空集。
4.2 灵敏度分析:目标函数系数与右端项变动后,最优解稳不稳
论文里只写一个最优解是不够的。评委通常关心的是:一旦市场价格系数波动,或者可用资源量变化,当前方案还是不是最优。这是灵敏度分析的典型应用。Lingo、SAS这类求解器的输出里会有一张松弛或灵敏度的表,记录目标函数系数的允许变化范围和约束右端项的允许变化范围。
敏感性比单纯最优解更有说服力。某个约束的影子价格大于0,说明它是当前方案下的紧约束,放宽这个约束,目标函数立刻改善;影子价格等于0,说明约束还有富余,这时候去增加资源没有收益。论文里不妨做成一张灵敏度表:约束名、当前右端项、允许增大区间、影子价格、结论。它能直接回答“某项资源增加多少就有边际收益”这类问题,比写一整页公式直观得多。
要注意灵敏度范围是局部的,不是所有范围内都能推。求解器给出的影子价格只在当前基不变的区间内有效,范围之外就要重新调模型。写论文时把这个前提带上一句话,评委就知道你是理解机理而不是单纯贴表。
4.3 启发式算法:大模型解不动时的退路与参数框
当变量上千、约束非线性,传统求解器长时间跑不出最优解,常见退路是启发式算法,比如遗传算法和粒子群优化。它们不保证最优,但能在可接受时间内给出可用解。
参数上我最关注的是:种群规模、迭代代数、交叉概率、变异概率。种群规模不是越大越好,40到100个个体、迭代50代通常够用;变异概率过高会让收敛曲线震荡,过低会让种群早早收敛到一个局部点。基础法则是先跑一次默认参数,看目标函数迭代曲线是否平滑下降,再逐步调变异概率和交叉概率,每次只改一个变量。
实际评估时,常见做法是把每代最优个体的目标值画成收敛曲线,再把各粒子的二维位置画成散点图;密密麻麻的点像星座图一样铺开,可以一眼判断种群是集中还是发散。启发式算法的结论要谨慎写成“本算法求得目标函数值为xxx”,不要写“全局最优解是xxx”。严谨一点还可以和线性规划的松弛解对比,说明偏差在百分之几以内,这样论文里的可信度更强。
5. 评价模型与四大模型避坑手册:AHP、熵权法、TOPSIS和翻车现场
5.1 层次分析法:成对比较矩阵与特征向量是核心
评价类赛题问的是:多个准则下,哪个方案最好。层次分析法是最常见的入门解法,把决策拆成目标层、准则层、方案层,再通过两两比较确定权重。
AHP的关键步骤就五步:列出准则;构造成对比较矩阵A,A_ij表示准则i比准则j重要多少,用1/9到9的标度;求A的最大特征值λmax和对应特征向量;把特征向量归一化得到权重;做一致性检验,CR小于0.1才接受。
一致性检验的计算式是CI = (λmax - n)/(n - 1),再算CR = CI / RI。RI的值按矩阵阶数查表:
| 阶数n | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| RI | 0 | 0 | 0.58 | 0.90 | 1.12 | 1.24 | 1.32 | 1.41 | 1.45 | 1.49 |
矩阵阶数超过4以后,手算特征向量很容易犯错。我一般直接用MATLAB的eig函数或者numpy求特征值和特征向量,再把最大特征值对应的向量归一化。矩阵阶数较低时手算近似值也只是为了展示推导思路,正式结果还是以程序为准。
5.2 熵权法与TOPSIS:用信息熵得到客观权重,再做理想解排序
层次分析法权重来自专家主观,赛题一旦注明“要求客观”,我就改用熵权法。熵权法的思想是:指标变异程度越大,信息熵越小,权重越大。比如评价几个投资方案,用收益率(%)、最大回撤、风险得分三个指标,收益率是正向指标,细节分配权重之前,负向指标要先反向处理。
熵权法步骤:
- 正向指标用x_ij / max_j归一化,负向指标用min_j / x_ij归一化。
- 计算比重p_ij = x_ij / Σx_ij。
- 计算信息熵e_j = -1/ln(n) × Σp_ij × ln(p_ij)。
- 计算权重w_j = (1 - e_j) / Σ(1 - e_j)。
Python里可以写成一个函数,方便直接套用:
import numpy as np def entropy_weight(X): # X: 行是样本,列是指标,已经完成正向/反向处理 n, m = X.shape p = X / X.sum(axis=0, keepdims=True) e = -1 / np.log(n) * np.sum(p * np.log(p + 1e-12), axis=0) w = (1 - e) / np.sum(1 - e) return wp * np.log(p)里有可能出现0乘ln(0)的情况,所以要加一个极小的1e-12做保护。权重得到以后,再用TOPSIS排序:把归一化矩阵乘权重向量得到加权矩阵,找正理想解和负理想解,计算每个方案到两端的欧氏距离,最终按贴近度排名。
5.3 四大模型赛前避坑清单:现象、原因与解决
把练习中反复遇到的翻车点整理成5条清单,每条按现象、原因、解决三步走。
翻车点1:层次分析法一致性检验一直不合格。现象是把两两比较矩阵改了三轮,CR值始终大于0.1。原因是指标太多,两两比值互相矛盾,矩阵天然很难满足一致性。解决方法是减少同一准则层指标数量到4个以下,单独调整矛盾最明显的单元格;如果还是不行,改为熵权法做客观权重。
翻车点2:K-means每次运行结果不同。现象是同一数据集、同一k值,两次跑出的簇中心变了。原因是初始质心随机选择。解决是固定随机种子,例如代码里写random_state=42,同时设置n_init=10;论文里也要写明种子值,保证他人可复现。
翻车点3:线性规划求解器报告无解,但理论上应该有解。现象是代码一模一样,改了一个约束的值,linprog直接返回无解。原因大概率是不等号方向抄错或者单位不一致,把可行域推成了空集。解决是先画两变量约束图观察可行域,再逐个约束看是哪一个引入后让问题不可行,把约束统一成标准形式再送求解器。
翻车点4:预测结果优秀得像中了彩票。现象是验证集上误差只有零点几个百分点。原因是归一化用了全样本统计量,或者时间序列切分时混入了未来数据,属于数据泄漏。解决是先切分再归一化,时间序列必须用前面时段做训练、后面时段做验证,预测值和真实值并列画图看是否偏移。
翻车点5:分类准确率很高但少数类全被牺牲。现象是准确率95%,少数类召回率只有30%。原因是类别不均衡,模型学到的几乎全是多数类特征。解决是用F1-score和混淆矩阵替代准确率做指标,或对少数类做过采样,或在0到1之间重搜分类阈值。
6. 把四大模型串进同一道赛题:题型判断与最后的模型包装
拿到题先别急着写代码,做一次快速题型判断。题干里出现“预测、预计、未来、趋势”,方向就是预测模型;出现“判别、识别、分类、聚类”,方向是分类模型;出现“最大收益、最小成本、最优排班”,方向是优化模型;出现“评价、评估、综合排名”,方向是评价模型。一道题经常不只一个类型,常见组合是先聚类做分群,再对每一群做优化,或者先预测再评价。方向判断错了,后面算法再复杂也救不回来。
我习惯把四类模型的对应关系做成一张决策卡:预测看数据量,数据少用GM(1,1),数据多用回归;分类先跑Logistic回归当基准,打不赢再上随机森林或SVM;优化先看约束类型,线性问题用linprog,整数问题用milp,规模太大才换启发式;评价题先确认客观还是主观,客观用熵权法,主观用AHP,两者结合就用AHP定准则层、熵权法定指标层。
模型包装也是得分点。正文里放三张表:模型概览表、验证指标表、参数设置表。模型概览表写模型名字、选型理由、输入特征、输出形式;验证指标表写每个模型在训练集和验证集上的R²、MAPE或F1;参数设置表写参数名、取值、调参方式。三张表一摆,建模逻辑就清楚了,不会让评委在一堆代码里找重点。
我自己的习惯是,所有预处理和模型入口固定随机种子,写进脚本开头;模型结果输出统一保留位数,避免同一张表里出现0.123456又出现0.12。还有一条血泪经验是,提交前最后一遍检查里,把预测值和真实值的散点图单独打出来看一遍,很多看似正常的模型在散点图上会暴露滞后或者系统性偏移。竞赛比的不是谁的算法名更炫,而是谁把决策逻辑讲圆了。希望帮到你。
本文还有配套的精品资源,点击获取