机器实战之AdaBoost

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值