EMD-SVM 太阳能功率预测

含数据读取→EMD 分解→SVM 回归→多步预测→结果保存/绘图,完成 EMD-SVM 太阳能功率预测
基于 15 min 采样光伏功率 + 4 维气象数据


一、文件结构

EMD_SVM_Solar/  
├─ main.m                % 主脚本  
├─ emd_decomp.m          % 调用 EMD 分解  
├─ build_train_svm.m     % 训练 SVM 子函数  
├─ forecast_svm.m        % 滚动预测子函数  
├─ calc_metrics.m        % 计算 MAPE/RMSE/R²  
├─ data/  
│  ├─ solar_power.xlsx   % 时间序列功率  
│  └─ weather.xlsx       % 同期气象数据  
└─ results/              % 输出图、指标表  

二、数据格式

  • solar_power.xlsx
    列 A:时间(yyyy-mm-dd HH:MM:SS)
    列 B:功率(MW)

  • weather.xlsx
    列 A-D:辐照度(W/m²)、温度(°C)、风速(m/s)、湿度(%)

(数据须对齐、无缺失;如缺失请先插值。)


三、核心代码

  1. main.m —— 一键运行
%% 1. 读数 & 归一化
clear; clc; close all;
power = readmatrix('data/solar_power.xlsx','Range','B:B');
meteo = readmatrix('data/weather.xlsx');          % 4×N
N = length(power);

% 归一到 [0,1]
power = (power - min(power)) / (max(power) - min(power));

%% 2. EMD 分解
[IMFs, res] = emd_decomp(power);          % 返回 cell 数组
K = numel(IMFs);                          % IMF 个数

%% 3. 构造监督数据集
lag = 24;   % 用过去 6h 预测下一步
[X, Y] = deal(cell(K,1));                 % 每个 IMF 独立
for k = 1:K
    [X{k}, Y{k}] = buildData(IMFs{k}, meteo, lag);
end

%% 4. 训练/验证/测试划分
ratio = [0.7 0.15 0.15];
idx = splitData(N-lag, ratio);

mdl = cell(K,1);
for k = 1:K
    mdl{k} = build_train_svm(X{k}(idx.train,:), Y{k}(idx.train));
end

%% 5. 测试集滚动预测
horizon = 96;   % 预测未来 24h
pred = zeros(horizon, K);
lastWin = cellfun(@(x) x(end-lag+1:end), IMFs, 'uni', 0);
meteoFut = meteo(end-horizon+1:end, :);   % 假设已知未来气象

for t = 1:horizon
    for k = 1:K
        feat = [lastWin{k}'; meteoFut(t,:)'];
        pred(t,k) = predict(mdl{k}, feat');
        lastWin{k}(1:end-1) = lastWin{k}(2:end);
        lastWin{k}(end) = pred(t,k);
    end
end
yhat = sum(pred,2);                       % 反归一化前
yhat = yhat*(max(power)-min(power))+min(power);

%% 6. 评估 & 绘图
ytrue = readmatrix('data/solar_power.xlsx','Range', sprintf('B%d:B%d', N-horizon+2, N+1));
figure; plot(ytrue,'b'); hold on; plot(yhat,'r--');
legend('真实','预测'); xlabel('采样点'); ylabel('功率 MW');
title(sprintf('EMD-SVM 未来 24h 预测\\nMAPE=%.2f%%',calc_metrics(ytrue,yhat)));

writematrix([ytrue, yhat],'results/pred24h.csv');
  1. emd_decomp.m —— 调用 MATLAB 内置 emd
function [IMFs, res] = emd_decomp(sig)
    [IMFs, res] = emd(sig,'MaxNumIMF',8,'Display',0);
    IMFs = mat2cell(IMFs, size(IMFs,1), ones(1,size(IMFs,2)));
end
  1. buildData.m —— 生成监督样本
function [X, y] = buildData(sig, meteo, lag)
    N = numel(sig);
    X = []; y = [];
    for t = lag:N-1
        X = [X; [sig(t-lag+1:t)'  meteo(t+1,:)]]; %#ok<AGROW>
        y = [y; sig(t+1)];
    end
end
  1. splitData.m —— 时序划分
function idx = splitData(N, ratio)
    trainN = floor(N*ratio(1));
    valN   = floor(N*ratio(2));
    idx.train = 1:trainN;
    idx.val   = trainN+1:trainN+valN;
    idx.test  = trainN+valN+1:N;
end
  1. build_train_svm.m —— 训练 ε-SVR(RBF)
function mdl = build_train_svm(X, y)
    % 网格搜索 [C,gamma](可换成贝叶斯优化)
    C_set   = 2.^(-2:2:8);
    g_set   = 2.^(-5:2:3);
    best = struct('mse',Inf);
    for C = C_set, for g = g_set
            mdl = fitrsvm(X, y, 'KernelFunction','rbf', ...
                          'KernelScale',1/g, 'BoxConstraint',C, ...
                          'Standardize',true);
            yhat = predict(mdl, X);
            mse = mean((y-yhat).^2);
            if mse < best.mse, best = struct('mdl',mdl,'mse',mse); end
    end, end
    mdl = best.mdl;
end
  1. calc_metrics.m —— 指标计算
function mape = calc_metrics(ytrue, yhat)
    mape = mean(abs((ytrue-yhat)./ytrue))*100;
    fprintf('RMSE=%.3f MW, R²=%.3f\n', ...
            sqrt(mean((ytrue-yhat).^2)), 1-var(ytrue-yhat)/var(ytrue));
end

四、运行步骤

  1. 将两份 Excel 放入 data/ 目录。

  2. 在 MATLAB 命令行执行

    >> addpath(genpath(pwd));
    >> main
    
  3. 结束后可在 results/ 查看

    • pred24h.csv(两列:真实 | 预测)
    • 自动弹出的对比图。

参考代码 实现emd的分解并利用svm预测 www.youwenfan.com/contentcsk/113013.html

五、可扩展提示

  • 模态混叠 → 改用 CEEMDAN(ceemdan 函数)。
  • 高维气象 → 先用 PCA 降维,再送入 SVM。
  • 超参搜索慢 → 用 bayesopt 替代网格搜索。
  • 长期预测 → 将 SVM 替换为 LSTM,保持 EMD 分解框架。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值