机器实战之AdaBoost

来源:互联网 发布:hammer.js中文文档 编辑:程序博客网 时间:2024/05/22 12:52

1 算法概述
这是一种基于数据集多重抽样的训练方法。运行过程:首先将所有训练样本赋予一个大小相等的样本权重,然后训练出一个弱分类器(只要识别率大于0.5即可),并计算该分类器的错误率,根据分类错误率动态调整样本权重,即奖励分类错误的样本,同时惩罚分类真确的样本,这样就能扩大分类错误样本的作用而削弱分类真确样本的作用;接着,更新完样本权重后,再用同样的训练样本训练第二个分类器,再根据训练的错误率,更新样本权重,再训练第二个分类器,依此类推,直到训练的错误率收敛到一定的精度或者弱分类器到达指定数目为止。
算法示意图为:
这里写图片描述
图中表示:首先5个训练有着同样的样本权重D,然后送入一个分类器,通过训练这个分类器,就会得分类错误的样本,根据分类错误的样本就能计算该分类器的错误率这里写图片描述
这里写图片描述
根据分类器的错误率就能计算出该分类器的权值这里写图片描述
这里写图片描述
比如,上图中第一个分类器的权值这里写图片描述=0.69。根据得到的分类器权值这里写图片描述就能动态更新样本权重:
这里写图片描述(当样本i为分类真确的样本)
这里写图片描述(当样本i为分类错误的样本)
所以,被分类真确的样本权重会越来越小,而分类错误样本权重会越来越大。
比如上图中,在进入第二分类器之前,5个训练样本权重就不一样了,经过第二个分类器训练之后,第二个分类器得到的权值这里写图片描述,然后再更新样本权重,再送入第三个分类器训练,得到第三个分类器的权值这里写图片描述,最后将所有弱分类器得到的权值进行加权这里写图片描述,从而得到最终的输出结果。
2 算法实现
(1)实现单层决策树

#返回错误率最小的单层树桩def buildStump(dataArr,classLabels,D):    dataMatrix = mat(dataArr); labelMat = mat(classLabels).T    m,n = shape(dataMatrix)    numSteps = 10.0; bestStump = {}; bestClasEst = mat(zeros((m,1)))    minError = inf #初始误差权重正无穷    for i in range(n):#遍历每个特征        rangeMin = dataMatrix[:,i].min(); rangeMax = dataMatrix[:,i].max()        stepSize = (rangeMax-rangeMin)/numSteps #每个特征的步长大小 0.1        for j in range(-1,int(numSteps)+1):#遍历每个步长 ,12步[-1,0,1,2,3,4,5,6,7,8,9,10]            for inequal in ['lt', 'gt']: #遍历大于和小于某个阈值                threshVal = (rangeMin + float(j) * stepSize)                #建立一颗单层决策树,对数据集进行预测                predictedVals = stumpClassify(dataMatrix,i,threshVal,inequal)#call stump classify with i, j, lessThan                errArr = mat(ones((m,1)))                errArr[predictedVals == labelMat] = 0 #预测对了,误差为0,否则为1                weightedError = D.T*errArr  #错误率的值                print "split: dim %d, thresh %.2f, thresh ineqal: %s, the weighted error is %.3f" % (i, threshVal, inequal, weightedError)                #保存错误率最小时的单层决策树,错误率以及类别估计值                if weightedError < minError:                    minError = weightedError                    bestClasEst = predictedVals.copy()                    bestStump['dim'] = i                    bestStump['thresh'] = threshVal                    bestStump['ineq'] = inequal    return bestStump,minError,bestClasEst

(2)完整AdaBoost算法

#训练多个单层决策树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)#利用buildStump()函数找到最佳单层决策树        print "D:",D.T        alpha = float(0.5*log((1.0-error)/max(error,1e-16)))#计算上面最佳单层决策树的权值        bestStump['alpha'] = alpha          weakClassArr.append(bestStump)                  #store Stump Params in Array        print "classEst:",classEst.T        #根据alpha,更新样本权重        expon = multiply(-1*alpha*mat(classLabels).T,classEst) #exponent for D calc, getting messy        D = multiply(D,exp(expon))                              #Calc New D for next iteration        D = D/D.sum()        #更新类别估计        aggClassEst += alpha*classEst        aggClassEst=sign(aggClassEst)        print "aggClassEst:",aggClassEst.T        #累加错误分类样本        aggErrors = multiply(aggClassEst!= mat(classLabels).T,ones((m,1)))        errorRate = aggErrors.sum()/m        print "total error: ",errorRate        if errorRate == 0.0: break    weakClassArr=mat(weakClassArr)    return weakClassArr,aggClassEst

(3)AdaBoost分类

#用多个弱分类器进行分类def adaClassify(datToClass,classifierArr):    dataMatrix = mat(datToClass)#do stuff similar to last aggClassEst in adaBoostTrainDS    m = shape(dataMatrix)[0]    aggClassEst = mat(zeros((m,1)))    #遍历每个弱分类器    for i in range(len(classifierArr)):        classEst = stumpClassify(dataMatrix,classifierArr[i]['dim'],\                                 classifierArr[i]['thresh'],\                                 classifierArr[i]['ineq'])#call stump classify        aggClassEst += classifierArr[i]['alpha']*classEst        aggClassEst=sign(aggClassEst)        print aggClassEst    return aggClassEst
0 0
原创粉丝点击