《机器学习实战》第七章----AdaBoost元算法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28773183/article/details/81061564

元算法

元算法是对其他算法进行组合的一种方法,其背后的思路就是组合多个专家的经验来得到最终的结论,类似于我们的投票.而提升方法是其中最常用的方法,在分类问题中,它通过改变训练样本的权重,学习多个分类器,并将这些这些分类器进行线性组合.


弱分类器和强分类器

关于AdaBoost方法,相比于SVM的大量推导,它显得更为简单一点,具体的推导,这里有一些个人认为非常好理解的推导:
AdaBoost实现
bootstrap, boosting, bagging 几种方法的联系
sign函数
单层决策树

弱分类器比较简单,一般常用的可以时单层决策树,但这种分类器虽然简单,但是分类性能很糟糕,因此利用提升方法学习出强分类器,弱分类器投票时占的权重小,相应的,强分类器占的权重大,这样的组合可以面对一些特殊样本,使得分类性能更加优秀.这里主要是代码中遇到的弱分类器的构建,其实简单的可以这样理解:

  1. 对每个特征循环,选择的特征是最好的
  2. 在特征的范围内选定步长,选择最合适的阈值
  3. ‘lt’和’gt’分别代表两种情况:第一种:’lt’:低于阈值的是分类为-1的,第二种:’gt’:高于阈值的分类为-1 (因为并不知道超过阈值应该分为哪一类
  4. 最终单层决策树的原则:minError,误差最小
    代码如下:
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()#rangeMin,rangeMax分别代表数据集中特征的最小和最大值
        stepSize = (rangeMax-rangeMin)/numSteps #步长
        for  j in range(-1,int(numSteps)+1): #循环12次
            for inequal in ['lt','gt']:
                threshVal = (rangeMin+float(j)*stepSize)
                predictedVals = stumpClassify(dataMatrix,i,threshVal,inequal)
                errArr = mat(ones((m,1)))
                errArr[predictedVals == labelMat] =0
                weightedError = D.T*errArr #<统计学习方法>Page139 (8.8)或Page138 (8.1)
                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

ROC曲线

先看一个例子:测试样本中有A类样本90个,B 类样本10个。分类器C1把所有的测试样本都分成了A类,分类器C2把A类的90个样本分对了70个,B类的10个样本分对了5个。则C1的分类精度为 90%,C2的分类精度为75%。但是,显然C2更有用些。另外,在一些分类问题中犯不同的错误代价是不同的(cost sensitive learning)。这样,默认0.5为分类阈值的传统做法也显得不恰当了。为了合理的评判分类器的性能(非均衡分类问题),ROC曲线应运而生.简单的来说,我们既要关注分类结果在正样本的正确率(+1),同时也要兼顾分类结果在负样本的分类错误率(-1).关于ROC曲线,这里有一个很好的博客:
ROC曲线与AUC值
画ROC曲线代码如下:

#ROC曲线
def plotROC(predStrengths,classLabels):
    cur = (1.0,1.0)
    ySum = 0.0
    numPosClas = sum(array(classLabels)==1.0)#阳性样本个数
    yStep = 1/float(numPosClas)
    xStep = 1/float(len(classLabels)-numPosClas)
    sortedINdicies = predStrengths.argsort()#将predStrength从小到达排列,取index,即分类得出的几率的排序
    fig = plt.figure()
    fig.clf()
    ax = plt.subplot(111)
    for index in sortedINdicies.tolist()[0]:#sortedINdicies.tolist()[0]:返回soredINdixies的一维列表
        if classLabels[index] == 1.0:
            delX = 0;delY = yStep
        else:
            delX = xStep;delY=0
            ySum += cur[1]
        ax.plot([cur[0],cur[0]-delX],[cur[1],cur[1]-delY],'r*')
        cur = (cur[0]-delX,cur[1]-delY)
    ax.plot([0,1],[0,1],'b--')
    plt.xlabel('False Positive Rate');plt.ylabel('True Positive Rate')
    plt.title('ROC curve for AdaBoost Horse Colic Detection System')
    ax.axis([0,1,0,1])
    plt.show()
    # print("the Area Under the Curve is: ",ySum*xStep

这里写图片描述


完整代码和训练集

Github–AdaBoost

猜你喜欢

转载自blog.csdn.net/qq_28773183/article/details/81061564