资讯详情

MATLAB LSTM城市人口预测实战:从数据预处理到误差评估

📅 2026/10/18 18:06:44 | 华诺云谱 👁 阅读
MATLAB LSTM城市人口预测实战:从数据预处理到误差评估
简介面向城市规划、数据分析及深度学习初学者这份MATLAB实现的城市人口预测项目基于长短期记忆网络LSTM完成时间序列建模适合作为本科毕业设计或课程扩展的参考代码。压缩包共38个文件核心为4个.m源码脚本包含主程序main1.m、main2.m以及MSE_RMSE_MBE_MAE.m、R_2.m等评价指标计算脚本另附人口数据xlsx表格与多张运行结果截图便于核验输出和调整参数。包体仅553KB文件类型覆盖代码、数据与图表预览结构清晰。目前已有525人学习代码注释完整可帮助读者理解LSTM在人口预测中的数据处理、网络搭建和误差评估流程也便于替换自身数据后直接扩展应用。1. 用 LSTM 预测城市人口为什么传统回归模型在这里会失灵城市人口数据是典型的时间序列——每年的人口数不仅和当年的经济、政策有关更和过去十几年的惯性增长强相关。用普通多元回归去拟合这种带长期依赖的数据往往误差大得离谱而长短期记忆网络LSTM通过门控机制把历史信息有选择地传递下去恰好能捕捉这种“惯性”。这份基于 MATLAB 的 LSTM 城市人口预测项目代码完整、数据齐全适合本科及以上水平的读者做课程设计、毕业论文扩展或入门时序预测实战。它解决的问题很具体给定某城市历年人口统计值用神经网络学习增长规律并预测未来若干年的人口数。文中配套了数据文件、训练脚本和误差评估脚本你不需要自己造轮子直接改数据和参数就能跑通。2. 项目骨架从 rar 压缩包到第一个可运行的预测结果2.1 文件构成与各文件职能拿到压缩包后第一件事是搞清楚每个文件是干什么的。解压后你会看到一组 JPG 图片编号从 a1 到 a16、b1 到 b16这些是博主在运行过程中保存的训练过程截图和结果图作用有两个一是给你一个“预期结果”的参照二是当你自己跑出来的图和它们对不上时可以对照排查哪一步出了问题。核心代码文件只有两个main1.m 和 main2.m再加上两个误差评估脚本 R_2.m 和 MSE_RMSE_MBE_MAE.m。2.2 main1.m 和 main2.m 的分工逻辑常见的设计思路是main1.m 负责读取人口数据、划分训练集和测试集、构造 LSTM 训练所需的序列格式main2.m 负责加载训练好的网络或用不同参数重新训练并输出预测曲线。我一般建议先运行 main1.m 生成基础模型再运行 main2.m 对比不同参数下的预测效果。有些版本会把两个脚本合并成一个但拆开的好处是——当你只需要微调模型参数时完全不需要重新跑数据预处理那一大段代码省时间也省内存。3. 数据入口人口数据.xlsx 的读取与序列化处理3.1 表格格式与读取方式项目配套的人口数据.xlsx 是核心数据源里面通常只有两列年份、人口数单位可能是万人或人也可能直接只有一列人口数加一列年份序号。MATLAB 读取 xlsx 的标准做法是% 读取人口数据表格假设第一列是年份第二列是人口数 data_table readtable(人口数据.xlsx); years data_table{:, 1}; % 年份列 pop data_table{:, 2}; % 人口数列 % 检查数据是否有缺失值 if any(isnan(pop)) error(人口数据包含缺失值请检查Excel表格); end % 将人口数据转为 double 类型并绘制原始曲线 pop double(pop); figure; plot(years, pop, b-o, LineWidth, 1.5); xlabel(年份); ylabel(人口数); title(原始人口数据曲线); grid on;这段代码先用了 readtable 读取 Excel再分别取出年份和人口两列。第 68 行做了一个缺失值检查——这是时间序列预测里最容易翻车的地方——如果 Excel 某一行是空的后面所有训练步骤都会出错但报错信息可能绕得很远你根本想不到是数据缺失的问题。isnan 配合 error 可以在第一时间阻止你用脏数据跑训练。3.2 为什么要做归一化处理LSTM 内部用的是 sigmoid 和 tanh 激活函数它们的输出范围分别限制在 (0,1) 和 (-1,1)。如果你直接拿几百万量级的人口数喂进去梯度计算会出问题网络很难收敛。常见做法是把数据映射到 [0,1] 区间等预测完成后再反归一化回真实人口数% 归一化到 [0,1] 区间 pop_min min(pop); pop_max max(pop); pop_norm (pop - pop_min) / (pop_max - pop_min); % 划分训练集和测试集这里假设前80%作为训练集 train_ratio 0.8; train_len floor(length(pop_norm) * train_ratio); % 构造 LSTM 输入输出对用过去 num_steps 年预测下一年 num_steps 3; % 时间步长即用过去几年预测下一年 XTrain []; YTrain []; for i (num_steps1):train_len XTrain [XTrain; pop_norm(i-num_steps:i-1)]; YTrain [YTrain; pop_norm(i)]; end % 转置为 LSTM 需要的格式特征维度 × 时间步 × 样本数 XTrain XTrain; YTrain YTrain;归一化这一步很多人图省事用 mapminmax 函数但手写这段代码的好处是你能清楚知道最大最小值分别是什么反归一化的时候不容易搞混。第 15 行的 for 循环是关键——它把普通的一维人口序列转成了“过去 3 年推下一年”的有监督样本对。这里 num_steps 的取值直接决定了模型的记忆长度取太小学不到长期趋势取太大则训练样本数量会大幅缩短需要看数据量权衡。3.3 预测值如何还原成真实人口数模型输出的是归一化后的数值怎么看都不是真实人口。还原时必须用回和训练时相同的 pop_min 和 pop_max% 反归一化预测结果 pred_pop pred_norm * (pop_max - pop_min) pop_min;注意如果换数据集时没有重新计算 min 和 max预测结果会完全错位。我见过有人直接套用项目自带的归一化参数去预测新城市的数据出来的曲线形状对但数值差了十万八千里。4. LSTM 网络搭建层数、神经元数和训练选项的选型依据4.1 网络结构定义与参数说明LSTM 在 MATLAB 中的搭建不是直接调用现成模型而是用 layer 对象逐层拼装。这个项目里最核心的网络定义代码大致如下% 定义 LSTM 网络结构 numFeatures num_steps; % 输入特征维度等于时间步长 numResponses 1; % 输出维度预测一个值 numHiddenUnits 50; % 隐藏层神经元数 layers [ sequenceInputLayer(numFeatures) % 序列输入层 lstmLayer(numHiddenUnits, OutputMode, last) % LSTM层只输出最后一个时间步 fullyConnectedLayer(numResponses) % 全连接层映射到输出维度 regressionLayer]; % 回归损失层 % 训练选项配置 options trainingOptions(adam, ... MaxEpochs, 200, ... % 最大训练轮数 MiniBatchSize, 16, ... % 小批量样本数 InitialLearnRate, 0.005, ... % 初始学习率 Shuffle, every-epoch, ... % 每轮打乱数据顺序 Verbose, false);这里最值得琢磨的是 lstmLayer 的 OutputMode 参数。改成 last 表示只取最后一个时间步的输出作为预测值——对于“用过去 N 年预测下一年”这种单步预测任务这是标准做法如果要做多步序列到序列的预测就得换成 sequence。第 7 行 lstmLayer 的神经元数 50 是个经验值人口数据一般只有几十年数据量小神经元太多容易过拟合太少则学不到增长惯性。4.2 学习率和训练轮数怎么调Adam 优化器的初始学习率我建议从 0.005 起步。如果损失曲线震荡得厉害就降一个量级到 0.001如果收敛太慢可以试着提高到 0.01但要注意会不会发散。MaxEpochs 设 200 是合理的——人口数据训练样本通常只有几十到几百条200 轮足够收敛再多容易过拟合把历史数据的噪声都背下来。判断是否过拟合的方式很简单看训练集误差和测试集误差的差距如果训练误差降得很低但测试误差反而上升就是过拟合了这时候减小 numHiddenUnits 或加大正则化权重。4.3 训练与预测的完整流程% 训练 LSTM 网络 net trainNetwork(XTrain, YTrain, layers, options); % 构造测试集的输入延续训练集的最后一个时间步 % 先取训练集最后 num_steps 个数据作为预测起点 XTest []; for i 1:(length(pop_norm) - train_len) idx train_len - num_steps i; if i 1 XTest pop_norm(idx : train_len); else % 用上一步的预测值作为输入滚动预测未来每一步 XTest [XTest; pred_norm(end)]; end end % 预测并反归一化 pred_norm predict(net, XTest); pred_pop pred_norm * (pop_max - pop_min) pop_min;滚动预测这部分是时间序列预测最容易出错的地方。测试集的第一个输入是训练集最后 3 年的真实值但第二个输入开始用的是模型自己上一步的预测结果而不是真实值。这意味着误差会逐级累积——预测年份越远可信度越低。图中 b 系列图片展示的就是这种滚动预测的效果对比。5. 避坑指南四个高频翻车现场与解决记录5.1 数据维度和 LSTM 输入格式不匹配现象运行 trainNetwork 时报错“输入数据维度不一致”或者提示 sequenceInputLayer 的维度与训练数据不匹配。原因LSTM 要求输入是“特征数 × 时间步数 × 样本数”的三维格式很多人直接把一列人口数据塞进去。解决用 size() 检查维度确保 XTrain 的维度是 num_steps × 1 × 样本数。我在 3.2 节代码中用了转置操作 XTrain XTrain就是把这个格式摆正。5.2 归一化后的预测值变成常数现象预测结果是一条水平直线不随时间变化。原因最常见的是学习率太大导致网络发散或者隐藏层神经元数太少模型退化成了简单均值预测。还有一个隐蔽原因是 MiniBatchSize 太大小样本数据都被压成一个批次LSTM 学不到时间依赖关系。解决把学习率降到 0.001MiniBatchSize 降到 8 或 16重新训练。5.3 图片编号对不上运行结果现象自己跑出来的图跟压缩包里 a1.jpg、b3.jpg 对不上。原因博主用的数据划分比例和 num_steps 参数可能和你在代码里改过的不一致导致图表中的时间范围或样本数量不同。解决先用原始参数完整跑一遍确认输出和图片一致后再改参数做实验。这不算 bug是参数版本问题。5.4 反归一化后人口数出现负值现象预测结果有负数或者超出合理人口数量级。原因归一化时用的是整段数据的 min 和 max但测试集末尾的数据如果明显超出历史范围模型外推能力有限归一化后的预测值可能低于 0 或高于 1反归一化后就产生异常值。解决如果工具支持可以用 ReLU 层限制输出非负或者检查预测年份是否超出训练数据时间范围太多尽量避免外推超过总时间跨度的 20%。6. 从指标到结论四个误差系数教你判断模型是否真的可用6.1 误差指标脚本的使用方法项目里的 MSE_RMSE_MBE_MAE.m 和 R_2.m 是用来评估预测精度的它们的调用方法很直接% 加载真实人口值和预测值 % 假设 true_pop 是真实人口pred_pop 是模型预测人口 R2 R_2(true_pop, pred_pop); [MSE, RMSE, MBE, MAE] MSE_RMSE_MBE_MAE(true_pop, pred_pop); % 输出结果 fprintf(决定系数R²: %.4f\n, R2); fprintf(均方误差MSE: %.4f\n, MSE); fprintf(均方根误差RMSE: %.4f\n, RMSE); fprintf(平均偏差MBE: %.4f\n, MBE); fprintf(平均绝对误差MAE: %.4f\n, MAE);6.2 各误差指标的实际含义R² 越接近 1 说明模型解释了大部分真实变化一般城市人口预测能到 0.9 以上就算不错。MSE 和 RMSE 量纲不同MSE 是误差的平方和平均RMSE 是它的开方和人口数据同量纲比如误差 5 万人左右RMSE 就会在这个数值附近。MAE 是对误差绝对值直接平均不容易被极端值干扰。MBE 的正负说明模型整体是偏高还是偏低——如果 MBE 是正数说明系统性地多报人口如果是负数则少报。6.3 案例总结一套我常用的调参检查法我自己跑这类项目时最常用的一套流程是先固定 num_steps 3、训练轮数 200、隐藏层 50跑通后再分别改变 num_steps 观察预测曲线变化。如果 num_steps 从 3 改成 5 后 RMSE 明显变大说明最近两年的数据对人口增长的影响更大模型记忆不需要太长反过来如果误差变小说明人口增长有明显惯性需要更长的历史窗口。这个过程看着像玄学实际是时间序列预测的核心诊断思路。从那以后我每次拿到一个 LSTM 时序项目都会强制自己按“先跑通、再改参数、最后看误差分解”的顺序走一遍这套顺序帮我避开了至少五次维度不对、参数失眠的坑。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑