简介:《基于改进神经网络的光伏发电功率短期预测方法研究》是一篇技术研究型PDF文档,面向光伏发电、电力调度及机器学习建模领域的研究者与工程师,主要解决光伏输出功率因辐照度、天气和季节等随机因素难以准确预测的问题。文章提出结合思维进化算法与BP神经网络的MEA-BP短期预测模型,输入因子包括大气温度、辐照度、风速和历史输出序列,并按春夏秋冬划分为四个预测单元进行训练与仿真验证,结果表明该模型能有效降低BP网络的预测误差。这份PDF为单个文件,压缩包大小约1.05MB,内容包含光伏输出功率特性分析、BP神经网络原理、改进算法设计及实验对比,便于读者系统掌握从数据特征到模型构建验证的完整建模思路。目前已有161人学习浏览,适合作为光伏功率预测、深度学习改进算法方向的研究参考。
1. 光伏发电功率短期预测:为什么 BP 网络会翻车,MEA-BP 能把 MAPE 从 32% 拉到 15%
做光伏功率预测的人都有一个共同感受:辐照度一变,BP 神经网络的预测值就跟着飘,明明训练时误差挺好看,一到阴雨天就原形毕露。这篇论文给了一个很实在的解法——把思维进化算法(MEA)和 BP 神经网络结合起来,用 MEA 去搜索 BP 网络的初始权重和阈值,替代随机初始化。论文用某 100 MW 并网电站一年的数据做验证,模型输入是温度、辐照度、风速和历史出力序列,按季节拆成 4 套预测单元,最终把平均绝对百分比误差(MAPE)从 BP 的 32.014% 压到了 15.12%,均方根误差(RMSE)从 7.714 MW 降到 3.8 MW。如果你正在做光伏电站的短期出力预测,或者想给 BP 网络找个靠谱的全局寻优方案,这篇论文的建模思路和参数设置可以直接拿来用。下文我把模型结构、四季预测单元、训练参数和复现时容易踩的坑逐条拆开讲。
2. 光伏出力特性分析:辐照度、天气、季节和温度,哪些能当输入特征
2.1 辐照度与功率的线性关系决定输入特征优先级
论文从电站实测数据出发,分析了连续 3 天的辐照度和有功功率曲线,结论很直接:辐照度和发电功率之间有很强的线性关系,辐照度越高,太阳能电池输出功率就越大。这个结论看似常识,但它决定了特征工程的优先级——辐照度必须作为模型的第一输入因子,而且最好是预测日的辐照度数据,不是单纯的历史辐照度。
实际做特征时,要注意辐照度的单位问题。有些电站数据给的是辐照度(W/m²),有些给的是日照强度百分比,建议统一换算成 W/m²。另外,辐照度数据在早晚时段会出现大量接近 0 的值,占比过高会稀释模型对有效时段的拟合能力,一般做法是按光伏出力时段截断,论文里春季和夏季取 07:00-19:00,秋季取 08:00-19:00,冬季取 09:00-19:00,就是这个道理。
还有一种常见误用:直接把辐照度当作功率的线性映射来预测。实际上辐照度到功率之间还存在组件温度、转换效率的损耗,午后辐照度依然高但功率开始下滑,论文里的温度分析也提到了这一点。所以辐照度是主特征,但不能是唯一特征。
2.2 天气类型与季节差异:为什么必须分组建模
论文对比了同一个月不同天气下的日功率曲线,结论是晴天输出曲线相似且平滑,雨天和多云天气下波动剧烈、输出水平低。这意味着,如果混着训练,网络会被晴天样本主导,阴雨天的预测误差会被系统性放大。常见做法是按天气类型给样本分组,比如晴、多云、阴、雨四类,每类单独训练模型;论文的简化方案是按季节分 4 组,原因在于季节差异与天气类型的分布强相关。
季节的影响在论文里体现得很直观:夏季日照时间最长但输出功率最小,冬季日照时间最短但输出功率最大。原因不难理解,冬季太阳高度角低、空气透明度高,加上组件工作温度低,转换效率更高。这带来一个启示:季节不只是时间标签,它同时编码了日照时长、辐照度水平和组件温度三个物理量。所以按季节拆分预测单元,既符合物理规律,又能降低单一模型的学习难度。
从实操角度,我不建议把季节作为输入特征传给网络再让它自己学——样本量本来就不大,季节特征在网络内部的表达不稳定。论文的分组方案更稳妥:四季各建一个预测单元,每个单元独立训练、独立预测。
2.3 温度是把双刃剑:午后功率下滑的物理原因
论文的温度分析用了一天内的温度和输出功率对比曲线,指出环境温度升高会让光伏组件温度升高,转换效率下降,因此输出功率在达到峰值后反而会逐渐减小。这是光伏预测里一个非常典型的非线性环节——同样的辐照度,早晨和下午的功率输出可能差不少。
做特征工程时,温度不能只取预测日当天的平均气温,我建议把最高气温和最低气温也一起送入模型,或者直接使用组件背部温度(如果电站有装温度传感器的话)。论文的输入向量里包含预测日及前 1 天的平均辐照度、温度、风速,属于比较精简的设置。你可以在这个基础上扩展,但要注意输入维度增加后,隐藏层节点数和训练样本量是否匹配,论文后面给出的 4 套网络结构可以当作起点参考。
3. MEA-BP 模型构建:BP 网络拓扑、编码方案与思维进化算法的迭代逻辑
3.1 BP 神经网络的缺陷:局部最优、收敛慢与过拟合
论文对 BP 神经网络的问题总结得很凝练:信息前向传播、误差反向传播,通过预测误差调整权重和阈值,但经常陷入局部最优化、收敛速度慢、拟合过度。这三个问题在光伏预测场景里会互相放大——光伏出力曲线本身有强烈的时段性,早晚接近 0,午间到达峰值,BP 网络对峰值时段的拟合往往不够,而对低谷时段容易过拟合。
网络拓扑上,论文用的是三层网络,输入层到隐藏层再到输出层。假设拓扑为 i-j-k,编码长度为 i×j + j×k + j + k。这个编码长度就是 MEA 要做全局搜索的维度。举个例子,如果输入 19 个节点、隐藏层 15 个节点、输出 13 个节点,那么编码长度是 19×15 + 15×13 + 15 + 13 = 285 + 195 + 28 = 508,意味着 MEA 要在 508 维的空间里找最优解。这个维度对于进化算法来说难度适中,种群规模 2000 完全够用。
一个值得注意的细节:BP 网络的初始权重和阈值对训练结果影响巨大。默认的随机初始化很容易让网络收敛到较差的局部最优,这也是为什么同一个模型多跑几次结果差异很大的原因。MEA 的核心价值就在这一步——用全局寻优替代随机初始化,先找到一组好的初始权重和阈值,再交给 BP 做局部精调。
3.2 思维进化算法的趋同与异化:比遗传算法更直接的全局寻优
思维进化算法保留了遗传算法的种群和进化概念,但用趋同和异化两种操作代替了遗传算子。趋同操作是在子种群内部快速搜索局部最优,每个子种群的最优个体得分就是该子种群的得分;异化操作是在整个解空间搜索,对得分较差的子群体进行解散并随机产生新的子群体,保证子群体总数不变。信息交换通过全局公告板和局部公告板完成。
MEA 的执行步骤论文里写得很清晰:先在解空间中随机生成一定规模的个体,按得分挑选出 M 个优胜个体和 T 个临时个体;围绕每个优胜个体和临时个体创建新个体,形成子群体;在每个子群体内做趋同操作直到子群体成熟;子群体成熟后,在全局公告板张贴得分,执行异化操作——优胜子群体和临时子群体之间进行替代、丢弃和个体释放;重复上述过程直到最优者的得分不能再提高,此时认为收敛,得到全局最优子群体和个体。
这个流程的好处在于,异化操作保证了搜索不会长时间停留在局部最优区域。和遗传算法对比,MEA 没有交叉和变异算子,它靠的是子群体之间的竞争和更新,机制更简单、参数更少,实际用起来反而容易控制。要注意种群规模、子群体数量、迭代次数这三个参数是联动的,论文里给的参数组合(种群 2000、各群体 100 个、子群规模 10、迭代 50 次)是针对单层隐藏层网络调试出来的,如果你改了网络拓扑,建议相应调整种群规模,具体调整思路放到第 5 章说。
3.3 MEA-BP 的算法流程:从编码到最优初始权重
MEA-BP 的整体流程可以概括为六步:确定神经网络拓扑结构,按拓扑结构确定编码方案,把编码映射为解空间中的个体;初始化 MEA 算法参数,设置种群规模和子群体数量;生成初始子群体、优胜子群体和临时子群体;在各子群体内执行趋同操作,在子群体间执行异化操作;迭代直到满足结束条件,输出最优个体;将最优个体解码为 BP 网络的初始权重和阈值,开始 BP 训练。
得分函数的选择直接影响搜索方向。论文将每个个体和种群得分函数设定为训练集均方误差的倒数——均方误差越小,得分越高。这意味着 MEA 在搜索时直接以 BP 训练集上的拟合效果为评价标准,而不是看权重本身的数值分布。这里有一个细节值得注意:得分函数只用了训练集均方误差,没有加验证集误差或正则化项,所以 MEA 阶段选出的初始权重偏向于对训练集的拟合。实际复现时,如果你想提高泛化能力,可以在得分函数里加上验证集误差的加权项,或者在 MEA 之后再用验证集做一次早停,避免后续 BP 训练过拟合。
下面的伪代码描述了 MEA 阶段的核心逻辑,我在每个关键步骤后面标注了对应论文中的操作含义:
import numpy as np def msea_optimize(encode_length, pop_size=2000, winner_num=100, temp_num=100, max_iter=50): # 初始化:在解空间随机生成 pop_size 个个体,每个个体长度 = 编码长度 population = np.random.randn(pop_size, encode_length) * 0.5 # 计算初始得分:得分 = 1 / (训练集均方误差 + eps) scores = np.array([1.0 / (mse(decode_weights(individual)) + 1e-8) for individual in population]) # 选出优胜个体和临时个体(得分最高的前 winner_num 和 temp_num 个) sorted_idx = np.argsort(scores)[::-1] winner_idx = sorted_idx[:winner_num] temp_idx = sorted_idx[winner_num:winner_num + temp_num] # 围绕每个优胜/临时个体生成子群体(论文中"关注优胜个体和临时个体,围绕每个个体创建新的个体") sub_populations = [] for idx in winner_idx: # 子群规模 = pop_size / (winner_num + temp_num) = 2000 / 200 = 10 sub_pop = population[idx] + np.random.randn(10, encode_length) * 0.1 sub_populations.append(sub_pop) # 临时子群体同样处理 for iteration in range(max_iter): # 趋同操作:每个子群体内部搜索,找到局部最优 sub_scores = [] for sub_pop in sub_populations: sub_scores.append(np.max([1.0 / (mse(decode_weights(ind)) + 1e-8) for ind in sub_pop])) # 异化操作:全局公告板比较得分,解散低分子群体并随机生成新子群体 # 优胜子群体保留,临时子群体中得分低者被解散并随机初始化 # 判断最优得分是否连续多轮未提升,若是则收敛 pass # 返回全局最优个体,解码为 BP 网络的初始权重和阈值 return best_individual这段伪代码的重点在三个地方:一是得分函数用了均方误差的倒数,和论文一致,mse()函数需要你自己实现,输入是解码后的权重和阈值,输出是当前 BP 网络在训练集上的均方误差;二是子群体生成时用了0.1倍的标准差做扰动,论文里虽然没写这个值,但实际操作中子群体内部的搜索范围不宜过大,否则趋同操作会退化成随机搜索;三是异化操作的触发条件依赖全局公告板的得分比较,需要记录每个子群体的最优得分并排序。
有了 MEA 选出的最优个体,接下来的 BP 训练就常规了:把最优个体解码为权重和阈值,设置学习率 0.1、目标误差 1e-4、最大迭代次数 1000,用训练集数据迭代更新网络参数,直到满足停止条件。我在做类似项目时会把 MEA 阶段的迭代次数和 BP 训练阶段的最大迭代次数分开记录,因为两者的收敛速度完全不同,混在一起不便于判断问题出在哪个阶段。
4. 四季四套预测单元:输入向量设计、网络结构与训练参数对照
4.1 为什么输入节点数不一样:日照时段决定了出力区间的长度
论文里一个容易忽略的细节是:四个预测单元的输入节点数不同,春季和夏季是 19 个,秋季是 18 个,冬季是 17 个。原因在于各季节的光伏出力时段不一样——春季和夏季取 07:00-19:00,共 13 个小时;秋季取 08:00-19:00,共 12 个小时;冬季取 09:00-19:00,共 11 个小时。输入向量的第一部分是预测日前 1 d 对应时段的每小时发电功率,所以时段长度不同,输入维度就不同。
这种按季节调整出力时段的做法,比固定取 24 小时输入要合理得多。凌晨和傍晚的零功率时段对训练没有任何正向贡献,反而会压低模型对有功时段的拟合权重。如果你复现时发现预测曲线在早晚时段出现明显的拖尾现象,大概率就是没有做时段截断。
四套预测单元的输入向量构成可以整理成下面的表格,方便对照:
| 预测单元 | 输入向量维度 | 输入向量构成 | 输出时段 | 输出维度 | 网络拓扑 |
|---|---|---|---|---|---|
| 春季 | 19 | 前 1 d 07:00-19:00 共 13 h 发电功率 + 预测日及前 1 d 的平均辐照度、温度、风速(6 个特征) | 07:00-19:00 共 13 h | 13 | 19-15-13 |
| 夏季 | 19 | 前 1 d 07:00-19:00 共 13 h 发电功率 + 预测日及前 1 d 的平均辐照度、温度、风速(6 个特征) | 07:00-19:00 共 13 h | 13 | 19-15-13 |
| 秋季 | 18 | 前 1 d 08:00-19:00 共 12 h 发电功率 + 预测日及前 1 d 的平均辐照度、温度、风速(6 个特征) | 08:00-19:00 共 12 h | 12 | 18-15-12 |
| 冬季 | 17 | 前 1 d 09:00-19:00 共 11 h 发电功率 + 预测日及前 1 d 的平均辐照度、温度、风速(6 个特征) | 09:00-19:00 共 11 h | 11 | 17-12-11 |
这里要注意输入向量维度的计算校验:春季 13 个小时的历史功率值 + 平均辐照度、温度、风速各两个(预测日和前 1 d),即 13 + 6 = 19,与论文表 1 完全对应。输出向量是预测日当天 07:00-19:00 每小时一个输出点,共 13 个点。隐藏层节点数的选取论文没有展开推导,而是直接给出结果,这也是这类论文的常见处理方式。实践中可以用经验公式 hidden = sqrt(input × output) + 1~10 来粗选,再逐步调整;论文用 15 或 12,符合这个范围。
4.2 训练数据划分:每季 80 组数据的含义与划分逻辑
论文的实验数据来自 2018 年 3 月 1 日到 2019 年 2 月 28 日,共 12 个月,每个季节一个预测单元,每个单元 80 组数据。需要理解的是,这里的 80 组不是 80 个小时,而是 80 个样本日——每一天构成一个样本,输入是前 1 d 的功率序列和气象数据,输出是当天的功率序列。数据消除异常值后,按季节各取 80 天。由于预测日前 1 d 的数据也要作为输入,所以 80 组数据实际覆盖了 81 天的运行记录,其中第 1 天只能作为输入参考。
80 个训练样本对于三层 BP 网络来说属于偏少的数据量,这也是为什么 MEA 的全局寻优能力在此场景下如此关键——网络本身可拟合的复杂度有限,初始化权重的好坏直接影响最终精度。如果你有更长时间的历史数据,比如两年以上,我建议不要简单扩充训练集,而是按相似日或天气类型再做一层细分,否则样本之间的冲突会拖累模型训练。论文选择每季 80 组,大概率是电站历史数据只有一年,这在实际项目里很常见,不必强求更多数据。
数据归一化也是不能跳过的一步。功率、辐照度的数值范围差异很大,风速和温度的差异同样明显。一般做法是把所有输入输出特征归一化到 [0,1] 或 [-1,1]。论文没有明确写归一化方式,但 BP 网络训练目标误差 1e-4 对未归一化的原始数据几乎不可能达到;所以按 [0,1] 归一化处理是合理推断。预测完成后,记得把输出结果反归一化回实际功率值,再算 MAE、MAPE、RMSE,单位是 MW 或百分比。
4.3 训练参数设置:种群规模、学习率、迭代次数到底怎么配
论文给出的 MEA 参数和 BP 训练参数是一组经过重复实验确定的组合,可以说是全文最值得抄作业的部分:
MEA 算法参数:种群规模 2000,优胜子种群数量 100,临时子种群数量 100,子群规模 10,迭代次数 50。
BP 网络训练参数:最大迭代次数 1000,学习率 0.1,训练目标误差 1e-4。
这里的参数有个联动关系:种群规模 2000 除以优胜与临时子种群总数 200,正好等于子群规模 10。也就是说,种群规模、子种群数量、子群规模三者满足整除关系,这个设计保证了每个子群体有均匀的个体数量。如果你要调整参数,优先保持这个整除关系不变,否则会出现某些子群体过大、某些过小,破坏异化操作的平衡性。
学习率 0.1 在光伏功率预测场景里属于偏大的取值。BP 网络在归一化数据上通常用 0.01~0.1,0.1 配合 1000 次迭代,加上 MEA 给出的优质初始权重,可以在合理时间内收敛。如果你自己实现时发现训练损失震荡不下降,优先把学习率降到 0.05 或 0.02,而不是盲目增加迭代次数。目标误差 1e-4 是均方误差的目标值,不是平均绝对误差——注意别把这两个指标搞混,前者是平方损失,后者是你最终评估时用的误差指标。
我把每套预测单元的数据构成和参数设置整理成一张速查表,方便直接对照:
| 项目 | 春季 | 夏季 | 秋季 | 冬季 |
|---|---|---|---|---|
| 数据时间跨度 | 2018.3.1-5.31 | 2018.6.1-8.31 | 2018.9.1-11.30 | 2018.12.1-2019.2.28 |
| 数据量/组 | 80 | 80 | 80 | 80 |
| 输入节点数 | 19 | 19 | 18 | 17 |
| 隐藏层节点数 | 15 | 15 | 15 | 12 |
| 输出节点数 | 13 | 13 | 12 | 11 |
| 出力时段 | 07:00-19:00 | 07:00-19:00 | 08:00-19:00 | 09:00-19:00 |
隐藏层节点在春季、夏季、秋季都是 15,只有冬季是 12。冬季输出只有 11 个点,历史输入也只有 11 个功率值,输入输出维度同时变小,隐藏层节点相应降低是合理的。不要试图让四套模型共用同一种网络结构——冬季用 19-15-13 会因为输入不足产生大量无意义的零填充,反而损害精度。
4.4 完整复现流程:从原始数据到四季预测结果
按照论文的方法完整跑一遍,我会推荐下面的顺序:
步骤一,数据清洗。剔除辐照度、功率、温度、风速中的异常值和空值,对一天内高于功率装机容量或低于 0 的采样点做标记删除。论文提到「消除异常数据后」划分预测单元,这个步骤看似不起眼,但对 MEA 的得分函数影响极大——一个异常大的功率尖峰会把该样本的均方误差拉高几个数量级,导致整个子群体得分失真。
步骤二,按季节切分数据。每个季节取连续 80 天,构造输入矩阵和输出矩阵。输入矩阵的每一行对应一个样本日的输入向量,维度分别为 19/19/18/17;输出矩阵的每一行对应当天的预测时段功率序列,维度分别为 13/13/12/11。
步骤三,数据归一化。
from sklearn.preprocessing import MinMaxScaler # 以春季为例:X_train shape = (80, 19),y_train shape = (80, 13) scaler_X = MinMaxScaler(feature_range=(0, 1)) scaler_y = MinMaxScaler(feature_range=(0, 1)) X_train_norm = scaler_X.fit_transform(X_train) y_train_norm = scaler_y.fit_transform(y_train)步骤四,运行 MEA 搜索最优初始权重。将 MEA 得到的最优个体解码为 19×15 + 15×13 + 15 + 13 = 508 个权重和阈值参数,赋给 BP 网络。
步骤五,BP 训练。学习率 0.1、目标误差 1e-4、迭代次数 1000,在归一化后的训练集上训练。
步骤六,预测与反归一化。对测试日预测后,用scaler_y.inverse_transform()还原功率值,与真实值计算 MAE、MAPE、RMSE。
这里有个实操建议:论文表 3 给出的是每个时间点的 3 d 平均绝对误差(MAE),单位都是 MW,整理时要注意区分「逐时刻误差」和「全天平均误差」。逐时刻误差能帮你定位模型在哪个时段表现差——通常午间误差最大,因为功率峰值高;早晚误差虽然小,但相对误差百分比反而可能偏大。
5. 复现避坑:数据清洗、弃光限电与 MEA 参数设置的四个教训
5.1 夜间和凌晨零功率时段不剔除,误差指标被严重稀释
现象:模型预测曲线看起来还行,但 MAPE 计算出来异常低,低到不真实。
原因:光伏功率夜间为 0,MAPE 计算时 0 值作为分母会产生无穷大;很多复现者为了避免这个问题,把夜间零值保留在序列里,结果 MAPE 被大量零值拉低,看起来精度很高,实际对调度没有参考价值。
解决:严格按论文的出力时段截断数据,春季夏季取 07:00-19:00,秋季取 08:00-19:00,冬季取 09:00-19:00。预测和评估都在截断后的时段内进行,不在序列里保留零功率时段。我一般还会把每天的日出日落时间算出来,动态裁剪出力时段,比固定时段更精准。
5.2 晴天的样本主导训练,阴雨天预测误差直接爆表
现象:训练集误差很低,但把模型放到阴雨天预测时,预测值明显偏高,曲线形态完全对不上。
原因:光伏电站历史数据中晴天占比高,BP 网络在训练时对晴天样本的拟合权重自然更大。MEA 的得分函数又是训练集均方误差的倒数,全局寻优同样被晴天样本主导。
解决:如果只按季节分组,至少要检查每个季节预测单元内晴天和阴雨天的样本比例。比例失衡时,可以按天气类型做加权采样,让阴雨天样本参与训练的概率提高。论文没有做这一步,因为 80 组数据再做天气分层会导致每类样本过少,但如果你有更长周期的数据,这个操作值得加。另一个补救方法是针对阴雨天单独建一个临时模型,用相似日方法选出与预测日天气类型最接近的历史样本做局部预测。
5.3 弃光限电期间的数据混入训练,模型学到了「假规律」
现象:预测曲线在部分时段被系统性压低,和真实功率偏差大,而且误差集中在每天的同一时段。
原因:论文图 7 里秋季和冬季曲线标出了「弃光限电」现象,在弃光时段电站实际输出被人为限制,远低于理论可发功率。如果这些数据直接进训练集,BP 网络会学到「这个时段功率本来就低」的错误规律。
解决:识别弃光时段的简单方法是用辐照度估算理论功率上限,如果实际功率持续明显低于理论功率且曲线呈平台状,标记为弃光时段。训练时要么剔除这些样本,要么把对应时段的输出值替换为理论计算值。用 MEA-BP 训练时同样要注意,得分函数不会区分弃光样本和正常样本,数据不进训练集才是根本解。
5.4 MEA 参数照抄导致子群体退化,收敛后精度反而不如随机初始化
现象:复现时直接套用论文的种群 2000、子群体 100、迭代 50 次,算法收敛很快,但预测精度波动很大,有时还不如直接跑 BP。
原因:网络拓扑和论文不同,编码长度变了,但 MEA 参数没变。编码长度从 508 变成 1000 以上时,2000 个种群个体在高维空间里非常稀疏,子群体内部的趋同操作搜不到有效区域,异化操作频繁解散子群体,算法提前收敛到较差的局部最优。
解决:参数调整遵循两个原则。一是维持整除关系:种群规模 = 子群体数量 × 子群规模,论文是 2000 = 200 × 10;当编码长度变长,优先加大子群规模到 15 或 20,同时减少子群体数量。二是看收敛曲线:如果得分在 10 轮迭代内就不再提升,说明搜索空间和种群规模不匹配,加大种群规模比加大迭代次数更有效。我自己的习惯是先跑一次种群 5000 的粗搜索,观察得分收敛情况,再回退到资源允许的最小规模,省时间也省内存。
6. 结果验证:用 MAE、MAPE、RMSE 判断模型是否真的变好了,以及逐时刻误差的三种分析角度
论文表 3 把四个季节、三种模型(本地预测系统、BP、MEA-BP)的逐时刻 3 d 平均绝对误差列成了矩阵,表 4 给出了每个预测单元的 MAPE 和 RMSE。看表 4 的数据,本地预测系统的平均 MAPE 高达 125.332%,基本没有参考价值;BP 网络平均 MAPE 32.014%,RMSE 7.714 MW;MEA-BP 平均 MAPE 15.12%,RMSE 3.8 MW。MAPE 从 32% 降到 15%,RMSE 接近腰斩,这个提升幅度在光伏短期预测里是显著的。
但只看平均值会掩盖很多问题。我一般会从三个角度拆解误差结果:
第一个角度是逐时刻 MAE 的时段分布。从表 3 可以看到,MEA-BP 网络在一天中的非峰值时段误差很小,比如春季 10:00 的误差只有 0.039 MW,而 07:00 和 19:00 的误差相对偏大。原因很简单,早晚时段功率从 0 爬升或下降到 0,斜率大,模型对陡峭变化的拟合能力天然偏弱。如果某个时段的误差明显高于相邻时段,优先检查那个时段的数据质量,再看是否需要增加输入特征。
第二个角度是误差的绝对值与相对值分离。MAPE 在低估场景下会失真——当实际功率很低,比如傍晚时段的 2 MW,预测值偏差 0.5 MW,相对误差就是 25%,看着很难看,但对电网调度来说这个绝对偏差完全可接受。所以评估模型时 MAPE 和 RMSE 要一起看,MAPE 反映相对精度,RMSE 反映大误差的惩罚力度,两者都下降才算真正的改进。
第三个角度是对比「弃光时段」和「正常时段」的误差差异。论文里秋季和冬季出现了弃光限电,本地预测系统在那几天的预测偏差明显更大。如果你复现时在数据清洗阶段已经剔除了弃光样本,那评估时也要把弃光时段从测试集中去掉,或者单独统计,否则预测模型在正常时段的真实精度会被弃光时段的偏差拖累。我在做项目评估时会在结果表里加一列「非弃光时段误差」,专门用来向调度侧说明模型在正常工况下的能力。
最后一个建议:把 BP 网络和 MEA-BP 的预测曲线画在同一张图上,逐点对齐。论文的图 7 就是这个做法,能直观看到 MEA-BP 对功率峰值的追逐比 BP 更紧。从那以后我每次复现类似改进神经网络的论文,都会强制走一遍「数据清洗 → 时段截断 → 归一化 → MEA 搜索 → BP 精调 → 逐时刻误差分析」的流程,哪怕结论已经写在论文里也要自己跑一次,毕竟只有亲手画出那条误差曲线,才知道哪些提升是算法带来的、哪些只是数据清洗的功劳。希望这个流程和这里拆出的参数细节能帮到你。
本文还有配套的精品资源,点击获取