ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

分布式光伏功率预测实战:EMD-PCA-LSTM与气象因子处理

分布式光伏功率预测实战:EMD-PCA-LSTM与气象因子处理 简介面向光伏发电功率预测与电力系统调度研究需求该资源提供一套完整的分布式光伏发电计及气象因子与出力预测方法的研究包。重点给出基于经验模态分解EMD、主成分分析PCA与长短期记忆神经网络LSTM组合的光伏功率预测模型可帮助研究人员复现并改进多气象因子影响下的功率预测实验。包体共8个文件包含4个MATLAB脚本负责分解、特征提取、训练与预测等核心流程、3个.mat数据文件提供风速、温度、风向及发电功率等实测样本另有1个内嵌子压缩包整体仅116KB小巧便携。目前已有208人学习下载适合电力系统、新能源方向的高年级本科生与研究生用于论文复现、算法对比或课程设计。通过该包可快速掌握EMD降噪、PCA降维与LSTM时序建模在光伏出力预测中的完整代码实现并结合实测数据验证模型精度。1. 分布式光伏发电计及气象因子及出力预测这份 zip 里到底装了什么做分布式光伏发电计及气象因子及出力预测最磨人的往往不是选哪个网络而是数据进模型之前那些看不见的坑。这份资源是一套完整可跑的 MATLAB 实现用经验模态分解EMD把风速、温度这类非平稳环境序列拆成多尺度分量接着用 PCA 去冗余再用 LSTM 做动态时间建模数据来自山西某电站 8 个月的 5 分钟级实采。包里直接给出风速、温度、功率三份序列、三个输入组合不同的训练脚本和一个指标评估脚本。适合做电力预测毕设的学生、想快速搭功率预测 baseline 的算法工程师以及要在调度侧评估误差的从业者。它直接解决的问题是气象因子以什么顺序、什么形式进模型以及评估结果怎么算才不翻车。2. 数据与脚本结构五个 .mat 加四个 .m先对清单再动手2.1 文件清单与变量约定跑之前先 whos 一遍文件内容关键变量/单位用途gonglv5min.mat5 分钟功率序列P 或 gonglv5minkW预测目标fengsu5min.mat5 分钟风速V 或 fengsu5minm/s环境特征wendu5min.mat5 分钟温度T 或 wendu5min℃环境特征yucemin5.m纯功率滞后特征训练脚本—基线模型yucemin5_fengxiang.m加入风向的训练脚本—单因子对比yucemin5fengsuwendufengxiang.m风速温度风向全特征脚本—完整模型zhibiao.m性能指标计算脚本MAE/RMSE/MAPE/R²评估不同版本的包里变量名可能不一样第一次跑别急着改代码先load之后用whos看变量名、类型和 size再决定要不要统一。另外清单里没有独立的 fengxiang5min.mat但两个脚本名都带_fengxiang第一次跑大概率会卡在「风向数据在哪」这个问题上。打开脚本看前几行的load和赋值语句就能确认来源如果包里的 mat 确实没带风向变量常见做法是把风向编码成 sin/cos 两个分量补进特征或者用同一时间轴的辐照度替代别直接删掉这路特征。风向对上午、下午不对称的出力曲线是有解释力的只是权重需要让模型自己去学。2.2 读数与时间轴对齐七万行数据先排好队% 先确认变量名再统一成列向量 load(gonglv5min.mat); load(fengsu5min.mat); load(wendu5min.mat); % 常见变量名P / gonglv5min, V / fengsu5min, T / wendu5min P gonglv5min(:); V fengsu5min(:); T wendu5min(:); % 以最短序列为准截断避免维度不匹配 n min([numel(P), numel(V), numel(T)]); P P(1:n); V V(1:n); T T(1:n); % 检查缺失值和异常值 fprintf(样本数 %dNaN 行数 %d\n, n, sum(isnan(P)|isnan(V)|isnan(T))); % 5 分钟采样8 个月约 288*244 ≈ 7 万个点逻辑说明(:)把行向量或矩阵强制转成列向量防止后面横向拼接时报维度错min截断是最省事的对齐方式代价是丢掉长序列尾部几十个点对七万样本量来说无影响。参数上5 分钟粒度意味着一天 288 个点8 个月约七万点这个体量喂给 LSTM 训练时间完全可接受。isnan检查是必做项采集端掉点通常表现为 NaN 或 0先查清楚再填。注意如果发现 NaN 超过总样本的 0.1%不要用 fillmissing 直接填先核对是不是时间戳错位导致整段值偏移这种情况填了等于造假。2.3 三个训练脚本怎么分工消融实验已经帮你排好三个脚本的输入端不同yucemin5.m 只用功率历史值不含任何气象因子yucemin5_fengxiang.m 在功率基础上加风向yucemin5fengsuwendufengxiang.m 加全量气象特征。这就是一套现成的消融实验最终评估时把三者都跑完对比 zhibiao.m 的输出就能量化每个气象因子的边际贡献。% 构造监督学习样本过去 lookback 个时刻预测未来 horizon 个时刻 lookback 12; % 12 个 5 分钟点 1 小时 horizon 1; % 预测未来 5 分钟 seqs {}; y []; for k lookback1 : n-horizon1 feat [P(k-lookback:k-1); V(k-lookback:k-1); T(k-lookback:k-1)]; seqs{end1} feat; % 3×lookback 的特征矩阵 y(end1) P(khorizon-1); end % LSTM 输入格式每个样本是 numFeatures×numTimeSteps 的矩阵 % trainNetwork 接收 cell 数组每个 cell 一个样本参数说明lookback是记忆窗口取 12 对应 1 小时太短学不到日周期太长样本数变少且训练变慢常见取 6/12/24 三档对比horizon1是单步预测改成 12 就是直接预测 1 小时后误差会明显放大一般先用单步验证模型结构对不对。feat的行是特征功率、风速、温度列是时间步这个维度顺序不能反sequenceInputLayer默认要求「特征 × 时间步」拼反了训出来的模型完全不可用。3. EMD 分解与 PCA 降维把非平稳序列拆成 LSTM 吃得下的形状3.1 EMD 解决什么问题非平稳序列为什么会让 LSTM 白学5 分钟功率序列里云层遮挡造成分钟级高频波动天气过程带来小时级中频成分日升日落是 24 小时周期这些叠加在一起就是典型非平稳信号。LSTM 的遗忘门擅长记规律但面对均值、方差随时间漂移的序列容易把短期波动当成规律硬拟合训练集指标不错换个天气状况立刻失灵。EMD 的价值在于它自适应地把序列拆成若干个本征模态函数IMF加一个残差IMF 按频率从高到低排列高频 IMF 对应云层快速变化低频 IMF 加残差对应日周期和季节趋势。每个分量都平稳一些之后再去组建模LSTM 学到的才是相对稳定的映射关系。提示EMD 不需要预设基函数不像小波分解要纠结小波基和分解层数这是它在这类气象序列上比小波更省心的原因。3.2 EMD 在 MATLAB 里的调用方式与参数% MATLAB R2018a 之后自带 emd更老的版本需要第三方工具包 [imf_V, resid_V] emd(V, MaxNumIMF, 8); % imf_V 是矩阵每一列一个 IMF列数由数据自适应决定 size(imf_V) % 看一眼拆出来几列 % 逐列 plot 观察分量尺度前几列高频后几列加残差是低频趋势逻辑说明emd内部通过三次样条包络迭代筛分返回的imf_V每列对应一个分量resid_V是最后的单调残差。MaxNumIMF8限制最多拆 8 个分量防止把纯噪声也拆成独立 IMF默认拆出数量取决于序列复杂度8 个月的数据一般落在 5 到 8 个。另一个常用参数SiftRelativeTolerance, 0.01控制筛分停止阈值默认值多数场景够用不用迷信论文里写的 0.05 或 0.001。分解前对序列两端做镜像延拓能有效抑制端点发散这个坑单独放在避坑章节展开。3.3 PCA 降维特征从二十几维回到个位数摘要里说的 5 种环境因素每个序列经 EMD 拆出 5 到 8 个 IMF拼在一起特征总数直接到 20 以上。但相邻 IMF 之间存在相关性比如风速的高频分量和功率的高频分量在云层场景下是同步波动的直接喂给 LSTM 既冗余又容易过拟合这时候 PCA 的价值就出来了。% 假设三个环境序列都已 EMD 分解拼成特征矩阵 F [imf_V, imf_T, imf_dir]; % imf_dir 来自风向序列分解 % 标准化PCA 对量纲敏感风速和温度单位不同不能直接混算 F (F - mean(F)) ./ std(F); [coeff, score, ~, ~, explained] pca(F); cumvar cumsum(explained); k find(cumvar 95, 1); % 累计方差贡献率到 95% F_pca score(:, 1:k); % 降维后的特征矩阵 fprintf(主成分数量: %d, 累计贡献率: %.2f%%\n, k, cumvar(k));参数说明explained是每个主成分解释的方差百分比cumsum累加后取第一个超过 95% 的位置k。95% 是功率预测场景里的常见阈值想严格一些取 98% 会保留更多原始信息但对抑制过拟合帮助不大数据噪声大时 90% 也能用。score是投影后的主成分得分后续 LSTM 输入用的是score(:,1:k)而不是coeff这两个变量搞反是新手常犯的错。PCA 只对特征矩阵做功率序列单独标准化否则会泄漏预测目标信息具体后果在避坑章节第四条细说。3.4 LSTM 结构与超参复现时按这个起点调numFeatures size(F_pca, 1); % 降维后的特征维度 numHidden 64; layers [ sequenceInputLayer(numFeatures) lstmLayer(numHidden, OutputMode, last) fullyConnectedLayer(1) regressionLayer]; options trainingOptions(adam, ... MaxEpochs, 80, ... MiniBatchSize, 64, ... InitialLearnRate, 0.001, ... LearnRateSchedule, piecewise, ... LearnRateDropFactor, 0.5, ... LearnRateDropPeriod, 20, ... Plots, training-progress, ... Verbose, 0); net trainNetwork(seqs, y, layers, options);逻辑说明seqs是第 2.3 节组好的 cell 数组y是对应的功率目标列。OutputMode,last表示只输出序列最后一个时刻的结果正好匹配单步预测如果改成预测未来多步要把输出模式换成sequence并调整输出层结构。numHidden从 64 起步数据量大可以试 128但要配合lstmLayer里的Dropout,0.2防止过拟合hidden units 往上加不一定更好这个参数很多时候是玄学。InitialLearnRate0.001是 Adam 的标准起步值loss 震荡就降到 3e-4LearnRateDropPeriod20表示每 20 个 epoch 学习率减半配合MaxEpochs80正好在训练后期精细收敛。训练时把ValidationData指到时间上靠后的验证集盯着验证 loss 判断过拟合比只看训练曲线可靠得多。3.5 三种特征输入的预期差异这个包自带的三个脚本已经把对比实验排好了。按常见经验纯功率基线在晴天表现尚可阴雨天因为缺少外部信息误差明显放大加风向的版本在 5 分钟级预测里贡献通常弱于风速和温度风向对出力的影响更多体现在小时级以上尺度加风速和温度后RMSE 一般能比基线降 8% 到 15%。但这个数字依赖电站的地理位置和季节摘要只给了「更高的精确度」这个定性结论具体收益在自己数据上跑完 zhibiao.m 才能确认别拿论文里的数字当自己的验收标准。4. 避坑与排查五条实测记录从时间对齐到误差计算4.1 时间轴与数据质量的两个坑坑 1horzcat 报维度不匹配或者训练到一半 loss 变 NaN。现象把风速、温度横向拼进特征矩阵时直接报错或者训练前几个 epoch 正常某次迭代后 loss 变成 NaN 且不再恢复。原因5 分钟级数据在采集端掉点三个 .mat 的样本数差几十到几百行另一个常见原因是某列变量从 mat 里读出来是行向量1×n横向拼接时形状对不上。解决先whos确认每个变量的 size统一用(:)转列向量以最短序列截断或者用interp1把差值的序列重采样到统一时间轴对 NaN 用fillmissing(P,previous)前向填充。千万别对功率序列做平滑滤波云层遮挡的陡降是模型要学的有效信息平滑掉等于给模型作弊。坑 2shuffle 时间序列验证集指标漂亮得不像话。现象训练时随机打乱样本验证集 R² 能到 0.98模型部署到下一周数据上 R² 掉到 0.8 以下。原因相邻 5 分钟样本之间高度自相关shuffle 之后训练集和验证集里混着彼此的近邻样本模型在验证集上相当于做插值而不是预测这是典型的时序泄漏。解决严格按时间顺序切分前 6.5 个月训练、后 1.5 个月验证trainingOptions里设置Shuffle,never。LSTM 的输入是 cell 数组打乱 cell 之间的顺序影响不大但打乱 cell 内部的时间步顺序等于破坏序列结构数据构造那一步就要保证时间有序。4.2 EMD 与 PCA 的两个坑坑 3EMD 端点飞翼导致首尾误差爆炸。现象分解出的第一个 IMF 在序列两端出现大幅摆动幅值比中间高一个量级预测结果在测试集开头和结尾段误差明显大于中间段。原因EMD 的包络估计用三次样条插值端点处没有数据约束样条包络在边界发散端点效应会沿迭代过程向内传播。解决分解前做镜像延拓把序列两端各翻转 200 个点左右接到头尾分解完丢掉延拓段或者训练时只取中间 90% 的数据预测时对输出段做过渡加权。另一个思路是控制MaxNumIMF分量少时端点效应传播范围相对小多试几个取值对比首尾段的误差。坑 4把功率序列混进 PCA预测峰值被削平。现象预测曲线整体滞后于真实值峰值明显被削平RMSE 比不做 PCA 还高。原因PCA 对特征做线性组合时功率序列里日周期主导的方差会吃掉主成分中环境因子的分量气象信息被当成冗余丢掉同时降维过程隐式用到了功率信息相当于特征构造阶段的标签泄漏。解决PCA 只作用于环境因子特征矩阵功率序列单独做标准化主成分数量用累计方差贡献率动态选择不拍脑袋定成 2 或 3。检查方法很简单投影后看前几个主成分的载荷系数如果第一个主成分和功率序列的相关性异常高说明构造阶段混入了目标信息。4.3 评估口径的一个坑坑 5MAPE 在夜间功率接近零时爆炸。现象整体 MAPE 报出来 20% 出头细看夜间段贡献了其中 90% 的误差白天晴天段 MAPE 其实只有 6% 左右。原因MAPE 的分母是真实功率夜间功率趋近 0几 kW 的绝对误差除以接近 0 的功率得到几百个百分点的相对误差直接把整体指标带崩。解决评估时分段统计只对P 0.1 * max(P)的样本算 MAPE主指标换成 MAE 和 R²MAPE 作为辅助参考。zhibiao.m 里如果直接算 MAPE建议加 epsilon 保护mape mean(abs((y_pred-y_true)./(y_trueeps)))eps 取 1 或 0.1 倍最大功率都行量纲不同选法不同自己心里有数即可。5. 验证与落地技巧用 zhibiao.m 评估再改成滚动多步预测5.1 zhibiao.m 怎么用四个指标一起看% 预测完成后把反归一化后的 y_pred 和 y_true 传入评估 % 如果 zhibiao.m 是脚本先看内部约定的变量名对齐再运行 [mae, rmse, mape, r2] zhibiao(y_true, y_pred); fprintf(MAE%.2f kW | RMSE%.2f kW | MAPE%.2f%% | R2%.4f\n, ... mae, rmse, mape*100, r2);逻辑说明误差计算必须在物理量纲下做。如果网络输出是 [0,1] 归一化值先反归一化回 kW 再调 zhibiao.m。四个指标各有侧重MAE 反映平均偏差水平RMSE 放大峰值误差MAPE 看相对百分比R² 看整体拟合度单独看任何一个都可能误判。比如 RMSE 高但 MAE 低说明误差集中在少数尖峰时刻这时候要查是不是云层遮挡样本。5.2 滚动多步预测把单步模型变成小时级预测steps 12; % 预测未来 12 个 5 分钟点即 1 小时 window seqs{end}; % 最后一段历史特征尺寸为 特征×lookback preds zeros(steps, 1); for s 1:steps preds(s) predict(net, {window}); % 单步预测 window [window(:, 2:end), preds(s)*ones(size(window,1),1)]; % 滚动窗口丢掉最旧时刻拼入新预测值 end参数说明滚动窗口保持lookback长度不变每预测一步就把最旧时刻丢出去换成模型自身的预测值。这里有个明显的累积误差效应第 1 步 RMSE 最小第 12 步通常放大 2 到 3 倍这是闭环预测的正常现象。代码里直接拿预测值拼窗口是简化写法严格做法是把新预测值放回原始特征空间重新走一遍标准化和 PCA 投影再拼回窗口这样特征分布才一致。想改善多步精度常见做法是训练时用 teacher forcing 或者在损失函数里对远期步长加权。从那以后我每次拿到这类功率预测数据都强制走一遍「时间对齐 → 时序切分 → EMD 端点检查 → 误差反归一化」四步再谈模型选型这套流程救过我好几次希望帮到你。本文还有配套的精品资源点击获取
返回列表