一、强分类器训练过程
算法原理如下(参考自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;
- 根据每一个特征训练简单分类器,仅使用一个特征;
- 从所有简单分类器中选出一个分错率最低的分类器,为弱分类器;
- 更新权重
- 最后组合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,负样本
其它样本的计算类似
结论:
强分类器分类,即通过若干个分类器的权重的正负号计算得出,而正负号是通过该若分类器的阈值判断得到;
强分类器比弱分类器准确率高。