小波神经网络(WNN)预测代码
小波神经网络(WNN)预测代码,结合了小波分析和神经网络的优势,适用于各种时间序列预测任务。
小波神经网络概述
小波神经网络结合了小波变换的多分辨率分析能力和神经网络的非线性映射能力,在预测领域表现出色。
特性 | 优势 | 适用场景 |
---|---|---|
多尺度分析 | 同时捕捉趋势和细节 | 非平稳时间序列预测 |
局部化特性 | 更好的时频局部化 | 突变点检测和预测 |
自适应学习 | 自动学习重要特征 | 复杂系统建模 |
完整的小波神经网络实现
1. 主函数框架
function [wnn_model, predictions, performance] = wnn_predict(train_data, test_data, varargin)
% 小波神经网络预测主函数
% 输入:
% train_data - 训练数据
% test_data - 测试数据
% varargin - 可选参数
% 输出:
% wnn_model - 训练好的WNN模型
% predictions - 预测结果
% performance - 性能指标
% 参数解析
p = inputParser;
addParameter(p, 'wavelet_type', 'db4', @ischar);
addParameter(p, 'decomposition_level', 3, @isnumeric);
addParameter(p, 'hidden_neurons', 10, @isnumeric);
addParameter(p, 'max_epochs', 1000, @isnumeric);
addParameter(p, 'learning_rate', 0.01, @isnumeric);
addParameter(p, 'goal', 1e-5, @isnumeric);
addParameter(p, 'show_window', false, @islogical);
parse(p, varargin{:});
params = p.Results;
fprintf('开始小波神经网络预测...\n');
fprintf('参数: 小波类型=%s, 分解层数=%d, 隐层神经元=%d\n', ...
params.wavelet_type, params.decomposition_level, params.hidden_neurons);
% 数据预处理
[processed_train, norm_params] = preprocess_data(train_data);
processed_test = normalize_data(test_data, norm_params);
% 小波分解
fprintf('进行小波分解...\n');
[wavelet_coeffs_train, wavelet_info] = wavelet_decomposition(...
processed_train, params.wavelet_type, params.decomposition_level);
% 构建训练样本
[X_train, Y_train] = create_training_samples(wavelet_coeffs_train);
% 训练小波神经网络
fprintf('训练小波神经网络...\n');
wnn_model = train_wnn_network(X_train, Y_train, params);
% 预测
fprintf('进行预测...\n');
predictions = wnn_predict_function(wnn_model, processed_test, wavelet_info, params);
% 反归一化
predictions = denormalize_data(predictions, norm_params);
% 性能评估
performance = evaluate_performance(test_data, predictions);
fprintf('预测完成!\n');
fprintf('RMSE: %.6f, MAE: %.6f, R²: %.4f\n', ...
performance.rmse, performance.mae, performance.r2);
end
2. 小波分解模块
function [wavelet_coeffs, wavelet_info] = wavelet_decomposition(data, wavelet_type, level)
% 小波分解
% 输入:
% data - 输入数据
% wavelet_type - 小波类型
% level - 分解层数
% 输出:
% wavelet_coeffs - 小波系数
% wavelet_info - 小波分解信息
if size(data, 2) > 1
% 多变量数据,分别处理每个变量
n_vars = size(data, 2);
wavelet_coeffs = cell(1, n_vars);
for i = 1:n_vars
[wavelet_coeffs{i}, wavelet_info] = decompose_single_series(...
data(:, i), wavelet_type, level);
end
else
% 单变量数据
[wavelet_coeffs, wavelet_info] = decompose_single_series(...
data, wavelet_type, level);
end
end
function [coeffs, info] = decompose_single_series(series, wavelet_type, level)
% 单序列小波分解
% 执行小波分解
[C, L] = wavedec(series, level, wavelet_type);
% 提取各层系数
coeffs = cell(1, level + 1);
coeffs{1} = appcoef(C, L, wavelet_type); % 近似系数
for i = 1:level
coeffs{i+1} = detcoef(C, L, i); % 细节系数
end
% 存储分解信息
info.C = C;
info.L = L;
info.wavelet_type = wavelet_type;
info.level = level;
info.original_length = length(series);
end
function [X, Y] = create_training_samples(wavelet_coeffs)
% 从小波系数构建训练样本
if iscell(wavelet_coeffs) && length(wavelet_coeffs) > 1
% 多变量情况
[X, Y] = create_multivariate_samples(wavelet_coeffs);
else
% 单变量情况
if iscell(wavelet_coeffs)
coeffs = wavelet_coeffs{1};
else
coeffs = wavelet_coeffs;
end
[X, Y] = create_univariate_samples(coeffs);
end
end
function [X, Y] = create_univariate_samples(coeffs)
% 单变量训练样本构建
n_levels = length(coeffs) - 1;
total_features = 0;
% 计算总特征数
for i = 1:length(coeffs)
total_features = total_features + length(coeffs{i});
end
% 构建特征矩阵和目标向量
n_samples = length(coeffs{1}) - 1; % 近似系数的长度减1
X = zeros(n_samples, total_features);
Y = zeros(n_samples, 1);
for i = 1:n_samples
feature_idx = 1;
% 近似系数特征
approx_features = coeffs{1}(i:i+1);
X(i, feature_idx:feature_idx+length(approx_features)-1) = approx_features;
feature_idx = feature_idx + length(approx_features);
% 细节系数特征
for j = 2:length(coeffs)
detail_coeff = coeffs{j};
if i <= length(detail_coeff)
X(i, feature_idx) = detail_coeff(i);
feature_idx = feature_idx + 1;
end
end
% 目标值 (下一个时间点的近似系数)
Y(i) = coeffs{1}(i+1);
end
% 移除全零行
valid_rows = any(X ~= 0, 2);
X = X(valid_rows, :);
Y = Y(valid_rows);
end
3. 小波神经网络核心
function wnn_model = train_wnn_network(X, Y, params)
% 训练小波神经网络
% 输入:
% X - 输入特征
% Y - 目标值
% params - 参数结构体
% 输出:
% wnn_model - 训练好的WNN模型
[n_samples, n_features] = size(X);
% 创建神经网络
net = fitnet(params.hidden_neurons, 'trainlm');
% 配置网络参数
net.divideParam.trainRatio = 0.7;
net.divideParam.valRatio = 0.15;
net.divideParam.testRatio = 0.15;
net.trainParam.epochs = params.max_epochs;
net.trainParam.lr = params.learning_rate;
net.trainParam.goal = params.goal;
net.trainParam.showWindow = params.show_window;
net.trainParam.showCommandLine = true;
% 使用小波函数作为激活函数(可选)
% 这里我们使用标准的sigmoid函数,但可以替换为小波函数
% 训练网络
fprintf('训练神经网络...\n');
[net, tr] = train(net, X', Y');
% 存储模型
wnn_model.net = net;
wnn_model.training_record = tr;
wnn_model.input_size = n_features;
wnn_model.output_size = size(Y, 2);
wnn_model.params = params;
% 计算训练性能
train_predictions = net(X');
train_performance = evaluate_performance(Y, train_predictions');
wnn_model.train_performance = train_performance;
fprintf('训练完成! 训练集RMSE: %.6f\n', train_performance.rmse);
end
% 自定义小波激活函数
function y = wavelet_activation(x, wavelet_type)
% 小波激活函数
switch wavelet_type
case 'mexican_hat'
y = (1 - x.^2) .* exp(-x.^2 / 2);
case 'morlet'
y = cos(1.75 * x) .* exp(-x.^2 / 2);
case 'gaussian'
y = exp(-x.^2);
otherwise
y = 1 ./ (1 + exp(-x)); % 默认sigmoid
end
end
4. 预测与重构模块
function predictions = wnn_predict_function(wnn_model, test_data, wavelet_info, params)
% WNN预测函数
% 输入:
% wnn_model - 训练好的WNN模型
% test_data - 测试数据
% wavelet_info - 小波分解信息
% params - 参数
% 输出:
% predictions - 预测结果
net = wnn_model.net;
% 对测试数据进行小波分解
if iscell(wavelet_info)
[test_coeffs, ~] = wavelet_decomposition(test_data, params.wavelet_type, params.decomposition_level);
else
[test_coeffs, ~] = wavelet_decomposition(test_data, wavelet_info.wavelet_type, wavelet_info.level);
end
% 构建测试样本
if iscell(test_coeffs) && length(test_coeffs) > 1
[X_test, ~] = create_multivariate_samples(test_coeffs);
else
if iscell(test_coeffs)
coeffs = test_coeffs{1};
else
coeffs = test_coeffs;
end
[X_test, ~] = create_univariate_samples(coeffs);
end
% 使用网络进行预测
wavelet_predictions = net(X_test');
predictions = wavelet_predictions';
% 如果需要,可以进行小波重构
if params.reconstruct
predictions = wavelet_reconstruction(predictions, wavelet_info);
end
end
function reconstructed = wavelet_reconstruction(predictions, wavelet_info)
% 小波重构
% 输入:
% predictions - 预测的小波系数
% wavelet_info - 小波分解信息
% 输出:
% reconstructed - 重构后的信号
if isfield(wavelet_info, 'C') && isfield(wavelet_info, 'L')
% 使用原始分解结构进行重构
C = wavelet_info.C;
L = wavelet_info.L;
wavelet_type = wavelet_info.wavelet_type;
% 这里需要根据预测结果更新系数
% 简化版本:直接使用waverec进行重构
reconstructed = waverec(C, L, wavelet_type);
reconstructed = reconstructed(1:length(predictions));
else
% 简单返回预测结果
reconstructed = predictions;
end
end
5. 数据预处理工具
function [processed_data, norm_params] = preprocess_data(data)
% 数据预处理
% 输入:
% data - 原始数据
% 输出:
% processed_data - 处理后的数据
% norm_params - 归一化参数
% 处理缺失值
data = fillmissing(data, 'linear');
% 检测并处理异常值
data = handle_outliers(data);
% 数据归一化
[processed_data, norm_params] = normalize_data(data);
fprintf('数据预处理完成: 原始数据维度 %s\n', mat2str(size(data)));
end
function data = handle_outliers(data)
% 处理异常值
if isvector(data)
% 对于向量数据
Q1 = quantile(data, 0.25);
Q3 = quantile(data, 0.75);
IQR = Q3 - Q1;
lower_bound = Q1 - 1.5 * IQR;
upper_bound = Q3 + 1.5 * IQR;
outliers = data < lower_bound | data > upper_bound;
if any(outliers)
fprintf('检测到 %d 个异常值,使用线性插值处理\n', sum(outliers));
data = filloutliers(data, 'linear');
end
else
% 对于矩阵数据,按列处理
for i = 1:size(data, 2)
data(:, i) = handle_outliers(data(:, i));
end
end
end
function [normalized_data, params] = normalize_data(data, params)
% 数据归一化
if nargin < 2
% 训练模式:计算归一化参数
params.min_val = min(data);
params.max_val = max(data);
% 避免除零
range = params.max_val - params.min_val;
range(range == 0) = 1;
params.range = range;
end
% 执行归一化 [0, 1]
normalized_data = (data - params.min_val) ./ params.range;
end
function denormalized_data = denormalize_data(normalized_data, params)
% 数据反归一化
denormalized_data = normalized_data .* params.range + params.min_val;
end
6. 性能评估模块
function performance = evaluate_performance(actual, predicted)
% 评估预测性能
% 输入:
% actual - 实际值
% predicted - 预测值
% 输出:
% performance - 性能指标结构体
% 确保维度一致
actual = actual(1:length(predicted));
predicted = predicted(1:length(actual));
% 计算各种指标
mse = mean((actual - predicted).^2);
rmse = sqrt(mse);
mae = mean(abs(actual - predicted));
% R²计算
ss_res = sum((actual - predicted).^2);
ss_tot = sum((actual - mean(actual)).^2);
r2 = 1 - (ss_res / ss_tot);
% MAPE (平均绝对百分比误差)
mape = mean(abs((actual - predicted) ./ actual)) * 100;
% 存储结果
performance.mse = mse;
performance.rmse = rmse;
performance.mae = mae;
performance.r2 = r2;
performance.mape = mape;
% 附加统计信息
performance.correlation = corr(actual, predicted);
performance.max_error = max(abs(actual - predicted));
end
function plot_prediction_results(actual, predicted, title_str)
% 绘制预测结果
figure('Position', [100, 100, 1200, 800]);
% 主预测图
subplot(2,3,1);
plot(actual, 'b-', 'LineWidth', 2); hold on;
plot(predicted, 'r--', 'LineWidth', 2);
legend('实际值', '预测值', 'Location', 'best');
title(sprintf('%s\n预测结果', title_str));
xlabel('时间点');
ylabel('值');
grid on;
% 误差图
subplot(2,3,2);
errors = actual - predicted;
plot(errors, 'g-', 'LineWidth', 1.5);
title('预测误差');
xlabel('时间点');
ylabel('误差');
grid on;
% 散点图
subplot(2,3,3);
scatter(actual, predicted, 30, 'filled', 'b');
hold on;
plot([min(actual), max(actual)], [min(actual), max(actual)], 'r--', 'LineWidth', 2);
xlabel('实际值');
ylabel('预测值');
title('实际值 vs 预测值');
grid on;
axis equal;
% 误差分布
subplot(2,3,4);
histogram(errors, 30, 'Normalization', 'probability');
title('误差分布');
xlabel('误差');
ylabel('频率');
grid on;
% 累积误差
subplot(2,3,5);
cumulative_error = cumsum(abs(errors));
plot(cumulative_error, 'm-', 'LineWidth', 1.5);
title('累积绝对误差');
xlabel('时间点');
ylabel('累积误差');
grid on;
% 性能指标展示
subplot(2,3,6);
performance = evaluate_performance(actual, predicted);
metrics = {'RMSE', 'MAE', 'R²', 'MAPE'};
values = [performance.rmse, performance.mae, performance.r2, performance.mape];
bar(values);
set(gca, 'XTickLabel', metrics);
ylabel('值');
title('性能指标');
grid on;
% 添加数值标签
for i = 1:length(values)
text(i, values(i), sprintf('%.4f', values(i)), ...
'HorizontalAlignment', 'center', 'VerticalAlignment', 'bottom');
end
sgtitle(sprintf('小波神经网络预测分析 - %s', title_str));
end
使用
示例1:时间序列预测
% 生成示例时间序列数据
t = 0:0.1:20;
original_signal = sin(t) + 0.5*sin(3*t) + 0.3*sin(5*t) + 0.1*randn(size(t));
% 添加趋势和噪声
trend = 0.02 * t;
noise = 0.2 * randn(size(t));
complex_signal = original_signal + trend + noise;
% 划分训练测试集
train_ratio = 0.7;
n_train = floor(train_ratio * length(complex_signal));
train_data = complex_signal(1:n_train)';
test_data = complex_signal(n_train+1:end)';
fprintf('时间序列预测示例\n');
fprintf('信号长度: %d, 训练集: %d, 测试集: %d\n', ...
length(complex_signal), n_train, length(test_data));
% WNN参数
wnn_params.wavelet_type = 'db4';
wnn_params.decomposition_level = 3;
wnn_params.hidden_neurons = 15;
wnn_params.max_epochs = 500;
wnn_params.learning_rate = 0.01;
wnn_params.show_window = false;
% 执行预测
[wnn_model, predictions, performance] = wnn_predict(...
train_data, test_data, wnn_params);
% 绘制结果
actual_test = test_data(1:length(predictions));
plot_prediction_results(actual_test, predictions, '时间序列预测');
% 比较不同小波类型
compare_wavelet_types(train_data, test_data);
示例2:比较不同小波类型
function compare_wavelet_types(train_data, test_data)
% 比较不同小波类型的性能
wavelet_types = {'db4', 'db8', 'sym4', 'coif4', 'haar'};
colors = lines(length(wavelet_types));
figure('Position', [100, 100, 1400, 600]);
% 预测结果比较
subplot(1,2,1);
actual = test_data;
plot(actual, 'k-', 'LineWidth', 3); hold on;
performance_metrics = zeros(length(wavelet_types), 4);
for i = 1:length(wavelet_types)
fprintf('\n测试小波类型: %s\n', wavelet_types{i});
try
[~, predictions, perf] = wnn_predict(...
train_data, test_data, ...
'wavelet_type', wavelet_types{i}, ...
'decomposition_level', 3, ...
'hidden_neurons', 10, ...
'max_epochs', 300, ...
'show_window', false);
plot(predictions, '--', 'Color', colors(i,:), 'LineWidth', 1.5);
% 存储性能指标
performance_metrics(i, 1) = perf.rmse;
performance_metrics(i, 2) = perf.mae;
performance_metrics(i, 3) = perf.r2;
performance_metrics(i, 4) = perf.mape;
catch ME
fprintf('小波类型 %s 失败: %s\n', wavelet_types{i}, ME.message);
performance_metrics(i, :) = NaN;
end
end
legend(['实际值', wavelet_types], 'Location', 'best');
title('不同小波类型预测结果比较');
xlabel('时间点');
ylabel('值');
grid on;
% 性能指标比较
subplot(1,2,2);
bar(performance_metrics);
set(gca, 'XTickLabel', wavelet_types);
legend('RMSE', 'MAE', 'R²', 'MAPE', 'Location', 'best');
title('不同小波类型性能比较');
ylabel('指标值');
grid on;
rotateXLabels(gca, 45);
sgtitle('小波类型对预测性能的影响');
end
示例3:多步预测
function multi_step_forecast(data, n_steps, wnn_params)
% 多步预测
% 输入:
% data - 时间序列数据
% n_steps - 预测步数
% wnn_params - WNN参数
fprintf('开始多步预测,步数: %d\n', n_steps);
% 初始化预测结果
forecasts = zeros(n_steps, 1);
current_data = data;
for step = 1:n_steps
fprintf('预测第 %d/%d 步...\n', step, n_steps);
% 使用当前数据训练模型并预测下一步
[~, next_pred, ~] = wnn_predict(...
current_data, current_data(end), wnn_params);
forecasts(step) = next_pred(end);
% 更新数据(滚动窗口)
current_data = [current_data(2:end); forecasts(step)];
end
% 绘制多步预测结果
figure;
n_historical = min(50, length(data));
historical_data = data(end-n_historical+1:end);
plot(1:n_historical, historical_data, 'b-', 'LineWidth', 2); hold on;
plot(n_historical:n_historical+n_steps, [historical_data(end); forecasts], 'r--', 'LineWidth', 2);
plot(n_historical+1:n_historical+n_steps, forecasts, 'ro', 'MarkerSize', 6, 'LineWidth', 2);
legend('历史数据', '预测序列', '预测点', 'Location', 'best');
title(sprintf('%d步预测结果', n_steps));
xlabel('时间点');
ylabel('值');
grid on;
fprintf('多步预测完成!\n');
end
示例4:参数敏感性分析
function parameter_sensitivity_analysis(train_data, test_data)
% 参数敏感性分析
% 测试不同隐层神经元数量
hidden_neurons_list = [5, 10, 15, 20, 25, 30];
rmse_results = zeros(length(hidden_neurons_list), 1);
fprintf('参数敏感性分析: 隐层神经元数量\n');
for i = 1:length(hidden_neurons_list)
fprintf('测试隐层神经元: %d\n', hidden_neurons_list(i));
try
[~, ~, perf] = wnn_predict(...
train_data, test_data, ...
'hidden_neurons', hidden_neurons_list(i), ...
'max_epochs', 300);
rmse_results(i) = perf.rmse;
catch
rmse_results(i) = NaN;
end
end
% 测试不同分解层数
decomposition_levels = [1, 2, 3, 4, 5];
rmse_levels = zeros(length(decomposition_levels), 1);
fprintf('\n参数敏感性分析: 小波分解层数\n');
for i = 1:length(decomposition_levels)
fprintf('测试分解层数: %d\n', decomposition_levels(i));
try
[~, ~, perf] = wnn_predict(...
train_data, test_data, ...
'decomposition_level', decomposition_levels(i), ...
'max_epochs', 300);
rmse_levels(i) = perf.rmse;
catch
rmse_levels(i) = NaN;
end
end
% 绘制敏感性分析结果
figure('Position', [100, 100, 1200, 500]);
subplot(1,2,1);
plot(hidden_neurons_list, rmse_results, 'bo-', 'LineWidth', 2, 'MarkerSize', 8);
xlabel('隐层神经元数量');
ylabel('RMSE');
title('隐层神经元数量敏感性分析');
grid on;
subplot(1,2,2);
plot(decomposition_levels, rmse_levels, 'ro-', 'LineWidth', 2, 'MarkerSize', 8);
xlabel('小波分解层数');
ylabel('RMSE');
title('分解层数敏感性分析');
grid on;
sgtitle('小波神经网络参数敏感性分析');
% 找到最佳参数
[best_rmse, best_idx] = min(rmse_results);
fprintf('\n最佳隐层神经元数量: %d (RMSE: %.4f)\n', ...
hidden_neurons_list(best_idx), best_rmse);
[best_rmse_level, best_idx_level] = min(rmse_levels);
fprintf('最佳分解层数: %d (RMSE: %.4f)\n', ...
decomposition_levels(best_idx_level), best_rmse_level);
end
高级功能
1. 实时预测更新
function updated_model = online_wnn_update(model, new_data, update_params)
% 在线更新WNN模型
% 输入:
% model - 现有WNN模型
% new_data - 新数据
% update_params - 更新参数
% 输出:
% updated_model - 更新后的模型
fprintf('在线更新WNN模型...\n');
% 提取现有网络
net = model.net;
% 对新数据进行小波分解
[new_coeffs, ~] = wavelet_decomposition(...
new_data, model.params.wavelet_type, model.params.decomposition_level);
% 构建新训练样本
if iscell(new_coeffs) && length(new_coeffs) > 1
[X_new, Y_new] = create_multivariate_samples(new_coeffs);
else
[X_new, Y_new] = create_univariate_samples(new_coeffs);
end
% 自适应学习率
if update_params.adaptive_learning
current_lr = net.trainParam.lr;
new_lr = current_lr * update_params.learning_decay;
net.trainParam.lr = max(new_lr, update_params.min_learning_rate);
end
% 增量训练
net.trainParam.epochs = update_params.incremental_epochs;
net = train(net, X_new', Y_new');
% 更新模型
updated_model = model;
updated_model.net = net;
updated_model.last_update = datetime;
fprintf('模型更新完成!\n');
end
2. 模型解释性分析
function analyze_wnn_components(wnn_model, wavelet_info)
% 分析WNN各组件贡献
fprintf('分析WNN各组件贡献...\n');
net = wnn_model.net;
% 获取网络权重
IW = net.IW{1}; % 输入层到隐层权重
LW = net.LW{2,1}; % 隐层到输出层权重
b1 = net.b{1}; % 隐层偏置
b2 = net.b{2}; % 输出层偏置
% 分析特征重要性
feature_importance = sum(abs(IW), 1);
figure;
subplot(2,2,1);
bar(feature_importance);
title('输入特征重要性');
xlabel('特征索引');
ylabel('重要性得分');
grid on;
% 小波系数贡献分析
if nargin > 1 && isfield(wavelet_info, 'level')
n_features_per_level = zeros(1, wavelet_info.level + 1);
% 这里需要根据实际特征分配计算各层贡献
% 简化版本:均匀分配
feature_idx = 1;
for i = 1:wavelet_info.level + 1
n_features = length(wavelet_info.detail_coeffs{i});
n_features_per_level(i) = n_features;
feature_idx = feature_idx + n_features;
end
subplot(2,2,2);
pie(n_features_per_level);
legend_labels = cell(1, wavelet_info.level + 1);
legend_labels{1} = '近似系数';
for i = 2:wavelet_info.level + 1
legend_labels{i} = sprintf('细节系数%d', i-1);
end
legend(legend_labels, 'Location', 'best');
title('小波系数特征分布');
end
% 神经元激活分析
subplot(2,2,3);
histfit(LW, 20);
title('输出权重分布');
xlabel('权重值');
ylabel('频率');
grid on;
% 网络结构可视化
subplot(2,2,4);
view(net);
title('神经网络结构');
sgtitle('小波神经网络组件分析');
end
参考代码 小波神经网络预测代码 www.youwenfan.com/contentcni/64776.html
参数调优指南
-
小波类型选择:
db4
,db8
: 适合大多数信号sym4
,sym8
: 对称小波,适合对称信号haar
: 简单快速,适合阶跃信号
-
分解层数:
- 通常3-5层
- 数据长度越长,可用的分解层数越多
-
网络结构:
- 隐层神经元:10-30个
- 学习率:0.001-0.1
- 训练次数:300-1000
-
数据预处理:
- 务必进行归一化
- 处理异常值和缺失值
- 考虑季节性分解
这个完整的小波神经网络预测代码包提供了从数据预处理到模型评估的完整流程,适用于各种时间序列预测任务。