资讯动态

数学建模实验2:用Python完成数据拟合与模型检验避坑指南

发布时间:2026/10/14 2:29:46 来源:尧图企业网站定制
简介这是一份昆明理工大学数学建模实验2的线性规划实验报告PDF面向数学建模、运筹学初学者以及需要完成类似实验任务的高校学生。报告围绕广告投放优化场景展开要求在总广告费不超过800千元、电视广告费用不超过500千元等约束下通过MATLAB求解白天电视、最佳时间电视、无线电广播和杂志广告的最佳投放次数以最大化招徕顾客数。全文包含实验目的与环境、符号说明、问题分析、线性规划模型建立、目标函数与约束条件推导以及使用linprog函数的完整源程序、运行结果截图和最终最佳投放方案分析。资源为单个PDF文件大小仅158KB内容排版完整可直接作为课程作业、实验报告或期末复习的参考资料。目前已有350人学习下载适合需要快速掌握线性规划建模步骤和MATLAB求解方法的学习者。1. 一份数学建模实验2.pdf解开后是一整套建模练习如果你在某高校课程平台下过一份《数学建模实验2》PDF多半有过类似经历满怀期待地打开发现里面既没有可复制的完整代码也没有标准答案只有两三页问题描述、一张数据表外加几句请用所学方法求解并完成实验报告。这份文件看起来单薄实际是老师把完整建模流程装进了一次作业里从读题、定变量、选方法到写代码、检验、写报告每一步都被要求明确。它能帮你补的恰恰是课堂上学不到的那段从题目到交付的完整链路。适合正在修数学建模课的学生、刚进数模竞赛门的新手以及准备给学生设计实验题的助教。2. 从PDF到任务清单先把实验指导书拆成能执行的四步2.1 先看结构一份实验PDF里通常藏着哪四样东西拿到PDF别急着打开数据表。我花十分钟通读一遍通常会发现文档由四部分组成实验目的、问题背景与数据、实验要求、评分与提交规范。这四部分位置不固定评分标准常藏在最后一页数据可能在正文也可能在附录漏掉任何一块都可能导致返工。结构块常见位置要提取的信息容易漏的坑实验目的开头一至两段本实验训练哪个建模方法写报告时照抄不转成自己的表述问题背景与数据第2至3节数据含义、单位、来源数据可能有缺失单位混着给实验要求文档中后部用几种方法、是否需要画图明确要求对比时只做一种会扣分评分与提交规范末页或附录报告结构、代码是否附上只提交结果没提交过程可能被打回这四块里最容易被忽略的是评分与提交规范。很多同学把全部精力放在建模上最后发现报告要按固定模板写、代码要附完整可运行版本、图表要单独编号。我一般拿到PDF第一件事就是把评分标准复制到单独的笔记里当作写报告时的检查清单等全部做完再逐条核对提交物能省掉不少返工时间。2.2 把要求翻译成执行步骤从看懂题目到四步流水线通读之后我会把PDF要求翻译成一条四步流水线第一步定义问题把题目里的每句话拆成变量和约束第二步选方法根据数据类型决定用拟合、插值还是回归第三步写代码求解把模型表达式变成可运行脚本第四步检验与报告计算指标、画图、把结论写成人话。举个例子PDF给出的题目是某产品过去12个月的销量数据预测下三个月销量同时要求用拟合方法建模并检验。那么四步的产物分别是变量定义表列出月份序号t、月销量y、参数a与b方法选型说明先用散点图判断趋势走向再选线性或指数拟合脚本与图表包括拟合参数、预测值、拟合曲线图检验报告包括R²、残差图、参数置信区间以及对预测结果的业务解释。变量定义这一步我建议用表格写死后面写报告直接搬过去符号含义单位来源/说明t月份序号从0开始月数据表第1列t0对应起始月y月销量件数据表第2列a截距t0时预测销量件拟合参数b斜率每过一个月销量变化件/月拟合参数四步中最容易被跳过的其实是第一步变量定义。很多同学直接写代码到报告里解释参数含义时卡壳回头再补定义等于重做一遍。我把这份定义表放在所有工作的起点每次跑完一步回头看一眼确认没偏离题目。如果PDF是扫描版文字没法直接复制我一般先用一个小脚本把文本抽出来再读import pdfplumber # 从PDF中按页提取纯文本便于快速定位题目和数据 with pdfplumber.open(experiment2.pdf) as pdf: for i, page in enumerate(pdf.pages): text page.extract_text() if text: print(f--- Page {i1} ---) print(text)逻辑说明extract_text()对印刷体PDF效果很好扫描图片版需要先OCR这一步不做也不影响后续建模至少能帮你快速定位页码打印分页文本后再用上面说的四块结构去切分比直接盯着一页页截图效率高得多如果提取出的文本乱序多半是文档本身分栏排版可以按栏顺序手工拼接不需要重新下载其他工具。这一章的核心目标是开工之前先花二十分钟把PDF吃透把一份模糊的请建模求解变成一张有验收标准的任务清单。做完这一步后面所有操作都只是填空。3. 用最小二乘拟合打通实验2原理、代码和参数3.1 为什么实验2十有八九落在拟合—检验这条主线上从教学安排看实验2很少直接上微分方程或仿真模拟最常见的就是数据拟合加回归分析。原因有三第一它能把建模从抽象变成可操作散点图一画、模型曲线一配建模过程立刻可视化第二它天然衔接后续的优化和误差分析课程R²、残差、置信区间这些概念都会在后面反复用第三它容易产出可量化的结果老师好评分学生也好核对。这里必须澄清一个常见误区拟合不等于插值。插值要求曲线穿过每一个已知点拟合只要求曲线整体误差最小。实验2要的是拟合因为你关心的是数据背后的趋势不是逐点还原噪声。选拟合还有一个现实原因带噪声的数据做插值曲线会剧烈震荡拟合曲线的抗噪能力更强预测也稳定得多。维度插值拟合目标曲线精确穿过所有已知点曲线整体误差最小对噪声的态度很敏感容易过拟合对噪声有平滑效果适用场景需要精确还原每个数据点找趋势、做预测在实验2中的出现率偶尔用于样条插值主流做法所以拿到实验2的数据先画散点图看趋势是线性、指数还是带周期再决定用哪一族拟合函数。这一步别省后面所有代码都建立在这个判断上方法选错等于全盘重做。3.2 最小二乘拟合的Python实现最小脚本与三个必调参数下面是最小可运行的拟合脚本包含从读数据到输出参数的全过程。假设数据文件是data.csv两列列名分别是month和sales共12行。import pandas as pd import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit # 1. 读取CSV数据month为月份序号sales为销量 df pd.read_csv(data.csv, encodingutf-8-sig) t df[month].values.astype(float) y df[sales].values.astype(float) # 2. 定义线性模型 y a b * t def linear_model(t, a, b): return a b * t # 3. 拟合返回最优参数popt和协方差矩阵pcov popt, pcov curve_fit(linear_model, t, y, p0[1, 1]) # 4. 计算拟合值和残差 y_fit linear_model(t, *popt) residual y - y_fit # 5. 画散点图和拟合曲线 plt.scatter(t, y, label观测值, colorsteelblue) plt.plot(t, y_fit, label拟合曲线, colordarkorange, linewidth2) plt.xlabel(月份 t) plt.ylabel(销量 y) plt.legend() plt.grid(alpha0.3) plt.savefig(fit_result.png, dpi150) plt.show() # 6. 输出参数 print(拟合参数 a%.3f, b%.3f % (popt[0], popt[1]))逻辑说明curve_fit的四个核心输入是模型函数、自变量、因变量和初始猜测p0。模型函数必须能用*popt解包方式调用函数签名顺序和popt顺序要一致pcov是协方差矩阵后面算置信区间要用别丢残差要自己算curve_fit不直接返回残差列表而残差图又是报告必需品所以第4步不能省。三个必调参数p0初始参数猜测。线性模型不敏感但换成指数模型后p0设不好会收敛到局部最优甚至直接报错。常见做法是按数据范围估计初始值比如指数模型取p0[min(y), (y[-1]-y[0])/(t[-1]-t[0])]maxfev最大迭代次数。数据量大或者模型复杂时默认值可能不够设maxfev8000能减少拟合失败的玄学问题absolute_sigma设为True时把数据误差当成绝对误差处理适合已知测量误差的实验数据实验2一般不知道误差保持默认即可。模型要换时只需改模型函数和p0。比如数据呈现指数增长改成def exp_model(t, a, b, c): return a * np.exp(b * t) c popt, pcov curve_fit(exp_model, t, y, p0[y.min(), 0.1, 0], maxfev8000)参数说明指数模型的a控制起始幅值b控制增长速率c控制基线偏移。p0里的 0.1 是b的初始猜测如果数据增长特别快可以试 0.5指数拟合对p0敏感一个通用技巧是先用线性拟合对数据取对数把斜率作为b的初始值。预测下一个月很简单把 t13 代入模型t_next 13.0 y_pred linear_model(t_next, *popt) print(第13个月预测销量: %.2f % y_pred)做预测前要确认自变量t的定义如果数据里 month 是从 1 开始的序号那下次就是 13如果 month 存的是实际日期必须转成连续序号再预测否则模型不知道下个月在数值上是多少。3.3 R²、残差图与置信区间实验2的评分点其实在检验环节拟合跑通只是开始报告的重头在检验。实验2的评分标准通常明确要求给出模型检验我见过很多代码一步到位、报告里却只有一张图和一句拟合效果很好的作业结果都被打回。检验环节至少要做三件事。第一件算R²决定系数。公式是1减去残差平方和除以总平方和越接近1说明模型解释的数据变异越多但R²不是越高越好过拟合时R²也会虚高。from scipy import stats # R² ss_res np.sum(residual**2) ss_tot np.sum((y - np.mean(y))**2) r2 1 - ss_res / ss_tot print(R² %.4f % r2) # 残差图残差随拟合值的变化 plt.scatter(y_fit, residual, alpha0.6) plt.axhline(0, colorgray, linestyle--) plt.xlabel(拟合值) plt.ylabel(残差) plt.savefig(residual_plot.png, dpi150) plt.show()残差图怎么看理想状态是残差点在零线上下随机分布没有明显弯曲也没有从窄到宽的喇叭口。如果残差呈现弯曲说明模型结构不对比如数据其实是二次趋势却用了直线如果残差呈喇叭形说明方差不稳定可以考虑对 y 取对数。第三件算参数的置信区间。这里用pcov和自由度修正的标准误给出 a 和 b 的95%置信区间能说明参数估计稳不稳# 参数标准误与95%置信区间 n, p len(t), 2 sigma2 np.sum(residual**2) / (n - p) se np.sqrt(np.diag(pcov) * sigma2) alpha 0.05 t_value stats.t.ppf(1 - alpha / 2, dfn - p) for i, name in enumerate([a, b]): ci_low popt[i] - t_value * se[i] ci_high popt[i] t_value * se[i] print(f{name}: {popt[i]:.3f} ± {t_value * se[i]:.3f}, CI[{ci_low:.3f}, {ci_high:.3f}])逻辑说明这里用残差方差sigma2除以自由度 n-p再乘pcov的对角线得到参数标准误se是教材里的标准做法如果置信区间跨过 0说明该参数在统计上不显著或许应该从模型中去掉这一项把这三样东西写进报告检验环节才算完整。很多比赛的优秀论文检验部分的篇幅比建模部分还长原因就在这里。4. 避坑数据拟合实验的5个典型翻车现场4.1 数据没排序拟合曲线像一团乱麻现象用 Pandas 读入 CSV 后直接画图散点图在横轴方向来回跳拟合曲线扭成麻花R² 甚至出现负值。原因数据文件的行顺序不是按自变量排好的。画图时plot是按行号顺序连线的数据乱序就会画出折返线而拟合本身按点计算不依赖顺序问题出在可视化不是模型错了。解决画曲线前先按自变量排序。df df.sort_values(month)再取数组拟合可以不排序但画图必须保证 x 单调递增否则曲线一团乱。这类问题在 Excel 导入的数据里特别常见我处理时习惯先print(df.head())确认 month 列是不是单调递增省得画完图才发现。4.2 贪图高次多项式结果过拟合现象用 8 次多项式把 12 个点的数据拟到 R²0.999报告很好看但预测下一个点时数值直接飞了。原因高次多项式自由度足够大可以穿过每个噪声点拟合的是噪声而不是趋势R² 在过拟合场景里完全失真。解决把数据分成训练集和测试集用测试集表现判断模型好坏。多项式次数超过 3 就要警惕或者直接看残差图——残差不再随机而是一段段弯曲就是过拟合信号。判断是否过拟合还有个快速办法如果测试集 RMSE 比训练集差一大截说明模型把训练集里的噪声也学进去了。4.3 把日期直接喂给模型现象数据里月份是 2023-01 这种字符串astype(float)直接报错有人手动转成 1、2、3 后模型能跑但解释参数时说不清每过一个月到底从哪天算起。原因日期不是连续数值变量字符串更没法参与计算。即便转成序号也需要明确基线否则回归系数的含义悬空答辩时容易被问住。解决把日期统一转成连续的时间索引比如从起始月份开始编号 0、1、2…并在报告里写清t0 对应 2023 年 1 月或者用pd.to_datetime处理成真正的 datetime再按月份差值计算序号。核心是让模型表达式里每个变量的定义都无歧义。统一化之后记得检查数据里有没有缺失月份缺月会导致序号错位预测全偏。4.4 只贴R²不画残差图报告被打回现象报告里只有一个 R²0.94配一张拟合曲线图老师反馈检验不充分补充残差分析后提交。原因评分标准里明确写了给出模型检验过程。R² 是整体指标残差图是局部诊断两者互补只写一个等于检验只做了一半。解决把 3.3 的残差图代码跑出来并在报告里补一句判断结论残差在零线附近随机分布无明显弯曲和漏斗形说明线性模型假设基本合理。这句话虽然短却是评分时区分跑完了和想明白了的关键。残差图这步没有捷径画出来几秒钟但能提前发现模型选错。4.5 报告只有代码没有假设看起来像调包侠现象代码能跑图也贴了但整份报告找不到变量定义和模型假设答辩被问为什么选线性模型直接卡住。原因数学建模报告评分看的是建模过程代码只是过程的一部分。没写假设等于没交代清楚模型成立的前提条件老师无从判断你是理解了还是只会调包。解决报告固定写五段问题重述、变量定义、模型建立含假设、求解与检验、结论。变量定义用表格列符号、含义、单位、来源模型假设写三条足够比如数据无系统性采集偏差销量变化短期连续忽略节假日等特殊扰动。写假设不是凑字数每条假设后面跟一句如果这个假设不成立模型会怎样比如数据有系统偏差会导致参数估计有偏这才是建模者的思考。5. 把实验2从能交做到能打比赛交叉验证与模型对比5.1 用交叉验证替代单次划分报告里多一张有说服力的图实验2多数人习惯全量数据拟合完算 R² 交差。这个做法在竞赛里会被挑战因为拟合和评价用的是同一批数据属于拿答案考自己。常见改进是留出最后几个点做预测检验但小样本下留出法波动大折数选得不同结论可能完全不同。我一般建议用 K 折交叉验证代码量很小from sklearn.model_selection import KFold, cross_val_score from sklearn.linear_model import LinearRegression X t.reshape(-1, 1) # 自变量需要二维数组 kf KFold(n_splits5, shuffleTrue, random_state42) scores cross_val_score(LinearRegression(), X, y, cvkf, scoringr2) print(五折R²: %.3f ± %.3f % (scores.mean(), scores.std()))参数说明shuffleTrue在分折前打乱数据避免时间顺序造成前后期偏移但如果你是严格的时间序列预测任务应该用TimeSeriesSplit按顺序划分实验2里做交叉验证用随机划分即可random_state42固定划分方式保证结果可复现报告里必须写不然别人复现不出你的数值会以为你编数据scores.std()大于 0.2 说明模型对数据划分很敏感也就是模型不稳定这时候要回头检查特征或数据量而不是硬调参数。加了这段指标报告里就能写五折交叉验证 R² 均值为 0.87±0.06模型在不同数据子集上表现稳定未出现明显过拟合。这句话比单独贴一个 R² 有说服力得多。5.2 做一次模型对比把报告从完成作业提到可参赛水平实验2通常只要求做一个模型但主动加一个对比模型会让报告质量上一个台阶。常见组合是线性、指数、二次多项式三选二用统一指标比较。看 RMSE 直观看 AIC 能惩罚参数数量防止无脑加项。模型适用数据形状参数个数实验2常见坑线性均匀上升或下降2有弯曲趋势时强行用线性指数近似等比增长2或3初始值设不好不收敛二次多项式有单峰或单谷3次数再高就过拟合from sklearn.metrics import mean_squared_error def rmse(y_true, y_pred): return np.sqrt(mean_squared_error(y_true, y_pred)) def aic(n, rss, k): return n * np.log(rss / n) 2 * k # 假设三个模型的预测值已存在y_fit_linear, y_fit_exp, y_fit_quad models { 线性: (y_fit_linear, 2), 指数: (y_fit_exp, 2), 二次: (y_fit_quad, 3), } for name, (y_pred, k) in models.items(): rss np.sum((y - y_pred) ** 2) print(f{name}: RMSE{rmse(y, y_pred):.3f}, AIC{aic(len(y), rss, k):.2f})前提是三个模型必须用同一份数据拟合预测值要按 t 排序对齐。把对比结果放进报告并写一句结论比如AIC 最小的是指数模型说明加入增长趋势后模型复杂度合理且比线性模型多解释 X% 的方差选型就有了依据。多数实验2的评分表里都有一项方法选择是否合理这半页内容就是专门送给这项分数的。我自己带学生做这类实验时最常见的情况是代码跑通就以为完事直到答辩被问你的模型假设是什么才发现整份报告最值钱的部分没写。后来我习惯把评分标准倒过来当检查清单先满足检验要求、再补代码、再补叙述每轮返工时间都短不少。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑