AdaBoost算法中寻找最优阈值分类器的代码优化

    AdaBoost每一轮的训练获得一个当前权重条件下的最优阈值。

% 逐步求精的方法获取第j个特征值上的最优分类器
% 输入:
% X      训练样本
, rows X cols 维矩阵 , rows个样本,每个样本cols个特征值
% Y      每个样本所属类别的标识
, 向量 , 长度为rows
% rows   样本容量 
% weight 权重向量
, 存放当前每个样本的权重值
% j       当前查找最佳弱分类器的特征列
% 输出:
%  bestError        %搜索到第j列最佳弱分类器得到的最小错误率
%  bestThresh   %搜索到第j列最佳弱分类器的阈值
%  bestBias        %搜索到第j列最佳弱分类器的偏置

% 迭代4次
, 每次将区间划分为12个小段
%
% 调用格式为 
[ bestError,bestThresh,bestBias ] = findBestWeakLearner(X , Y , rows , weight , j)
% 最后更新 
2007 - 03 - 25  
function 
[ bestError,bestThresh,bestBias ] = findBestWeakLearner(X , Y , rows , weight , j)
% 检查输入特征向量与类标需为列向量
iptcheckinput(X
, {'logical' , 'numeric'} , {'2d' , 'nonempty' , 'real'} , mfilename ,  'X' ,   1 ) ;
iptcheckinput(Y , {'logical' , 'numeric'} , {'column' , 'nonempty' , 'integer'} , mfilename ,  'Y' ,   2 ) ;

iteration
= 4 ;                                      % 迭代次数
sectNum = 12 ;                                  % 每次迭代,将搜索区域划分的片段
maxFea = max(X(: , j)) ;                      % 搜索空间的最大值 
minFea = min(X(: , j)) ;                       % 搜索空间的最小值
step = (maxFea-minFea)/(sectNum- 1 ) ;         % 每次搜索的递增量

bestError
= rows ;                             % 初值:最好的分类器错误率
for iter = 1 :iteration                         % 迭代iteration次 , 范围逐步缩小 , 寻找最优值
        tempError
= rows ;                   % 初值:第iter次迭代的分类器错误率      
        for i = 1 :sectNum                    % 第iter次迭代的搜索次数
            thresh
= minFea+(i- 1 )*step ;     % 第i次搜索的阈值
            for p = 1 :- 2 :- 1                      % !这个循环可去掉
                h
= zeros(rows , 1 ) ;          %每个样本对弱分类器的输出
                for ii = 1 :rows                  %!这个循环可向量化
                    if((p*X(ii
, j))<(p*thresh))
                        h(ii)
= 1 ;
                    else
                        h(ii)
= 0 ;
                    end
                end %end for
                error
= sum(weight(find(h~ = Y))) ;  % 第iter次迭代第i次搜索加权错误率
                
                   %! 这段属冗余代码
                if(error<tempError)           % 第iter次迭代最优的错误率 阈值 偏置
                    tempError
= error ;           % 第iter次迭代最小的错误率
                    tempThresh = thresh ;    % 第iter次迭代最小错误分类情况下的阈值
                    tempBias = p ;                  % 第iter次迭代最小错误分类情况下的偏置
                end
            end%end for p
        end%end for i
        if(tempError<bestError)          %  迭代获取的最优错误率 阈值 偏置
                bestError
= tempError ;
                bestThresh = tempThresh ;
                bestBias = tempBias ;
        end
        %将搜索范围缩小
, 继续进行搜索
         span
= (maxFea-minFea)/ 8 ;              % 搜索范围减为原有的1/4             
         maxFea = tempThresh+span ;           % 减少搜索范围后搜索空间的最大值     
         minFea = tempThresh-span ;            % 减少搜索范围后搜索空间的最小值
        
        step
= (maxFea-minFea)/(sectNum- 1 ) ; % 减少搜索范围后每次搜索的递增量
end

在将循环向量化,并删除一些重复的赋值运算后。代码量大大减少,计算效率也得到极大改善。

% 在特征列上获得最优的阈值分类器

% 假设分布满足高斯分布
% 通过高斯模型求取两个类别的均值
% 在两个类别的均值中间搜索最有阈值分类器
% 采用逐步求精的搜索策略
%
% 输入:
% FeatureVector 特征向量,查找最佳弱分类器的特征列
; 列向量      
% Y             每个样本所属类别的标识 , 长度为rows ; 列向量
% rows          样本容量 
% weight        权重向量
, 存放当前每个样本的权重值

% 输出:
%  bestError    搜索到第j列最佳弱分类器得到的最小错误率
%  bestThresh   搜索到第j列最佳弱分类器的阈值
%  bestBias     搜索到第j列最佳弱分类器的偏置

% 迭代4次
, 每次将区间划分为8个小段
%
% 调用格式为
[ bestError,bestThresh,bestBias ] = searchBestWeakLearner(FeatureVector , Y , rows , weight)

2007 - 11 - 07   

% findBestWeakLearner 扩展版本

function 
[ bestError,bestThresh,bestBias ] = searchBestWeakLearner(FeatureVector , Y , rows , weight)
% 检查输入特征向量与类标需为列向量
iptcheckinput(FeatureVector
, {'logical' , 'numeric'} , {'column' , 'nonempty' , 'real'} , mfilename ,  'FeatureVector' ,   1 ) ;
iptcheckinput(Y , {'logical' , 'numeric'} , {'column' , 'nonempty' , 'integer'} , mfilename ,  'Y' ,   2 ) ;

u1
= mean(FeatureVector(find(Y == 1 ))) ;       % 类别1均值
u2 = mean(FeatureVector(find(Y == 0 ))) ;       % 类别2均值

iteration
= 4 ;                                     % 迭代次数
sectNum = 8 ;                                   % 每次迭代,将搜索区域划分的片段

maxFea
= max(u1 , u2) ;                      % 搜索空间的最大值 
minFea = min(u1 , u2) ;                        % 搜索空间的最小值
step = (maxFea-minFea)/(sectNum- 1 ) ;         % 每次搜索的递增量
bestError = rows ;                           % 初值:最好的分类器错误率

for iter
= 1 :iteration                        % 迭代iteration次 , 范围逐步缩小 , 寻找最优值
        tempError
= rows ;                   % 初值:第iter次迭代的分类器错误率      
        for i = 1 :sectNum                  % 第iter次迭代的搜索次数
            thresh
= minFea+(i- 1 )*step ;     % 第i次搜索的阈值
            h = FeatureVector<thresh ;       % 所有样本的阈值分类结果
            error = sum(weight(find(h~ = Y))) ; % 第iter次迭代第i次搜索加权错误率
            p = 1 ;
            if(error> 0.5 )                   % 若错误率超过0 .5 ,则将偏置反向
                error
= 1 -error ;
                p = - 1 ;
            end
            if( error<bestError )        % 第iter次迭代最优的错误率 阈值 偏置
                bestError
= error ;          % 第iter次迭代最小的错误率
                bestThresh = thresh ;    % 第iter次迭代最小错误分类情况下的阈值
                bestBias = p ;               % 第iter次迭代最小错误分类情况下的偏置
            end
        end%end for i

        % 将搜索范围缩小
, 继续进行搜索
        span
= (maxFea-minFea)/ 8 ;             % 搜索范围减为原有的1/4                    
        maxFea = bestThresh+span ;           % 减少搜索范围后搜索空间的最大值     
        minFea = bestThresh-span ;             % 减少搜索范围后搜索空间的最小值
       
       step
= (maxFea-minFea)/(sectNum- 1 ) ;  % 减少搜索范围后每次搜索的递增量
end


针对2000个样本,训练50轮AdaBoost分类器,采用findBestWeakLearner搜索最优分类器耗时150s,采用searchBestWeakLearner耗时50s,仅为原有1/3。

toself: 程序改变心境

你可能感兴趣的:(优化,算法,function,Integer,扩展)