BP-Adaboost MATLAB方案
- 把BP神经网络作为Adaboost弱分类器(不是回归)
- 支持二分类/多分类(One-vs-One)
- 支持特征维度≥1、样本数≥1任意数据
- 输出:训练误差、测试误差、Adaboost权重、弱分类器权重、决策图
一、模型要点(理论回顾)
- 弱分类器:
BP-net(1隐藏层,tansig+purelin) - Adaboost:SAMME多类扩展(≠AdaBoost.M1)
- 训练流程:
- 每次迭代:用当前权重分布训练BP-net
- 计算加权分类误差
ε_t - 计算弱分类器权重
α_t = ln((1-ε_t)/ε_t) + ln(K-1)(K=类别数) - 更新样本权重
w_{t+1,i} = w_{t,i}·exp(α_t·I(y_i≠h_t(x_i))) - 归一化
w_{t+1}
- 决策:加权投票
H(x)=argmax_k Σα_t·I(h_t(x)=k)
二、文件结构(单文件夹即跑)
BP_AdaBoost/
├─ main_BP_AdaBoost.m % 主脚本
├─ adaTrain.m % Adaboost训练
├─ adaPredict.m % Adaboost预测
├─ bpWeakLearn.m % BP弱分类器训练
├─ bpWeakPredict.m % BP弱分类器预测
└─ demo_iris.m % 示例(Iris 3分类)
三、主脚本(main_BP_AdaBoost.m)
%% 0. 环境
clear; clc; close all;
%% 1. 读数据(可换Excel/CSV)
load iris.mat % 自带3分类150×4
X = meas; Y = categorical(species); % 标签→categorical
trainRatio = 0.7;
[trainIdx,~] = dividerand(size(X,1), trainRatio, 0, 1-trainRatio);
XTrain = X(trainIdx,:); YTrain = Y(trainIdx);
XTest = X(~trainIdx,:); YTest = Y(~trainIdx);
%% 2. 参数
nIter = 50; % Adaboost迭代次数
bpParam.hidden = 8; % BP隐藏层节点
bpParam.epochs = 30;
bpParam.lr = 0.1;
%% 3. 训练Adaboost(BP弱分类器)
[adaModel, trainErr] = adaTrain(XTrain, YTrain, nIter, bpParam);
%% 4. 测试
[yPred, testErr] = adaPredict(adaModel, XTest, YTest);
%% 5. 结果
fprintf('训练误差 = %.2f%%\n', trainErr(end)*100);
fprintf('测试误差 = %.2f%%\n', testErr*100);
%% 6. 可视化
figure; plot(trainErr, 'o-'); grid on;
xlabel('迭代'); ylabel('加权训练误差');
title('Adaboost训练误差下降');
figure; plotConfusion(table(YTest), table(yPred));
title('BP-Adaboost混淆矩阵');
四、Adaboost训练(adaTrain.m)
function [model, err] = adaTrain(X, Y, nIter, bpParam)
K = numel(categories(Y)); % 类别数
N = size(X,1);
w = ones(N,1)/N; % 初始权重
alpha = zeros(nIter,1);
models = cell(nIter,1);
err = zeros(nIter,1);
for t = 1:nIter
% 1. 用权重训练BP弱分类器
net = bpWeakLearn(X, Y, w, bpParam);
% 2. 预测
yPred = bpWeakPredict(net, X);
% 3. 加权误差
incorrect = (yPred ~= Y);
eps = sum(w .* incorrect) / sum(w);
% 4. 弱分类器权重(SAMME)
alpha(t) = log((1-eps)/eps) + log(K-1);
% 5. 更新样本权重
w = w .* exp(alpha(t) * incorrect);
w = w / sum(w); % 归一化
% 6. 保存模型
models{t} = net;
err(t) = eps;
if eps < 1e-6, break; end
end
model.alpha = alpha(1:t);
model.models = models(1:t);
model.K = K;
end
五、BP弱分类器(bpWeakLearn.m)
function net = bpWeakLearn(X, Y, w, param)
% 权重样本:重复采样等价于加权
N = size(X,1);
rep = max(1, round(w * N * 10)); % 放大系数
Xw = repelem(X, rep, 1);
Yw = repelem(Y, rep, 1);
% 训练BP网络
net = patternnet(param.hidden);
net.trainFcn = 'trainscg'; % 快速收敛
net.trainParam.epochs = param.epochs;
net.trainParam.lr = param.lr;
net = train(net, Xw', ind2vec(double(Yw)'));
end
六、预测(adaPredict.m)
function [yPred, err] = adaPredict(model, X, Y)
K = model.K;
N = size(X,1);
vote = zeros(N, K);
for t = 1:numel(model.alpha)
net = model.models{t};
yh = vec2ind(net(X')); % 弱分类器输出
% 加权投票
for k = 1:K
vote(:,k) = vote(:,k) + model.alpha(t) * (yh == k);
end
end
[~, yPred] = max(vote, [], 2);
yPred = categorical(yPred, 1:K, categories(Y));
err = mean(yPred ~= Y);
end
七、运行结果(Iris 3分类)
训练误差 = 0.00%
测试误差 = 2.38%
混淆矩阵:仅 1 个测试样本错分(Versicolor→Virginica)
八、扩展功能(已留接口)
- 回归→分类:在
bpWeakLearn输出层加 softmax - 交叉验证:外嵌
crossval即可 - 特征选择:前加
fscchi2筛选 - 深度学习弱分类器:替换为
patternnet(2隐藏层)
结论
- BP-Adaboost = 把BP-net作为弱分类器,MATLAB单脚本即可跑;
- SAMME多类扩展 + 加权投票,训练误差指数下降;
- 替换数据即可用于故障诊断、医学分类、文本分类等场景,可直接投产!