小波神经网络(WNN)用于电力负荷预测—(MATLAB)

1) 小波神经网络 概念

对小波神经网络最常用、最好训练的形式是 小波基函数网络(Wavelet Basis Network)

y^(t)=P^(t)=∑k=1Kwk⋅ψ ⁣(zk−bkak)+w0\hat y(t)=\hat P(t)=\sum_{k=1}^{K} w_k\cdot \psi\!\left(\frac{z_k-b_k}{a_k}\right)+w_0y^(t)=P^(t)=k=1∑Kwk⋅ψ(akzk−bk)+w0

  • (ψ(⋅)\psi(\cdot)ψ(⋅)):母小波(一般选 Morlet 最稳)
  • (zkz_kzk):进入第 (kkk) 个小波节点的输入向量分量(通常就是某维特征,或线性组合)
  • (ak>0a_k>0ak>0):尺度,(bkb_kbk):平移
  • (wk,w0w_k,w_0wk,w0):线性输出权

直觉:它不是去"小波变换后再接 NN",而是把小波当成一种带尺度/平移的可学习基函数,网络通过学习 ((a_k,b_k,w_k)) 来拟合负荷的非线性周期性。

本文示例使用 一维输入版(每一维输入各自进自己的小波节点,结构简单、稳定),你要升级到"(z=W x) 线性组合版"我也可以补。


2) 电力负荷预测:怎么把问题做成监督学习

设负荷序列为 (P(1),P(2),...,P(N)P(1),P(2),\dots,P(N)P(1),P(2),...,P(N)),采样间隔=1h(或15min,同理)。

(1) 经典单步预测输入向量

x(t)=[P(t−1),P(t−2),...,P(t−L),D(t),H(t),1weekend(t))\mathbf{x}(t)= \big[P(t-1),P(t-2),\dots,P(t-L), D(t),H(t), \mathbb{1}_{\text{weekend}}(t) \big)x(t)=[P(t−1),P(t−2),...,P(t−L),D(t),H(t),1weekend(t))

  • 历史负荷:(L=24L=24L=24)(小时)或 (96)(15min)
  • 日历特征:日编号 (D)、小时编号 (H)、周末/节假日指示
  • 温度/天气:能拿到就加(效果提升很大)

输出:(P^(t)=f(x(t))\hat P(t)=f(\mathbf{x}(t))P^(t)=f(x(t)))

(2) 归一化

建议用滑动窗口 z-score 或 min-max,这里先用简单 min-max:

matlab 复制代码
Pn = (P - min(P))/(max(P)-min(P)+eps);

负荷预测里别把未来信息泄露进归一化(即不要用全局 future max/min 去归一化 test 段),工程上常见做法是:用 train 段统计做映射,test 段 clip。


3) 小波(Morlet)定义与网络前向

Morlet 母小波(复小波取实部即可):

ψ(u)=cos⁡(5u) exp⁡ ⁣(−u2/2)\psi(u)= \cos(5u)\,\exp\!\big(-u^2/2\big)ψ(u)=cos(5u)exp(−u2/2)

前向计算(单样本 (x∈Rdx\in\mathbb{R}^dx∈Rd),这里让每个小波只吃一个维度 (x(j)x(j)x(j)),最稳):

  • 假设有 (KKK) 个小波节点,且 (K=d×mK = d\times mK=d×m)(每层维度 (mmm) 个 ((a,b)(a,b)(a,b)))
  • 对第 (j=1..dj=1..dj=1..d) 维输入,对应小波组 (k=(j−1)m+1..jmk=(j-1)m+1 .. jmk=(j−1)m+1..jm)

u=(x(j)−bk)/ak,hk=ψ(u)u = (x(j)-b_k)/a_k,\quad h_k=\psi(u)u=(x(j)−bk)/ak,hk=ψ(u)

  • 输出

y^=w0+∑k=1Kwk hk\hat y = w_0 + \sum_{k=1}^{K} w_k\,h_ky^=w0+k=1∑Kwkhk


4) MATLAB:可运行的最小 Demo(单步预测 + MAPE/RMSE)

这是原理级可复现代码(不是调库),你可以直接贴进 MATLAB 跑通,再换成你的真实负荷 CSV。

matlab 复制代码
%% ========= 1. 数据:造一条"有日周期+周末+噪声"的负荷 =========
Fs = 24;                % 24点/天
N  = 14*Fs;             % 14天
t  = (1:N)';

base = 100*ones(N,1);
daily = 30*(0.5+0.5*cos(2*pi*(t-7)/24));          % 日间高峰
week = 15*(mod((1:N)'-1,7)>=5);                    % 周末抬升
P = base + daily + week + 5*randn(N,1);            % 负荷
P = max(P,50);

% 可视
figure; plot(t,P); grid on; title('Synthetic Load'); xlabel('hour index');

%% ========= 2. 构造监督样本(lag-24 单步预测)=========
L = 24;                 % 历史长度
D = L + 2;              % 输入维:24负荷 + hour + weekend_flag

X = []; Y = [];
for i = (L+1):N
    hist = P(i-L:i-1);
    hr   = mod(i-1,24)/24;                  % 小时归一化到 [0,1]
    we   = double(mod(i-1,7)==5 | mod(i-1,7)==6);
    xi   = [hist(:)./120 ; hr ; we];        % 简单归一化(你的真实数据再校准)
    X = [X; xi'];
    Y = [Y; P(i)];
end

% 输出也归一化(可选但更稳)
Ymean = mean(Y); Ystd = std(Y)+eps;
Y = (Y-Ymean)/Ystd;

%% ========= 3. 训练/测试切分(前70%训练)=========
n = size(X,1);
ntr = floor(0.7*n);
Xtr = X(1:ntr,:); Ytr = Y(1:ntr);
Xte = X(ntr+1:n,:); Yte = Y(ntr+1:n);

%% ========= 4. 初始化 WNN(Morlet 小波基)=========
d = size(X,2);         % 输入维
m = 2;                 % 每个维的小波个数(可调)
K = d*m;               % 总小波节点

% 参数打包:theta = [a(:); b(:); w(:); w0]
a0 = 0.5+0.3*rand(K,1);% 尺度
b0 = rand(K,1);        % 平移(建议用输入统计量初始化更好)
w0 = randn(K,1)*0.1;
w00= 0;
theta0 = [a0;b0;w0;w00];

psi = @(u) cos(5*u).*exp(-u.^2/2);   % Morlet(实部)

% ---------- 前向 ----------
function [y, H, Jac] = wnn_forward(X, theta, d, m)
    K = d*m;
    a = theta(1:K); b = theta(K+1:2*K); w = theta(2*K+1:3*K); w0 = theta(end);
    Ns = size(X,1);
    H  = zeros(Ns,K);
    for i=1:Ns
        idx=0;
        for j=1:d
            for r=1:m
                k=idx+r;
                u=(X(i,j)-b(k))/a(k);
                H(i,k)=psi(u);
            end
            idx=idx+m;
        end
    end
    y = H*w + w0;
    % Jacobian wrt theta(数值也行,但解析更稳定)
    Jac = []; % 你把解析导放这里,或下面用数值Jacobian(见训练)
end

% ---------- 目标函数(带一点正则)==========
lambda = 1e-4;
fun = @(th) wnn_obj(th, Xtr, Ytr, d, m, lambda, psi);

%% ========= 5. 训练:Levenberg-Marquardt(推荐)=========
opts = optimoptions('lsqnonlin',...
    'Algorithm','levenberg-marquardt',...
    'Display','iter',...
    'MaxIterations',120,...
    'StepTolerance',1e-8);

[theta_hat,~,res] = lsqnonlin(fun, theta0,[],[],opts);

%% ========= 6. 推理 + 反归一化 + 指标 =========
pred_tr = wnn_pred(Xtr, theta_hat, d, m, psi)*Ystd + Ymean;
pred_te = wnn_pred(Xte, theta_hat, d, m, psi)*Ystd + Ymean;

Ytr_true = Ytr*Ystd + Ymean;
Yte_true = Yte*Ystd + Ymean;

fprintf('TRAIN MAPE=%.2f%%  RMSE=%.3f\n',mape(Ytr_true,pred_tr),rmse(Ytr_true,pred_tr));
fprintf('TEST  MAPE=%.2f%%  RMSE=%.3f\n',mape(Yte_true,pred_te),rmse(Yte_true,pred_te));

figure; plot(Yte_true,'k'); hold on; plot(pred_te,'r--'); grid on;
legend('True','WNN Forecast'); title('WNN Load Forecast (Test)');

%% ========= 工具函数 =========
function F = wnn_obj(th, X, Y, d, m, lam, psi)
    K = d*m;
    a=th(1:K); b=th(K+1:2*K); w=th(2*K+1:3*K); w0=th(end);
    Ns=size(X,1); E=zeros(Ns,1);
    for i=1:Ns
        s=w0;
        idx=0;
        for j=1:d
            for r=1:m
                k=idx+r;
                u=(X(i,j)-b(k))/a(k);
                s=s + w(k)*psi(u);
            end
            idx=idx+m;
        end
        E(i)=s-Y(i);
    end
    % 软正则(抑制权值爆炸)
    F = [E; sqrt(lam)*w; sqrt(lam)*(a-0.5)];
end

function y = wnn_pred(X, th, d, m, psi)
    K=d*m; a=th(1:K); b=th(K+1:2*K); w=th(2*K+1:3*K); w0=th(end);
    Ns=size(X,1); y=zeros(Ns,1);
    for i=1:Ns
        s=w0; idx=0;
        for j=1:d
            for r=1:m
                k=idx+r;
                u=(X(i,j)-b(k))/a(k);
                s=s+w(k)*psi(u);
            end
            idx=idx+m;
        end
        y(i)=s;
    end
end

function v=mape(a,b), v=mean(abs(a-b)./max(abs(a),1e-6))*100; end
function v=rmse(a,b), v=sqrt(mean((a-b).^2)); end

参考代码 用于小波神经网络电力负荷预测 www.youwenfan.com/contentcsv/81439.html

5) 你把它用到"真实电力负荷 CSV"

  1. 读入data = readtable('load.csv'); 拿到 P = data.Load; 与时间戳
  2. 做特征
    • hour = hour(timestamp)weekend = (weekday==6|7)
    • 有温度:x_temp = (T-20)/15
  3. 归一化要"训练统计→测试"(更规范)
  4. 输入维改成:[P(t-1)...P(t-L), hour_norm, weekend, temp_norm]
  5. 小波节点数先从 每维 m=2~4 试(K=d*m),过大会过拟合