一直以来,Adaboost都是我比较喜欢的模式分类方法,工作当中用的也比较多,Adaboost的算法思想决定了其特别适合于机器视觉中的目标检测任务,即简单的易于区分的只用很少的弱分类器就可以区分,较难的则使用更多的弱分类器来区分。本篇博客简要介绍Adaboost及其变种(variants),重点放在各种variants的实现及差别(尤其是在数据不平衡情况下的差别),以便在工作中针对不同问题灵活选取Adaboost 的type。这里主要介绍Discrete Adaboost, Real Adaboost, Gentle Adaboost, Modest Adaboost, Parameterized Adaboost 及Penalized Adaboost。
关于Adaboost,首先借参考文献中的一幅图,整体了解其发展
各种Adaboost variants本质上是相同的,只是在弱分类器的输出及样本权重更新有所差别,本博客这里只选取decision stump作为weak classifier。
Discrete Adaboost
Discrete Adaboost是最简单的Adaboost,其算法流程如下图所示
Discrete Adaboost弱分类器的输出为+1, -1,为了各种Variants统一,定义decision stump
% stump is a structure with the flowing field % .fidx feature index % .thresh local thrshold of the stump % .parity predicting parity (+1: > threshold is positive, -1: > threshold is negative) % .posProb probability for positive % .negProb probability for neagtive % .error local weighted error
- Real Adaboost
- Gentle Adaboost
- Modest Adaboost
- Parameterized Adaboost
- MarginPruning Adaboost
- Penalized Adaboost
- Cost-Generalized AdaBoost
),一开始我也对这个发现持怀疑态度,就从最基本的Discrete
Adaboost出发来验证一下%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Asymmetric Adaboost train demo(Cost-Sensitive AdaBoost algorithms)
clc; clear all;
close all;
%% Make training data of two classes "red" and "blue"
% with 2 features for each sample (the position x and y).
Nb = 1500; Nr = 100;
angle = rand(Nb,1)*2*pi; l = rand(Nb,1)*40+30; blue = [sin(angle).*l cos(angle).*l];
angle = rand(Nr,1)*2*pi; l = rand(Nr,1)*40; red = [sin(angle).*l cos(angle).*l];
% All the training data
trainData = [blue;red];
trainLabel(1:Nb) = -1; trainLabel(Nb+1:Nb+Nr) = 1;
trainLabel = trainLabel(:);
% Show the data
figure;
plot(blue(:,1), blue(:,2), 'b.'); hold on; plot(red(:,1), red(:,2), 'r.');
grid on; legend('Negative', 'Positive'); title('Training Data');
%% Cost-Generalized AdaBoost
Cp = 0.5; Cn = 0.3;
weight_p = ones(Nr, 1)/Nr;
weight_n = ones(Nb, 1)/Nb;
weight = [Cn/(Cp+Cn)*weight_n; Cp/(Cp+Cn)*weight_p];
weight = weight/sum(weight);
itrNum = 100;
models = []; casErr = []; casErrPos = []; casErrNeg = [];
predictedLabelCascade = zeros(size(trainLabel));
for k = 1 : itrNum
% train a decision stump(weak classifier)
stump = DecisionStumpTrain(trainData, trainLabel, weight, 'Discrete');
predictedLabel = DecisionStumpPredict(stump, trainData);
% weak classifier influence on total result is based on the current
% classification error
alpha = 0.5 * log((1-stump.error)/max(stump.error,eps));
% update samples weights
weight = weight .* exp(-alpha.*trainLabel.*predictedLabel);
weight = weight / sum(weight);
% calculate the current error of the cascade of weak classifiers
predictedLabelCascade = predictedLabelCascade + predictedLabel*alpha;
casPrecdict = sign(predictedLabelCascade);
casErr = [casErr, sum(casPrecdict~=trainLabel) / (Nb+Nr)];
casErrPos = [casErrPos, sum((casPrecdict~=trainLabel).*(trainLabel==1)) / Nr];
casErrNeg = [casErrNeg, sum((casPrecdict~=trainLabel).*(trainLabel==-1)) / Nb];
model.error = casErr(end);
model.stump = stump;
model.alpha = alpha;
models = [models; model];
if(model.error == 0); break; end
end
% figure out the cascade training error
figure;
plot(casErr, 'r'); grid on; hold on;
plot(casErrPos, 'g'); plot(casErrNeg, 'b');
legend('Total Error', 'Positive Error', 'Negative Error');
figure;
plot(blue(:,1), blue(:,2), 'b.'); grid on; hold on;
plot(red(:,1), red(:,2), 'r.');
errIdx = find(casPrecdict ~= trainLabel);
plot(trainData(errIdx, 1), trainData(errIdx, 2), 'sm');
title(['TErr = ', num2str(sum(casPrecdict ~= trainLabel)), ...
', FN = ', num2str(sum((casPrecdict ~= trainLabel).*(trainLabel==1))), ...
', FP = ', num2str(sum((casPrecdict ~= trainLabel).*(trainLabel==-1)))]);随机生成1500个负样本核100个正样本,设置正样本类别权重Cp=0.5,负样本类别权重Cn=0.3,结果如下:
。如果设置Cp = 0.5; Cn = 0.1; 你会惊奇的发现- 实验结果
% initialize weight of samples
if 1
% Cost-Generalized AdaBoost
Cp = 0.5; Cn = 0.2;
weight = ones(size(trainLabel));
weight(trainLabel==1) = (1/sum(trainLabel==1)) * (Cp/(Cp+Cn));
weight(trainLabel==-1) = (1/sum(trainLabel==-1)) * (Cn/(Cp+Cn));
else
weight = ones(size(trainLabel));
weight = weight / sum(weight);
end参考文献:
2012 Ferreira Figueiredo Boosting Algorithms A Review of Methods Theory and Applications
2015 Analysis of Generalization Ability for Different AdaBoost Variants Based on Classification and Regression Trees
2015 Penalized AdaBoost Improving the Generalization Error ofGentle AdaBoost through a Margin Distribution
2015 Shedding Light on the Asymmetric Learning Capability of AdaBoost
2015 Revisiting AdaBoost for Cost-Sensitive Classification(1)
2015 Revisiting AdaBoost for Cost-Sensitive Classification(2)
关于Real_AdaBoost算法的分析与改进
本文详细介绍了Adaboost及其多种变种算法,包括DiscreteAdaboost、RealAdaboost、GentleAdaboost等,并探讨了它们在处理数据不平衡问题上的表现。
476





