恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
BP神经网络电力负荷预测:MATLAB实现与参数整定全流程解析
首页
资讯中心
/
BP神经网络电力负荷预测:MATLAB实现与参数整定全流程解析
BP神经网络电力负荷预测:MATLAB实现与参数整定全流程解析
发布时间:2026/10/3 23:38:06
简介基于MATLAB的BP神经网络电力负荷预测毕业设计/课程设计源码包面向电力系统数据分析、神经网络建模学习者提供从Excel数据读取、网络训练到负荷预测的完整可运行实现。工程共334个文件以329个xlsx数据文件为主包含历史负荷、气象等时序数据另有3个m脚本主程序及自定义映射函数、1个README说明与1个asv备份压缩包仅5.34MB轻量便于快速部署调试。项目源码经环境编译验证评审分98分难度适中适合本科毕业设计、期末大作业或课程设计参考。其中weather.xlsx、按日期命名的负荷样本等数据组织清晰配合read_load_data_from_excel.m等文件可直观理解数据预处理、BP网络构建、训练与误差分析流程。目前已有162人学习下载适合需要快速获取可复现代码并希望减少调试时间的MATLAB使用者。1. BP神经网络做电力负荷预测为什么这个老方法至今没人敢扔调度员最怕的不是高峰而是明天十点钟的负荷突然比预测值高出5%。多备一台机组一晚上燃料成本打水漂少备一台最坏情况是拉闸。电力负荷预测就是这么个直接跟钱和安全挂钩的活儿而BP神经网络是这个领域里被验证次数最多的黑盒模型——它不需要你假设负荷和温度、日类型之间是什么函数关系只要给足历史样本它自己往上逼近。很多毕业生和转行的工程师第一次独立做预测项目选的就是这条路线。这篇文章要拆的是一份基于MATLAB的BP神经网络负荷预测代码。全文覆盖从数据构造、网络搭建、参数整定到预测效果验证的完整链路代码可以直接改数据开跑。适合三类人正在做电力负荷预测方向毕设的学生、在电网或园区做短期负荷预测需要搭基线模型的工程师以及想把BP当对照模型、后面再上LSTM或Transformer的研究者。老方法没有过时用不对才过时。2. BP神经网络预测负荷先把网络结构和数学原理落到纸面上2.1 负荷预测为什么用BP而不是直接写回归方程电力负荷序列有一个特点它有趋势、有周期性、有随机扰动。工作日的负荷曲线和周末完全不同夏天和冬天的早晚峰位置也不一样。如果你用多元线性回归得手动构造这些特征、还要处理共线性如果你用树模型又得做大量特征工程。BP神经网络的好处在于它用多层非线性变换把“历史负荷温度日期类型”映射到“未来负荷”这个目标上不需要你预先指定交互项。换个角度理解BP在这里的角色它是一个函数逼近器。数学上已经证明一个带足够多隐含层节点的三层BP网络可以逼近任意连续函数这就是万能逼近定理。具体到负荷预测输入是过去若干天的负荷值、当天的最高最低温度、星期几输出是未来一天或未来一个时刻的负荷。你喂给它的样本越多、特征越跟负荷变化相关它逼近出来的映射就越准。有个容易忽略的前提BP是梯度下降法训练出来的它对特征的尺度极其敏感。负荷动辄是几百兆瓦温度是几十摄氏度星期几是1到7这三个量级放一起如果不做归一化梯度更新会被大数值的特征主导小数值特征几乎学不到东西。所以任何BP负荷预测代码的第一步一定不是建网络而是处理数据。2.2 BP网络结构怎么定输入层、隐含层、输出层的职责分配标准BP网络就是三层结构输入层、一层隐含层、输出层。输入层节点数等于特征数量输出层节点数等于预测目标的维度隐含层节点数需要手动整定。负荷预测最常见的输入构造方式是滑动窗口。比如用前7天的同一时刻负荷预测今天同一时刻的负荷那输入就是7个节点如果再加上“当天最高温度、当天最低温度、星期几、是否节假日”输入节点就变成11个。输出一般是1个节点就是预测时刻的负荷值。隐含层节点数没有解析解经验公式是取输入层和输出层节点数之和的根号值附近再上下试探。比如输入11个输出1个隐含层可以先设12再往10和15两个方向试。代码里最核心的就是训练函数的选择。MATLAB的feedforwardnet默认用Levenberg-Marquardt算法做训练也就是trainlm。这个算法在中小样本规模下收敛快、精度高是负荷预测这类回归任务的默认首选。scarce样本量大的时候可以切到trainscg量化共轭梯度显存占用小、速度更快。下面这段代码是最小可用版本直接在MATLAB里就能跑通。% 加载处理好的输入特征和输出目标 % inputData: 每行一个样本列为特征历史负荷、温度、星期几等 % targetData: 每行一个样本列为预测时刻的实际负荷值 load(loadData.mat); % 你的数据文件包含 inputData 和 targetData % 划分训练集和测试集前80%训练后20%测试 trainRatio 0.8; trainLen floor(size(inputData, 1) * trainRatio); trainInput inputData(1:trainLen, :); trainTarget targetData(1:trainLen, :); testInput inputData(trainLen1:end, :); testTarget targetData(trainLen1:end, :); % 创建BP网络隐层10个节点 hiddenSize 10; net feedforwardnet(hiddenSize); % 训练参数LM算法最大迭代次数1000误差目标0.001 net.trainFcn trainlm; net.trainParam.epochs 1000; net.trainParam.goal 0.001; net.trainParam.min_grad 1e-6; % 训练网络 [net, tr] train(net, trainInput, trainTarget); % 测试集预测 predicted net(testInput);这段代码的逻辑是先按行取样本转置成列向量输入——MATLAB神经网络工具箱要求样本按列排这是新手最容易忽略的坑。trainRatio控制训练集和测试集的划分比例80%训练、20%测试是回归任务里的常见默认值。hiddenSize是最需要调的参数直接决定网络的拟合能力太小则欠拟合太大则过拟合后续章节会专门讲怎么试探。训练完成后net就是一个训练好的网络对象可以直接用它预测新样本。predict的维度是隐含层节点数乘输出层节点数配合权重矩阵和偏置项构成一个完整映射。2.3 网络的数学计算过程从输入到输出的一次正向传播训练好的网络怎么把输入变成输出正向传播的过程可以用矩阵运算描述。设输入向量为x输入层到隐含层的权重矩阵为W1隐含层偏置为b1隐含层输出h经过激活函数tanh或logsig变换再乘隐含层到输出层的权重矩阵W2加偏置b2得到最终输出y。$$h \tanh(W_1 x b_1)$$$$y W_2 h b_2$$这个过程的含义是输入特征先被线性变换到隐含层空间再经过非线性激活函数做映射最后线性组合成预测值。BP算法做的是反向传播——计算输出误差对每个权重和偏置的偏导然后用梯度下降更新它们。理解这个计算过程对调参很有用。如果你发现训练误差降不下去问题往往出在激活函数饱和区。负荷数据归一化到[0,1]后如果某个样本的特征值全部接近1tanh的导数值趋近于0梯度就会消失权重更新几乎停滞。这时候要么检查归一化是否正确要么换用logsig激活函数它的输出范围是[0,1]跟归一化后的目标数据天然匹配。3. 电力负荷数据预处理从原始序列到可训练样本的完整流程3.1 负荷序列的特征构造滑动窗口、温度变量、日期变量怎么落成矩阵拿到手的原始数据通常是两列时间戳和负荷值。直接把这个序列喂给网络是行不通的——网络需要的是“输入特征到目标值”的样本对而不是一本书从头读到尾。最常见做法是滑动窗口构造样本。假设要预测第t天的最高负荷可以用第t-1天到第t-7天的最高负荷作为输入特征。如果数据粒度是小时级要预测明天上午10点的负荷输入就是过去7天同一时刻的负荷值。这样每个样本有7个负荷特征。除了历史负荷温度和日期特征对短期负荷预测影响很大。温度可以直接用预测日的最高气温和最低气温各作为1个特征。星期几用1到7编码也可以用one-hot展开成7个特征——BP网络里直接用一个整数也可以网络会自己学习这个数字跟负荷的关系但one-hot更稳妥避免隐含“星期三比星期二大1”这种无意义的关系。是否节假日是一个0或1的二值特征对预测节假日和节后一天的负荷特别重要。把这些特征拼在一起每一行就是一个样本最后一列是目标值。如果特征有11个输入矩阵就是样本数乘11目标矩阵是样本数乘1。这里有个很多人翻车的点特征矩阵的每一列必须是对齐的如果某个日期缺温度数据不能直接填0最好用前一天的温度补齐或者删掉这个样本否则网络会学到错误映射。3.2 归一化的两种姿势mapminmax的坑与手动归一化的可逆性MATLAB神经网络工具箱自带mapminmax函数做归一化这是官方推荐做法。mapminmax把每一行数据映射到[-1,1]或[0,1]区间训练前调用一次预测后反归一化一次工具箱会自动记录归一化的参数不需要手动保存。用mapminmax有个问题容易踩它默认按行归一化如果数据排列方式是“每列一个样本”直接调用会把每个特征单独归一化这没问题但如果数据排列是“每行一个样本”那就变成每个样本单独归一化不同样本之间的量纲就乱了。所以在调用之前必须先确认数据排列方式统一转成“特征行、样本列”的格式。手动归一化的好处是可逆性更直观代码可控。把数据缩放到[0,1]公式是(x-min)/(max-min)预测完再乘回来。下面是手动归一化的完整代码包含预测后的反归一化。% 手动归一化把原始负荷映射到[0,1]区间 load(loadData.mat); featureRaw inputData; % 原始特征矩阵N x DN为样本数 targetRaw targetData; % 原始目标向量N x 1 % 计算每个特征维度的最小值和最大值 featMin min(featureRaw, [], 1); featMax max(featureRaw, [], 1); targetMin min(targetRaw, [], 1); targetMax max(targetRaw, [], 1); % 归一化到[0,1] featureNorm (featureRaw - featMin) ./ (featMax - featMin); targetNorm (targetRaw - targetMin) ./ (targetMax - targetMin); % 划分训练集和测试集 trainLen floor(size(featureNorm, 1) * 0.8); trainFeature featureNorm(1:trainLen, :); trainTarget targetNorm(1:trainLen, :); testFeature featureNorm(trainLen1:end, :); testTargetRaw targetRaw(trainLen1:end, :); % 保留原始值用于最后对比 % 训练BP网络 hiddenSize 12; net feedforwardnet(hiddenSize); net.trainFcn trainlm; [net, tr] train(net, trainFeature, trainTarget); % 预测并反归一化 predNorm net(testFeature); predicted predNorm .* (targetMax - targetMin) targetMin;逻辑说明先把原始特征和目标值分别归一化这里用的是按列计算min和max也就是每个原始维度一个min值。featureNorm和targetNorm的范围都是[0,1]。训练集和测试集用的是同一个min和max参数这非常重要——如果分别用各自的最大最小值归一化测试集的分布就被人为拉平了相当于作弊。测试集的绝对误差会被低估。参数说明hiddenSize取了12如果输入维度是7个负荷加3个温度加1个星期几就是11维12比经验公式的根号11略高属于偏大一点给网络更多拟合空间。targetMax和targetMin是原始负荷数据里的最大最小值反归一化之后predicted的单位和原始负荷一致了。3.3 数据切分的三个层次训练集、验证集、测试集各司其职初学者最容易犯的错误是只用训练集和测试集两分法训练完直接在测试集上评估精度然后反复改参数看测试集结果。这样做的问题在于测试集已经被“偷看”了——你调参数的过程中网络间接记住了测试集的信息最终报告的测试集精度是偏乐观的。正确做法是三分法训练集训练网络权重验证集做早停和选参测试集只做最终评估。MATLAB的train函数内部会自动从训练集里分出验证集做早停不需要手动切。默认配置是训练集70%、验证集15%、测试集15%这个比例在样本量充足时够用。如果样本量太少比如只有几百个验证集占比可以降到10%。还有一层切分容易被忽略时间顺序。负荷数据是时间序列不能随机打乱再切分否则会造成数据泄露——测试集里的某些样本会出现在训练集前面网络相当于看到了“未来的数据”。正确做法是按时间顺序前80%训练后20%测试中间不能穿插。4. 训练参数整定与模型评估从默认参数到预测误差可控4.1 隐含层节点数怎么试从小到大的网格搜索法隐含层节点数是BP网络里最敏感的超参数。节点太少网络表达能力不足训练集误差都降不到目标值节点太多网络开始死记训练样本测试集误差反弹这就是过拟合。经验公式只能给一个起点真正靠谱的是做小范围网格搜索。具体做法分别设隐含层节点数为4、6、8、10、12、15每个配置训练一次记录训练集误差和测试集误差。测试集误差最低的那个节点数就是当前数据下的最优选择。注意每次训练都要重新初始化权重否则对比不公平。用MATLAB实现网格搜索比较直接但由于train函数内部有随机权重初始化同一配置多次训练结果会略有波动。常见做法是每个配置训练3次取平均消除随机性影响。% 网格搜索最优隐含层节点数 hiddenCandidates [4 6 8 10 12 15]; testErrors zeros(length(hiddenCandidates), 1); trainErrors zeros(length(hiddenCandidates), 1); for i 1:length(hiddenCandidates) hiddenSize hiddenCandidates(i); net feedforwardnet(hiddenSize); net.trainFcn trainlm; net.trainParam.epochs 500; net.trainParam.goal 1e-4; % 每次训练前重置随机种子保证可比性 rng(i); [net, tr] train(net, trainFeature, trainTarget); % 计算训练集预测误差均方根误差 trainPred net(trainFeature); trainRMSE sqrt(mean((trainPred - trainTarget).^2)); trainErrors(i) trainRMSE; % 计算测试集预测误差 testPred net(testFeature); testRMSE sqrt(mean((testPred - testTargetNorm).^2)); testErrors(i) testRMSE; end % 打印结果 disp(隐藏节点数 训练RMSE 测试RMSE); for i 1:length(hiddenCandidates) fprintf(%d %.4f %.4f\n, hiddenCandidates(i), trainErrors(i), testErrors(i)); end % 找测试误差最小的配置 [bestError, bestIdx] min(testErrors); fprintf(最优隐藏节点数: %d, 测试RMSE: %.4f\n, hiddenCandidates(bestIdx), bestError);逻辑说明这个脚本把训练和评估串成一个循环每个候选节点数独立训练一次。rng(i)的作用是固定随机数种子让每次训练的权重初始值不同但同一配置下保持可复现。trainFeature和trainTarget是在3.2节准备好的归一化训练数据。参数说明trainRMSE和testRMSE都用均方根误差单位是对数化后的[0,1]区间。如果你要跟原始负荷值的误差对比需要把预测结果反归一化后再算RMSE。epochs设500对于几百个样本的负荷预测足够了再大容易过拟合goal设1e-4是误差目标LM算法会在达到这个精度时提前停止。4.2 训练函数选择trainlm、trainscg、trainbr的适用场景对比MATLAB神经网络工具箱提供了多种训练函数本质区别在于优化算法。三种最常见的选择trainlm是Levenberg-Marquardt基于高斯牛顿法的改进利用二阶导数信息收敛速度快适合中小规模数据集训练几百到几千个样本通常几十次迭代就能到目标误差。缺点是内存占用高、对初始值敏感。trainscg是标量共轭梯度法不需要计算Hessian矩阵内存占用小训练速度稍慢但稳定适合样本量大、特征维度高的情况。如果你的数据有几万条trainlm可能出现内存不足trainscg是更好的选择。trainbr是贝叶斯正则化它在训练过程中自动调整正则化系数防止过拟合能力最强但训练时间最长。适合数据量少、噪声大、你不想手动调正则化参数的情况。负荷预测的典型场景数据量几千条特征十几个trainlm是默认选择。如果发现测试集误差远大于训练集误差说明过拟合了可以换trainbr试试。下面的表格总结了三种函数的适用场景训练函数收敛速度内存占用过拟合控制典型场景trainlm快高弱中小样本快试验默认首选trainscg中低弱大样本量几千条以上trainbr慢中强样本少且噪声大需要稳定泛化4.3 评估指标怎么算MAE、RMSE、MAPE在负荷预测里的不同解读训练完模型怎么评价它好不好用三个指标各看一个侧面。MAE平均绝对误差直接反映预测值与实际值之间的平均偏离量单位跟负荷一致比如30兆瓦。它对所有误差一视同仁不会放大极端误差。RMSE均方根误差先把每个误差平方再平均开根号大误差会被放大所以RMSE总是大于等于MAE。如果RMSE比MAE大很多说明预测结果里存在少数误差特别大的点需要排查是不是某些日期的负荷波动异常。MAPE平均绝对百分比误差是无量纲的以百分比形式呈现方便不同预测对象之间横向对比。调度部门通常要求短期负荷预测MAPE控制在3%到5%以内。计算MAPE有个坑如果某个时刻的实际负荷接近0这个点的百分比误差就会爆炸。凌晨低谷时段负荷可能只有峰值的十分之一MAPE稍高是正常的看整体趋势时建议剔除这种极端点。下面是综合评估代码假设你已经用最优隐藏节点数训练好了一个网络对测试集做预测并反归一化。% 假设net是最优节点数训练好的网络特征和原始值变量名沿用3.2节 testPredNorm net(testFeature); testPred testPredNorm .* (targetMax - targetMin) targetMin; % 计算三个评估指标 errors testPred - testTargetRaw; % 预测值与实际值的差 MAE mean(abs(errors)); RMSE sqrt(mean(errors.^2)); MAPE mean(abs(errors ./ testTargetRaw)) * 100; fprintf(MAE: %.2f MW\n, MAE); fprintf(RMSE: %.2f MW\n, RMSE); fprintf(MAPE: %.2f%%\n, MAPE); % 找出误差最大的5个点看看是哪些时段 [sortedErrors, idx] sort(abs(errors), descend); top5 idx(1:5); disp(误差最大的5个样本及对应日期); disp(top5); % 这里的top5对应测试集里第几个样本可回溯到原始数据集逻辑说明反归一化之后testPred的单位是兆瓦testTargetRaw是原始负荷值。errors直接算两者的差。百分比误差用errors除以实际值再乘以100这里用的是测试集全部点如果某个点实际负荷接近0MAPE会被拉高建议在计算前过滤掉那些负荷低于某个阈值比如50MW的点得到更稳妥的MAPE。参数说明sort函数降序排列误差top5前5个是预测最不准的样本。把这些样本回溯到原始数据集查询它们的日期和时段通常是节假日切换日、极端天气日这些都是BP网络的天然弱点不用过于纠结。4.4 早停与防止过拟合train函数里隐藏的验证集机制MATLAB的train函数内部默认把训练数据再切三份训练集、验证集、测试集比例默认是0.7/0.15/0.15。验证集的作用是早停每个epoch结束后网络计算一次验证集误差如果验证集误差连续上升若干次说明开始过拟合训练提前终止。这个机制不需要额外配置代码但它默认开启的你可以在net.trainParam里看到max_fail参数默认是6次。把max_fail调大网络在验证集误差上升时能被允许继续训练更久适合数据噪声大的情况调小训练更早停止泛化更强但可能欠拟合。需要留意的是这个内置验证集是在训练集内部划的跟外部划分的测试集不冲突。外部测试集从头到尾不参与训练也不参与早停判断只做最终评估。所以流程是原始数据按时间顺序切80%训练20%测试训练代码内部再把这80%切成训练验证做早停。如果发现验证集误差下降很慢可能是初始权重太差。MATLAB里可以用net.initFcn和net.initParam设置初始化方式默认是Nguyen-Widrow初始化对非线性激活函数比较友好一般不需要改。真正要改的是初始随机种子用rng固定一个值训练结果可复现调试时方便对比。5. BP神经网络负荷预测避坑手册现象、原因、解决一条龙5.1 训练误差降到1e-10测试误差却大得离谱现象训练完成后训练集误差几乎为0网络在训练集上完美拟合但测试集的预测曲线明显偏离实际负荷误差率超过15%。原因过拟合。隐含层节点数太多网络把训练样本的噪声也记下来了。训练集误差降得越低不代表模型越好只能说明网络记住了训练集里的每一个点包括那些因为突发事件导致的异常负荷值。解决把隐含层节点数降下来回到网格搜索找最优配置。另外检查早停是否生效——验证集误差连续6次不下降时训练自动停止如果max_fail设得太小可能验证误差还没开始体现过拟合信号就已经停止需要调大max_fail或者改用trainbr做贝叶斯正则化。5.2 预测结果全是同一个值网络根本没学进去现象测试集预测结果几乎是一个常数画出来是一条水平直线MAPE超过30%。原因数据归一化出了问题。最常见的是训练和预测的反归一化参数不匹配。训练时用mapminmax归一化目标值预测后忘记反归一化直接用归一化后的数值跟真实值比误差自然巨大。另一种情况是目标值在归一化时用了错误的min和max——比如测试集的min和max分别计算而不是沿用训练集的参数导致分布漂移。解决检查归一化的参数是否在训练和测试之间保持一致。手动归一化的代码里训练时的targetMin和targetMax必须保存下来预测时用同一组参数做反归一化。如果用了mapminmax预测后调用mapminmax(reverse, pred, settings)其中settings是训练时保存的归一化参数。5.3 训练集误差迟迟不降学习率与激活函数在作祟现象训练前几百个epoch误差纹丝不动loss曲线像一个平台后面也可能突然下降或者完全不动。原因学习率太低或初始权重没有落在合适的区域。trainlm算法里学习率由mu参数控制默认是0.001训练过程中会自动调整但如果初始mu太小前期的权重更新量极小误差下降缓慢。另一种原因是激活函数进入了饱和区——输入数据归一化范围选错了如果用了[-1,1]范围但隐含层激活函数是logsig输出范围0到1负输入会直接走进饱和区梯度接近0。解决把输入归一化范围从[-1,1]改成[0,1]跟logsig的输出范围对齐。或者把激活函数换回tansig它在[-1,1]范围内有更好的梯度响应。trainlm的mu参数可以在net.trainParam.mu里手动设置初始值一般设成0.001到0.1之间如果平台期太久可以调到0.01。5.4 同一份数据多次训练结果忽好忽坏现象不改任何代码和参数连续运行两次训练测试集预测误差一个MAPE是3%另一个是8%差距悬殊。原因BP网络每次训练的初始权重都是随机生成的MATLAB默认的随机种子每次启动都会重新生成。初始权重不同LM算法最终收敛到的局部最优解就不同这是BP算法先天的不确定性。解决用rng固定随机种子比如rng(42)这样每次运行都得到相同的初始权重和相同的结果。如果做网格搜索或者对比实验务必在每组实验前用不同的rng固定种子保证组间只有控制变量在变。实际项目中一般会训练10次取测试误差最小的那个模型保存这样既保留随机性又拿到最优结果。5.5 预测曲线整体滞后一天输入变量没对齐现象预测负荷曲线的峰谷和实际负荷曲线的峰谷形状相似但整体向右平移了一天。原因输入特征构造时日期对齐出了问题。比如你要预测1月10日的最高负荷输入用了1月9日到1月3日的负荷值但温度特征用了1月11日的预报温度——温度数据时间戳和负荷数据时间戳没有对齐导致网络学到的映射里存在时间偏移。解决仔细检查特征矩阵每一列的时间戳。一个稳妥的办法是构造样本时输出一个时间标签矩阵预测完成后把预测值和实际值按时间标签对齐画图一眼就能看出是否存在偏移。如果输入特征里包含温度预报数据必须用预测发布时刻能获取到的预报值而不是事后才能拿到的实测值否则在真实场景里模型会失效。6. 预测结果可视化与波形分析把误差转化成功率调度决策依据模型训完评估指标达标下一步是把预测结果画出来放到调度场景里看它到底能不能用。可视化不是画一张好看的图就算完事你要能从图里读出三个信息整体跟随性、峰谷误差、突变时段误差。整体跟随性看预测曲线和实际曲线的重合度。重合度高说明模型学到了负荷的周期性规律。峰谷误差要看早晚两个高峰时段的误差符号——如果模型在早峰时段系统性偏低10%调度员就知道要在早峰前额外准备一台旋转备用机组这个信息比一个笼统的MAPE有用得多。突变时段误差通常对应节假日切换、极端天气这些时段模型会给出偏保守的预测曲线抖动明显需要在规则层面额外修正。画图代码建议直接用MATLAB的figure和plot把实际值和预测值放在同一坐标系显示标注日期刻度。% 预测结果可视化 figure(Position, [100 100 1000 500]); plot(testTargetRaw, b-, LineWidth, 1.5); hold on; plot(testPred, r--, LineWidth, 1.5); hold off; legend(实际负荷, BP预测负荷, Location, best); xlabel(测试集样本序号); ylabel(负荷MW); title(BP神经网络电力负荷预测结果对比); grid on; % 误差分布直方图 figure(Position, [100 600 800 300]); histogram(errors, 30); xlabel(预测误差MW); ylabel(样本数); title(预测误差分布);逻辑说明第一张图把测试集的每个样本按时间顺序绘制蓝色实线是实际负荷红色虚线是预测负荷两条线之间的缝隙就是误差的直观体现。第二张图用直方图看误差分布如果误差近似正态分布在0附近说明模型没有系统性偏差如果直方图明显偏向正值说明模型整体低估负荷偏向负值则说明高估。你有系统性偏差的时候可以在预测结果上做后修正——把偏差均值加回去通常能改善一点MAPE。最后说一个个人习惯保存预测结果时除了输出PDF和PNG图片我总会把预测值和实际值连同时间戳一起导出成CSV字段包括日期、时刻、实际负荷、预测负荷、误差。这样做有两个好处一是可以在Excel里做更细的分析比如按星期几分组算误差二是项目交差时答辩或领导经常追问“某某日的预测是多少”有了一张全量的明细表三秒钟就能查出来。后端上线或者评审时才不用临时翻图、重新跑训练。希望这个习惯能帮到你也祝你的负荷预测项目一次跑通。本文还有配套的精品资源点击获取