
1. 从零到一为什么数学建模绕不开MATLAB如果你刚接触数学建模看到队友或学长学姐电脑上那些花花绿绿的曲线和密密麻麻的代码心里可能既好奇又发怵。你可能会想我数学基础一般编程更是零经验这个叫MATLAB的软件看起来这么复杂我真的能学会吗答案是肯定的而且你可能比想象中更快上手。数学建模的核心是把一个现实问题用数学的语言描述出来再通过计算得到答案或预测。这个过程里MATLAB扮演的角色就像一个“超级计算器”和“万能画板”的结合体。它最大的优势就是让数学表达和计算变得直观。你不用像学C语言那样先花大量时间理解指针、内存管理也不用像学Python做科学计算需要额外配置NumPy、SciPy、Matplotlib等一系列库。MATLAB从设计之初就是为矩阵运算和科学可视化服务的它的语法非常贴近我们手写的数学公式。举个例子你要解一个线性方程组 Ax b。在MATLAB里你几乎可以照搬数学写法x A \ b。一个反斜杠就搞定了背后是它封装好的、经过高度优化的数值计算库。再比如画图你想看一个函数 y sin(x) 在0到2π之间的图像只需要两行代码x 0:0.01:2*pi; plot(x, sin(x))。这种直观性对于需要快速验证想法、迭代模型的建模过程来说是无可替代的效率工具。我见过很多队伍在三天三夜的比赛里用Python可能还在调试环境、处理库版本冲突而用MATLAB的队伍已经跑出第一版结果开始分析问题了。这并不是说MATLAB比Python更好而是在数学建模这个“短平快”、强调结果导向的特定场景下MATLAB的集成化、开箱即用特性让它成为了无数新手队伍的首选敲门砖甚至是很多资深教练推荐的第一工具。2. 极速搭建你的第一个MATLAB工作环境工欲善其事必先利其器。对于新手最怕的就是在安装环节卡住热情被消磨殆尽。MATLAB的安装其实比很多大型软件要友好。首先你需要获取软件。对于在校学生最推荐的途径是通过学校的正版软件中心。绝大多数开设理工科专业的高校都购买了校园授权你可以用学号登录下载获得完全正版、功能齐全的软件这是最稳妥、最合法的方式。如果学校没有提供MathWorks官网也提供为期30天的全功能试用版足够你完成一次完整的入门学习甚至准备一次比赛。安装过程基本是“下一步”到底但有三个关键点需要注意这能帮你避开后续90%的奇怪问题。第一安装路径请务必使用全英文。不要包含任何中文或特殊字符比如“D:\软件\MATLAB”就是绝对的禁忌。一个推荐的路径是“D:\MATLAB\R2024a”这样的格式。这是因为MATLAB的底层和一些工具箱对路径中的非ASCII字符支持不佳可能导致函数无法调用、工具箱加载失败等玄学问题。第二关于工具箱的选择。安装程序会让你勾选需要安装的工具箱Toolboxes。对于数学建模入门你不需要全部安装那会占用大量磁盘空间动辄几十GB。我建议的核心必选清单是MATLAB本体必选。Simulink虽然你可能暂时用不到它做动态系统仿真但一些高级的优化、控制系统工具箱依赖于它勾选上以防万一。Optimization Toolbox优化工具箱。数学建模的半数问题最终都归结为优化问题求最大、最小、最优解这是使用频率最高的工具箱之一。Statistics and Machine Learning Toolbox统计与机器学习工具箱。处理数据、做回归分析、假设检验比如热词中提到的t检验ttest/ttest2全靠它。Curve Fitting Toolbox曲线拟合工具箱。当你有一堆数据点想找一个函数来近似描述时这个工具箱的图形化界面和函数能极大提升效率。Symbolic Math Toolbox符号数学工具箱。可以进行公式推导、求导、积分等符号运算虽然比赛中直接使用不多但在学习阶段验证理论公式非常有用。其他如图像处理、信号处理等工具箱可以根据你可能的建模方向比如赛题涉及图像分析再决定是否安装。初次安装按以上清单来已经能覆盖数学建模竞赛80%以上的需求。第三安装后的第一件事——设置工作路径。安装完成后打开MATLAB你会看到一个包含“命令行窗口”、“工作区”、“当前文件夹”等面板的界面。请立刻在“当前文件夹”工具栏里点击“浏览文件夹”图标选择一个你计划存放所有代码和数据的文件夹比如“D:\MyMatlabProjects”。然后右键点击这个文件夹选择“添加到路径” - “选定文件夹”。这个操作的意义在于以后你在这个文件夹及其子文件夹下写的所有脚本和函数MATLAB都能直接找到并运行避免出现“未定义函数或变量”的错误。这是很多新手会忽略但至关重要的第一步。3. MATLAB编程思维像搭积木一样构建你的模型很多编程教程一上来就讲变量、循环、条件判断这固然正确但容易让人迷失在语法细节里。对于数学建模我们换一种思路把MATLAB当作一个可以交互式执行数学命令的超强环境。你的核心任务是学会如何把数学问题“翻译”成MATLAB能理解的指令。3.1 一切皆矩阵理解MATLAB的底层逻辑这是MATLAB最核心的思想也是它速度的源泉。在MATLAB中最基本的数据单位是数组Array而一维数组是向量二维数组就是矩阵。甚至一个单独的数字在MATLAB看来也是一个1x1的矩阵。这意味着很多操作我们都可以用对整个矩阵的运算来完成而不是写循环。这种思想叫“向量化编程”它能极大提升代码的简洁性和运行效率。比如你要计算一个向量中每个元素的平方。新手可能会写循环x [1, 2, 3, 4, 5]; result zeros(size(x)); % 先创建一个和x一样大的空向量 for i 1:length(x) result(i) x(i)^2; end而向量化的写法是x [1, 2, 3, 4, 5]; result x.^2; % 注意这里有个点 .^一行搞定。这里的点运算符.代表“按元素操作”。x.^2就是对x中的每个元素单独做平方运算。同理.*是元素乘./是元素除。当你需要对两个同型矩阵进行对应位置的运算时就必须使用点运算符。而直接的*在MATLAB中代表矩阵乘法遵循线性代数规则。混淆*和.*是新手最常犯的错误之一。3.2 数据读入与初步探索你的模型燃料模型跑不起来一半的问题出在数据上。数学建模竞赛的数据通常以Excel.xlsx, .xls或文本文件.txt, .csv的形式提供。MATLAB读取它们非常简单。对于Excel文件使用readtable函数是现在更推荐的方式因为它会把数据读成一个“表”table类型的变量能保留列名处理混合类型数据数值和文本非常方便。data readtable(你的数据文件.xlsx); % 读取整个工作表 % 或者指定工作表 data readtable(你的数据文件.xlsx, Sheet, Sheet1); % 查看前几行 head(data) % 查看数据摘要每列的统计信息、类型 summary(data) % 提取某一列数据假设列名为‘Temperature’ temp data.Temperature; % 点号索引非常直观 % 或者 temp data(:, Temperature); % 单元格索引对于CSV或TXT文件readmatrix纯数值数据或readtable含文本头是首选。% 假设CSV文件第一行是列名 data_table readtable(data.csv); % 假设TXT文件全是数字以空格或逗号分隔 data_matrix readmatrix(data.txt);读入数据后不要急着建模。先用plot、scatter画几个散点图看看分布用histogram看看数据分布用mean、std、min、max计算基本统计量。这个探索过程Exploratory Data Analysis, EDA能帮你发现异常值、数据特点甚至直接启发你选择什么样的模型。比如你发现两个变量在散点图上呈明显的线性关系那么线性回归模型可能就是你的首选。3.3 函数与脚本组织你的代码当你的操作超过三五行就应该考虑组织代码了。MATLAB有两种主要的文件脚本.m文件和函数也是.m文件。脚本像是一个记事本里面按顺序写下一系列命令。当你运行脚本时效果等同于在命令行窗口逐行输入这些命令。脚本中的变量会留在工作区Workspace中。它适合用于一次性的数据分析流程或测试。函数是封装好的、可重复使用的功能模块。它有自己的输入参数、内部变量不污染工作区和输出结果。定义函数以function关键字开头。函数文件的名字最好与函数名一致。例如我们创建一个计算一元二次方程根的函数保存为solve_quadratic.mfunction [x1, x2] solve_quadratic(a, b, c) % SOLVE_QUADRATIC 求解一元二次方程 a*x^2 b*x c 0 % 输入 % a, b, c: 二次项、一次项、常数项系数 % 输出 % x1, x2: 方程的两个根可能是复数 % % 示例 % [r1, r2] solve_quadratic(1, -3, 2); % 解 x^2 - 3x 2 0 delta b^2 - 4*a*c; % 计算判别式 x1 (-b sqrt(delta)) / (2*a); x2 (-b - sqrt(delta)) / (2*a); end在另一个脚本或命令行中你就可以直接调用它[root1, root2] solve_quadratic(1, -5, 6);。养成写函数的习惯尤其是注释以%开头不仅能让你的代码清晰在团队协作时更是至关重要。MATLAB编辑器还支持在函数定义行下按CtrlD快速跳转到函数文件非常方便。4. 数学建模核心工具箱实战从问题到求解掌握了基础操作我们就可以直面数学建模的核心了。比赛题目千变万化但用到的MATLAB工具和思路有很强的规律性。下面我们围绕几个最常见的建模任务拆解具体怎么做。4.1 拟合与回归寻找数据背后的规律这是数学建模中最基础、最常用的技术之一。题目常给出一些观测数据让你找出变量之间的关系并进行预测。MATLAB的曲线拟合工具箱Curve Fitting Toolbox和统计工具箱让这一切变得可视化且简单。场景假设你有一组时间和温度的数据想找出温度随时间变化的趋势。数据准备time [0, 1, 2, 3, 4, 5]; temperature [15.2, 16.1, 17.5, 18.8, 20.1, 21.0];使用拟合工具在命令行输入cftool会打开一个图形化的曲线拟合器。选择数据在工具界面分别将time选为X datatemperature选为Y data。选择模型工具提供了大量预设模型如多项式Polynomial、指数Exponential、傅里叶级数Fourier等。你可以先选一个“Linear”线性拟合看看效果。工具会实时画出拟合曲线并给出拟合方程如f(x) p1*x p2和衡量拟合好坏的指标如R-squareR²越接近1越好、RMSE均方根误差越小越好。比较与选择你可以尝试不同的模型比如二次多项式对比它们的R²和残差图Residuals plot。残差图应该随机分布在0线附近如果呈现明显的规律如抛物线形说明模型选择不当。生成代码这是最关键的一步当你找到满意的模型后点击菜单栏的“文件”-“生成代码”MATLAB会自动生成一个包含所有拟合参数和模型的函数文件。你可以把这个函数直接用到你的主程序里进行预测比如predicted_temp myfit(time_new);。这避免了手动输入参数的麻烦和错误。对于更复杂的多元线性回归多个自变量你可以直接用统计工具箱的fitlm函数% 假设有一个table数据‘mydata’包含因变量Y自变量X1, X2 mdl fitlm(mydata, Y ~ X1 X2); % 拟合线性模型 Y b0 b1*X1 b2*X2 disp(mdl); % 查看详细的模型摘要包括系数估计、p值、R²等 plotResiduals(mdl); % 绘制残差分析图检查模型假设fitlm的输出非常专业包含了假设检验的结果如每个系数的p值能告诉你哪个自变量对因变量的影响是显著的。4.2 优化问题求解在约束下寻找最佳方案“最优解”是数学建模永恒的主题。无论是安排生产计划使利润最大还是设计路径使距离最短都属于优化问题。MATLAB的优化工具箱Optimization Toolbox是解决这类问题的利器。优化问题通常包含三个要素决策变量、目标函数要最大化或最小化的东西、约束条件。我们以一个简单的线性规划为例假设一家工厂生产两种产品A和B生产每个A产品利润3元耗电2度每个B产品利润4元耗电3度。工厂每天总电量限制为100度。问每天生产多少A和B能使总利润最大定义问题决策变量设生产A产品x1件B产品x2件。目标函数最大化利润P 3*x1 4*x2。在MATLAB中我们通常处理最小化问题所以将其转化为最小化-P -3*x1 -4*x2。约束条件电量约束2*x1 3*x2 100非负约束x1 0,x2 0使用linprog求解linprog是求解线性规划的核心函数。f [-3; -4]; % 目标函数系数向量因为要求最小化 -利润 A [2, 3]; % 不等式约束系数矩阵电量约束 b [100]; % 不等式约束右侧向量 Aeq []; % 等式约束系数矩阵本例无 beq []; % 等式约束右侧向量 lb [0; 0]; % 决策变量的下界 ub []; % 决策变量的上界本例无即正无穷 [x, fval, exitflag] linprog(f, A, b, Aeq, beq, lb, ub);解读结果x是最优解向量即x1和x2的值。fval是目标函数在最优解处的值。因为我们输入的是-P所以实际最大利润是-fval。exitflag是求解器退出标志。exitflag 0表示成功找到最优解exitflag 0表示达到最大迭代次数exitflag 0表示问题无解或求解失败。务必检查这个标志很多新手拿到结果就直接用不检查exitflag如果求解失败结果将是毫无意义的。对于非线性优化问题常用的函数是fmincon有约束和fminunc/fminsearch无约束。它们的调用方式比linprog复杂需要你提供一个计算目标函数值的函数句柄。例如用fminsearch寻找函数f(x) (x-3)^2 5的最小值点这是一个无约束优化显然最小值在x3处fun (x) (x-3).^2 5; % 定义目标函数使用匿名函数 x0 0; % 提供一个初始猜测点 [x_opt, fval] fminsearch(fun, x0);优化求解器的性能和结果严重依赖于初始值x0的选取。对于复杂问题可能需要尝试多个不同的初始点或者使用全局优化算法如GlobalSearch。4.3 统计分析与假设检验用数据说话当你的模型涉及到比较两组数据是否有显著差异、或者检验某个假设是否成立时就需要用到统计推断。热词中提到的ttest和ttest2就是典型的工具。ttest单样本t检验用于检验一组数据的均值是否等于某个给定的理论值。场景你改进了一种生产工艺测得10个新产品的重量克为[100.1, 99.8, 100.2, 100.0, 99.9, 100.3, 99.7, 100.1, 100.0, 99.8]。旧工艺的理论标准重量是100克。问新工艺生产的零件平均重量是否仍然是100克双侧检验data [100.1, 99.8, 100.2, 100.0, 99.9, 100.3, 99.7, 100.1, 100.0, 99.8]; [h, p, ci, stats] ttest(data, 100); % 检验均值是否为100 % h0 表示在默认显著性水平0.05下接受原假设均值等于100 % p值p-value是观测到当前数据或更极端数据的概率。p 0.05通常认为不显著。 % ci 是均值的95%置信区间。ttest2双样本t检验用于检验两组独立数据的均值是否相等。场景你有两种教学方法A和B分别对两组学生进行测试得到成绩。问两种教学方法的效果平均成绩是否有显著差异groupA [78, 85, 92, 88, 76]; groupB [82, 90, 95, 85, 88, 91]; [h, p, ci, stats] ttest2(groupA, groupB); % h1 表示拒绝原假设两组均值相等认为有显著差异。 % 注意ttest2默认假设两组数据的方差相等。如果方差不齐应使用 Vartype, unequal 参数。 [h2, p2] ttest2(groupA, groupB, Vartype, unequal);关键区别ttest检验一组数据与一个固定值ttest2比较两组独立数据的均值。选择哪一个完全取决于你的研究问题和数据结构。除了t检验统计工具箱还提供了方差分析anova1、非参数检验如ranksum、相关性分析corrcoef等一系列函数。在做任何检验前最好先通过画图如箱线图boxplot直观感受一下数据分布检查是否有异常值。5. 可视化与论文图表制作让你的结果自己“说话”一份优秀的数学建模论文必然包含清晰、美观、专业的图表。MATLAB的绘图功能极其强大远超一般人的认知。它不仅能画简单的折线散点图还能制作出版级质量的复杂图表。5.1 基础绘图与精细化调整最基本的plot函数已经很强大了但默认的图形往往达不到论文要求。你需要学会定制几乎所有的图形属性。x linspace(0, 10, 100); y1 sin(x); y2 cos(x); figure(Position, [100, 100, 800, 600]); % 设置图形窗口位置和大小[左 下 宽 高] plot(x, y1, b-o, LineWidth, 2, MarkerSize, 8, MarkerFaceColor, b); % 蓝色实线圆圈标记线宽2标记大小8标记填充蓝色 hold on; % 保持当前图形以便在同一坐标系绘制下一条线 plot(x, y2, r--s, LineWidth, 1.5, MarkerSize, 6, MarkerFaceColor, r); % 红色虚线方块标记 xlabel(时间 (秒), FontSize, 12, FontWeight, bold); ylabel(振幅, FontSize, 12, FontWeight, bold); title(正弦与余弦函数对比, FontSize, 14); legend(sin(x), cos(x), Location, best); % 图例自动选择最佳位置 grid on; % 显示网格 set(gca, FontSize, 11); % 设置当前坐标轴字体大小hold on这是多曲线绘制的关键命令。不加它的话第二次plot会清空之前的图形。线型、标记和颜色可以通过一个字符串指定如b-o表示蓝色(b)实线(-)带圆圈(o)标记。r--s表示红色(r)虚线(--)带方块(s)标记。这是MATLAB绘图的一个快捷语法。set(gca, ...)gca代表“获取当前坐标轴句柄”通过set函数可以修改坐标轴的几乎所有属性这是精细化调整的终极武器。5.2 多子图与专业图表使用subplot函数可以在一个窗口内创建多个坐标系便于对比。figure; subplot(2, 2, 1); % 创建一个2行2列的布局并激活第1个位置 plot(x, y1); title(子图1); subplot(2, 2, 2); scatter(rand(50,1), rand(50,1)); title(子图2散点图); subplot(2, 2, 3); histogram(randn(1000,1), 30); title(子图3直方图); subplot(2, 2, 4); bar([10, 15, 7, 20]); title(子图4柱状图);对于三维数据surf曲面图、mesh网格图、contour等高线图能提供更直观的视角。例如可视化一个二元函数z x.*exp(-x.^2 - y.^2)[X, Y] meshgrid(-2:0.1:2, -2:0.1:2); % 生成网格点 Z X .* exp(-X.^2 - Y.^2); figure; surf(X, Y, Z); xlabel(X); ylabel(Y); zlabel(Z); title(三维曲面图); shading interp; % 平滑着色 colorbar; % 显示颜色条5.3 导出高质量图片用于论文这是最后一步也至关重要。MATLAB默认保存的图片分辨率往往不够。不要用截图使用print或exportgraphics函数。% 方法1使用 print 函数通用可调分辨率 print(-dpng, -r600, my_figure.png); % 保存为600 DPI的PNG % -dpdf 保存为PDF -depsc 保存为EPS期刊常用矢量格式 % 方法2使用 exportgraphics 函数R2020a以后推荐更简单 exportgraphics(gcf, my_figure_highres.png, Resolution, 600); % gcf: 获取当前图形句柄 % 还可以指定背景色比如保存为透明背景的PNG用于PPT exportgraphics(gcf, my_figure_transparent.png, Resolution, 600, BackgroundColor, none);对于论文推荐使用PDF或EPS矢量格式这样无论放大多少倍都不会失真。如果期刊要求位图则确保分辨率至少为300 DPI600 DPI更佳。6. 避坑指南与效率提升前人踩过的坑你绕过去在实战中你会遇到各种报错和意外情况。这里总结几个最常见的新手坑和提升效率的技巧。6.1 常见错误与调试“未定义函数或变量”原因最常见。要么拼写错误要么文件不在MATLAB的搜索路径中。解决检查拼写。使用which 函数名命令查看MATLAB是否能找到该函数。确保你的脚本或函数所在的文件夹已“添加到路径”见第2部分。“索引超出矩阵维度”原因试图访问一个矩阵中不存在的行或列。比如矩阵A是3x3的你却执行A(4,1)或A(1,4)。解决在访问前用size(A)命令查看矩阵的维度。在循环中确保循环变量i、j的范围不超过size(A,1)和size(A,2)。矩阵维度不匹配原因进行矩阵运算如加减、乘除时两个矩阵的维度不满足运算规则。比如A(3x2)和B(2x4)可以相乘得到C(3x4)但A(3x2)和B(3x2)直接使用*矩阵乘就会报错。解决分清*矩阵乘和.*元素乘。如果要做元素乘确保两个矩阵维度完全相同并使用点运算符。脚本与函数变量冲突现象在脚本中调用函数后发现脚本里的某个变量值被意外改变了。原因函数内部使用了与脚本中同名的变量且未妥善处理。函数内部变量本应是局部的但如果你在函数内使用了clear等命令可能会影响到基础工作区。解决在函数开头使用nargin,nargout检查输入输出避免在函数内使用clear all这会把工作区的变量也清空为函数内部的临时变量起独特的名字。调试利器设置断点在编辑器行号旁边点击出现红点。运行程序时会在断点处暂停你可以查看此时所有变量的值。步进暂停后使用工具栏的“步进”Step按钮一行一行执行代码观察变量变化。命令行调试在程序暂停时你可以在命令行窗口直接输入变量名查看其值甚至修改变量值进行测试。6.2 提升代码效率与可读性向量化向量化再向量化如前所述用矩阵运算代替循环是提升MATLAB代码速度最有效的方法。对于多层嵌套循环效率提升可能是几百甚至上千倍。预分配数组空间如果你必须使用循环并且会不断向一个数组添加元素务必先预分配好空间。% 糟糕的做法数组动态增长每次循环MATLAB都要寻找新的连续内存 result []; for i 1:10000 result [result, someCalculation(i)]; % 非常慢 end % 好的做法预分配 result zeros(1, 10000); % 先创建一个10000个元素的零向量 for i 1:10000 result(i) someCalculation(i); % 直接赋值速度快得多 end使用tic和toc计时在怀疑某段代码效率低下时用tic和toc包裹起来可以精确测量其运行时间。tic; % 你的代码段 elapsedTime toc; fprintf(这段代码运行了 %.4f 秒。\n, elapsedTime);写好注释和文档在函数开头用注释块%清晰地说明函数功能、输入、输出和示例。这不仅帮助队友几天后你自己回头看也能快速理解。MATLAB的help命令会显示这些注释非常方便。7. 从入门到参赛一个完整的建模流程演练让我们用一个简化的、虚构的赛题片段把前面所有的知识点串起来走一遍从拿到问题到输出结果的完整流程。题目背景某城市共享单车运营公司希望预测未来一周内不同区域在每天不同时段的单车需求量以便进行调度。提供了过去一个月内核心商圈A区每小时的单车借还数据包含时间戳、借车量、还车量、天气情况分类、温度、湿度等。我们的任务建立一个预测模型预测未来一周A区每小时的借车量。步骤一问题分析与数据导入明确目标预测“借车量”这是一个回归问题预测连续值。确定可能的特征自变量时间因素小时、星期几、是否节假日、天气因素天气类型、温度、湿度、历史因素前几小时的借车量。使用readtable导入提供的Excel数据文件bike_data.xlsx并查看数据概况。data readtable(bike_data.xlsx); head(data); summary(data); % 检查缺失值 missing_sum sum(ismissing(data)); disp(各列缺失值数量); disp(missing_sum); % 如果有缺失值考虑删除或填充如用前后均值填充 data fillmissing(data, movmean, 3); % 用移动平均填充窗口为3步骤二数据探索与预处理可视化探索figure; subplot(2,2,1); plot(data.Timestamp, data.BorrowCount); % 借车量随时间变化趋势 xlabel(时间); ylabel(借车量); title(借车量趋势); subplot(2,2,2); scatter(data.Temperature, data.BorrowCount); % 借车量与温度关系 xlabel(温度); ylabel(借车量); title(借车量 vs 温度); subplot(2,2,3); boxplot(data.BorrowCount, hour(data.Timestamp)); % 按小时查看借车量分布 xlabel(小时); ylabel(借车量); title(不同小时借车量箱线图); subplot(2,2,4); histogram(data.BorrowCount, 50); % 借车量分布直方图 xlabel(借车量); ylabel(频次); title(借车量分布);从这些图中我们可能发现借车量有明显的日周期早晚高峰和周周期工作日/周末不同与温度可能呈非线性关系太冷太热都骑得少。特征工程从原始时间戳中提取更有用的特征。data.Hour hour(data.Timestamp); % 提取小时 data.Weekday weekday(data.Timestamp); % 提取星期几1周日7周六 data.IsWeekend ismember(data.Weekday, [1, 7]); % 是否为周末 data.IsHoliday ...; % 假设有一个函数或列表判断是否为节假日 % 对分类变量‘Weather’进行独热编码One-Hot Encoding weather_dummy dummyvar(categorical(data.Weather)); % 生成虚拟变量矩阵 % 将虚拟变量合并回原表需要处理列名此处简化 % 考虑加入滞后特征如前一小时的借车量 data.BorrowCount_Lag1 [NaN; data.BorrowCount(1:end-1)]; % 滞后一期 % 删除包含NaN的行因为第一行滞后特征为NaN data rmmissing(data);步骤三模型选择、训练与评估划分数据集将最后一周的数据作为测试集之前的数据作为训练集。train_data data(data.Timestamp datetime(2023-10-24), :); test_data data(data.Timestamp datetime(2023-10-24), :); % 准备特征矩阵X和响应变量y features {Hour, Weekday, IsWeekend, Temperature, Humidity, BorrowCount_Lag1}; % 以及天气的虚拟变量列 X_train train_data{:, features}; y_train train_data.BorrowCount; X_test test_data{:, features}; y_test test_data.BorrowCount;尝试不同模型线性回归作为基线模型。mdl_linear fitlm(X_train, y_train); y_pred_linear predict(mdl_linear, X_test);回归树/集成方法可能能更好地捕捉非线性关系。% 使用回归树 mdl_tree fitrtree(X_train, y_train); y_pred_tree predict(mdl_tree, X_test); % 使用随机森林集成多棵树通常更稳健 mdl_rf TreeBagger(50, X_train, y_train, Method, regression); % 50棵树 y_pred_rf predict(mdl_rf, X_test); y_pred_rf cell2mat(y_pred_rf); % 预测结果是cell数组需转换模型评估在测试集上比较预测效果。% 计算均方根误差 RMSE rmse_linear sqrt(mean((y_test - y_pred_linear).^2)); rmse_tree sqrt(mean((y_test - y_pred_tree).^2)); rmse_rf sqrt(mean((y_test - y_pred_rf).^2)); fprintf(线性回归RMSE: %.2f\n, rmse_linear); fprintf(回归树RMSE: %.2f\n, rmse_tree); fprintf(随机森林RMSE: %.2f\n, rmse_rf); % 可视化预测 vs 真实值 figure; plot(y_test, b-, LineWidth, 2, DisplayName, 真实值); hold on; plot(y_pred_rf, r--, LineWidth, 1.5, DisplayName, 随机森林预测); xlabel(时间点测试集); ylabel(借车量); title(模型预测效果对比); legend(show); grid on;选择RMSE最小的模型作为最终模型。通常随机森林这类集成模型在复杂数据上表现更好。步骤四模型应用与结果输出进行预测使用训练好的最佳模型假设是mdl_rf对未来一周的特征数据需要提前准备好包括未来天气的预测值、基于预测值计算的滞后特征等进行预测。输出结果将预测结果整理成表格并绘制成直观的图表插入论文。% 假设 future_features 是准备好的未来特征矩阵 future_predictions predict(mdl_rf, future_features); % 创建结果表 result_table table(future_timestamps, future_predictions, ... VariableNames, {Timestamp, Predicted_BorrowCount}); % 保存为Excel文件方便提交和查看 writetable(result_table, prediction_results.xlsx); % 绘制预测图 figure; plot(result_table.Timestamp, result_table.Predicted_BorrowCount, g-, LineWidth, 2); xlabel(日期时间); ylabel(预测借车量); title(A区未来一周每小时借车量预测); datetick(x, mm/dd HH:MM, keepticks); % 格式化时间坐标轴 grid on; exportgraphics(gcf, future_prediction.png, Resolution, 300);步骤五撰写论文要点在论文中你需要清晰地阐述以上所有步骤问题重述与分析用你自己的话说明要做什么。数据预处理描述如何处理缺失值、异常值以及进行了哪些特征工程。附上关键的数据探索图如箱线图、散点图。模型建立解释为什么选择随机森林模型例如能处理非线性、交互作用对异常值不敏感等。简要说明其原理。模型求解与结果给出模型评估指标RMSE等并展示测试集上的预测对比图证明模型的有效性。预测与应用展示对未来一周的预测结果图表并给出简洁的文字说明。优缺点与改进客观分析本模型的优点和局限性例如依赖天气预测的准确性并提出可能的改进方向如引入更多外部数据尝试深度学习模型LSTM等。通过这样一个完整的、简化的流程你将亲身体验到从数据到模型再到结果的完整链条。记住在真正的比赛中数据会更脏特征工程更复杂模型调参如随机森林的树深度、叶子节点最小样本数也需要反复尝试。但核心的MATLAB操作思想和流程就是如此。多练多踩坑多总结你会发现自己从一个对MATLAB和建模一无所知的小白逐渐成长为能够独立解决复杂问题的准专家。