一、强分类器训练过程

算法原理如下(参考自VIOLA P, JONES M. Robust real time object detection[A] . 8th IEEE International Conference on Computer Vision[C] . Vancouver , 2001.)

  • 给定样本 (x1; y1) , . . . , (xn; yn) ; 其中yi = 0表示负样本,yi =1表示正样本;
  • 初始化权重:负样本权重W0i= 1/2m, 正样本权重W1i = 1/ 2l,其中m为负样本总数,l为正样本总数;
  • 对于t = 1, … T(T为训练次数):

    1. 权重归一化,简单说就是使本轮所有样本的权重的和为1;
    2. 根据每一个特征训练简单分类器,仅使用一个特征;
    3. 从所有简单分类器中选出一个分错率最低的分类器,为弱分类器;
    4. 更新权重
  • 最后组合T个弱分类器为强分类器

二、代码实现及说明(python)

目的:训练得到一个强分类器,该强分类器分错率低于预设值,且该强分类器由若干个弱分类器(对应单个特征)组成,通过若干个分类器及其权重计算得到的值对样本进行分类。

def adaBoostTrainDS(dataArr,classLabels,numIt=40): 
    weakClassArr = [] #存放强分类器的所有弱分类器信息
    m = shape(dataArr)[0] 
    D = mat(ones((m,1))/m)   #权重初始化
    aggClassEst = mat(zeros((m,1)))
    for i in range(numIt):
        bestStump,error,classEst = buildStump(dataArr,classLabels,D)#根据训练样本、权重得到一个弱分类器

        print "D:",D.T
        alpha = float(0.5*log((1.0-error)/max(error,1e-16)))#计算alpha值,该值与分错率相关,分错率越小,该值越大,弱分类器权重
                                                            #max(error,1e-16)用于确保错误为0时不会发生除0溢出
        bestStump[\'alpha\'] = alpha  
        weakClassArr.append(bestStump)  #存储该弱分类
        print "classEst: ",classEst.T
        expon = multiply(-1*alpha*mat(classLabels).T,classEst) 
        D = multiply(D,exp(expon))  #重新计算样本权重
        D = D/D.sum() #归一化
        #计算当前强分类器的分错率,达到预期要求即停止
        aggClassEst += alpha*classEst
        print "aggClassEst: ",aggClassEst.T
        aggErrors = multiply(sign(aggClassEst) != mat(classLabels).T,ones((m,1))) #计算数据点哪个是错误
        print \'aggErrors: \',sign(aggClassEst) != mat(classLabels).T
        print \'aggErrors: \',aggErrors
        errorRate = aggErrors.sum()/m #计算错误率
        print "total error: ",errorRate
        if errorRate == 0.0: break
    return weakClassArr

三、运行结果

训练样本:

    datMat = matrix([[ 1. ,  2.1,  0.3],
                                 [ 2. ,  1.1,  0.4],
                                 [ 1.3,  1. ,  1.2],
                                 [ 1. ,  1. ,  1.1],
                                 [ 2. ,  1. ,  1.3],
                                 [ 7. ,  2. ,  0.35]])
    classLabels = [1.0, 1.0, 1.0, -1.0, -1.0, -1.0]

训练得到的强分类器(强分类器分错率:0%,单个弱分类器最小分错率为33%,在上一篇已经测试过):

[{\’dim\’: 0, \’ineq\’: \’gt\’, \’thresh\’: 1.6000000000000001, \’alpha\’: 0.34657359027997275},

{\’dim\’: 1, \’ineq\’: \’lt\’, \’thresh\’: 1.0, \’alpha\’: 0.5493061443340549},

{\’dim\’: 0, \’ineq\’: \’gt\’, \’thresh\’: 2.2000000000000002, \’alpha\’: 0.5493061443340549},

{\’dim\’: 2, \’ineq\’: \’gt\’, \’thresh\’: 0.29999999999999999, \’alpha\’: 0.4777557225137181},

{\’dim\’: 0, \’ineq\’: \’lt\’, \’thresh\’: 1.0, \’alpha\’: 0.49926441505556346}]

手动计算分类:

针对第一个样本[ 1. ,  2.1, 
0.3]
,利用强分类器计算结果如下:

0.34657359027997275

0.5493061443340549


0.5493061443340549

+
0.4777557225137181

+
0.49926441505556346

= -0.468165741378801—>小于0,正样本

 

针对第六个样本[
7. ,  2. ,  0.35]
,利用强分类器计算结果如下:

+ 0.34657359027997275

0.5493061443340549

+
0.5493061443340549

+
0.4777557225137181


0.49926441505556346

= +0.3250648977381274—>大于0,负样本

其它样本的计算类似

结论:

强分类器分类,即通过若干个分类器的权重的正负号计算得出,而正负号是通过该若分类器的阈值判断得到;

强分类器比弱分类器准确率高。

 

版权声明:本文为chenpi原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/chenpi/p/5128234.html