Mechine Learning——Adaboost

Adaboost的本质就是三个臭皮匠赛过诸葛亮。

集成方法(ensemble method)通过组合多个学习器来完成学习任务,颇有点“三个臭皮匠顶个诸葛亮”的意味。基分类器一般采用的是弱可学习(weakly learnable)分类器,通过集成方法,组合成一个强可学习(strongly learnable)分类器。所谓弱可学习,是指学习的正确率仅略优于随机猜测的多项式学习算法;强可学习指正确率较高的多项式学习算法。集成学习的泛化能力一般比单一的基分类器要好,这是因为大部分基分类器都分类错误的概率远低于单一基分类器的。

集成方法主要包括Bagging和Boosting两种方法,Bagging和Boosting都是将已有的分类或回归算法通过一定方式组合起来,形成一个性能更加强大的分类器,更准确的说这是一种分类算法的组装方法,即将弱分类器组装成强分类器的方法。

与bagging不同的是,bagging是互相独立的几个臭皮匠发言后进行汇总,而boost是一个一个臭皮匠轮流发言,每个臭皮匠根据上个臭皮匠的发言进行改进,最后把结果汇总。
bagging:
在这里插入图片描述
boost:
在这里插入图片描述
“三个臭皮匠,赛过诸葛亮。”
这里臭皮匠就是垃圾算法,但是汇总集成以后就变成大牛算法了
一开始每个样本的权重都是一样的,
对预测错的数据要加大权重
此外还要算出这个算法的错误率
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
上面四张图
P1是错误率,根据其带入P2算出比重α。
可以看出当错误率低时,α会变大
α是个每个弱算法的比重,当错误率低的时候他的比重会变大
D是每个样本的权重
P3可以看出当预测错误的时候,比例会变大
P4是用来归一化的,让sum(D)=1

def stumpClassify(dataMatrix,dimen,threshVal,threshIneq):#just classify the data
    retArray = ones((shape(dataMatrix)[0],1))
    if threshIneq == 'lt':
        retArray[dataMatrix[:,dimen] <= threshVal] = -1.0
    else:
        retArray[dataMatrix[:,dimen] > threshVal] = -1.0
    return retArray

‘It’的意思是less than;‘gt’的意思是greater than。就是大小于的意思
dataMatrix就是训练集特征矩阵
dimen就是特征,即第dimen个特征
threshVal是指阈值,即判断的界限
threshIneq有‘It’,‘gt’两个选择,即判断的方式
把 threshIneq threshVal的值记作-1,其余为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 #init error sum, to +infinity
    for i in range(n):#loop over all dimensions
        rangeMin = dataMatrix[:,i].min(); rangeMax = dataMatrix[:,i].max();
        stepSize = (rangeMax-rangeMin)/numSteps
        for j in range(-1,int(numSteps)+1):#loop over all range in current dimension
            for inequal in ['lt', 'gt']: #go over less than and greater than
                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
                weightedError = D.T*errArr  #calc total error multiplied by D
                #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

input:
dataArr是训练集特征矩阵
classLabels是指标签向量
D是每个样本的权重
中间值解释:
errArr是误差向量(预判错误的误差1,预判正确的误差0)
weightedError是根据权重得到的总误差
output:
bestStump为字典,存着误差最小时的特征,阈值和大小于
minError是指最小误差,即min(weightedError)
bestClasEst是误差最小时预测向量

def adaBoostTrainDS(dataArr,classLabels,numIt=40):
    weakClassArr = []
    m = shape(dataArr)[0]
    D = mat(ones((m,1))/m)   #init D to all equal
    aggClassEst = mat(zeros((m,1)))
    for i in range(numIt):
        bestStump,error,classEst = buildStump(dataArr,classLabels,D)#build Stump
        #print "D:",D.T
        alpha = float(0.5*log((1.0-error)/max(error,1e-16)))#calc alpha, throw in max(error,eps) to account for error=0
        bestStump['alpha'] = alpha  
        weakClassArr.append(bestStump)                  #store Stump Params in Array
        #print "classEst: ",classEst.T
        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()
        #calc training error of all classifiers, if this is 0 quit for loop early (use break)
        aggClassEst += alpha*classEst
        #print "aggClassEst: ",aggClassEst.T
        aggErrors = multiply(sign(aggClassEst) != mat(classLabels).T,ones((m,1)))
        errorRate = aggErrors.sum()/m
        print "total error: ",errorRate
        if errorRate == 0.0: break
    return weakClassArr,aggClassEst

numIt是迭代次数,这里默认为40
每一次迭代都会得到一个弱算法,即臭皮匠
代码实现中用weakClassArr列表储存每一个弱算法的相关信息
即每个每个弱算法的字典,此外还扩充了字典,再加了每个弱算法的α值
因为最后要把这几个臭皮匠的意见按照权重累加从而得到最后的预测值
aggClassEst是按照比重把预测值累加起来
aggErrors是列表,预测正确的是0,预测不正确的是1

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
        print aggClassEst
    return sign(aggClassEst)

datToClass是要预测的数据
classifierArr是训练好的分类器,即上个代码里面的weakClassArr

if __name__ == '__main__':
    dataArr,classLabels = loadSimpData()
    weakClassArr, aggClassEst = adaBoostTrainDS(dataArr, classLabels)
    print(adaClassify([[0,0],[5,5]], weakClassArr))

这里[[0,0],[5,5]]是要测量的数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值