机器学习实战之利用AdaBoost元算法提高性能

1、算法原理

当做重要决定时,我们往往不会只听从一个人的意见,而是听从很多人的意见,这就是元算法的思路。

Boosting:使用多个弱分类器,来构建一个强的分类器。不同的分类器是通过串行训练(先产生的分类器,用于后产生的分类器的产生过程中)获得的,每个新的分类器都是根据已训练出的分类器的性能来进行训练。boosting是通过集中关注被已有分类器错分的那些数据来获得新的分类器。

boosting分类的结果是基于所有的分类器加权求和得到的。每个分类器都有不同的权重。

2、训练算法

adaboost的训练过程如下:训练数据中的每个样本,并赋予其一个权重,这些权重构成了向量D。一开始,这些权重都初始化成相等值。首先在训练数据上训练出一个弱分类器并计算该分类器的错误率,然后在同一数据集上再次训练弱分类器。在分类器的第二次训练中,将会重新调整每个样本数据的权重,其中第一次分对的样本的权重将会降低,分错的样本的权重将会提高。为了从所有弱分类器中得到最终的分类结果,AdaBoost为每个分类器都分配了一个权重值alpha。这些alpha是基于每个弱分类器的错误率进行计算的。

错误率

                                    \varepsilon = 未分类的样本数目  /  所有样本数目

alpha的计算公式为:   \alpha = ln\left ((1-\varepsilon )/\varepsilon \right )/2

如果某个样本被正确分类  D_{i}^{t+1} =D _{i}^{t}e^{-a}/sum(D)

如何某个样本被错分 D_{i}^{t+1} =D _{i}^{t}e^{a}/sum(D)

代码:

def stumpclassify(datamatrix,dimen,threshval,threshineq):#通过阈值比较对数据进行分类
    retarray = ones((shape(datamatrix)[0],1))
    if threshineq == 'lt':
        retarray[datamatrix[:,dimen] <= threshval] = -1.0
    else:
        retarray[datamatrix[:,dimen] > threshval] = -1.0
    return retarray

def buildstump(dataarr,classlabels,D):#选择单层最优决策树
    datamatrix = mat(dataarr)
    labelmat = mat(classlabels).T
    m,n = shape(datamatrix)
    numsteps = 10.0 ;beststump = {}; bestclassest=  mat(zeros((m,1)))
    minerror = inf
    for i in range(n):
        rangemin = datamatrix[:,i].min() ;rangemax = datamatrix[:,i].max()
        stepsize  = (rangemax - rangemin) /numsteps
        for j in range(-1,int(numsteps) + 1):
            for inequal in ['lt','gt']:
                threshval = (rangemin + float(j)*stepsize)
                pridictedvals = stumpclassify(datamatrix,i, threshval,inequal)
                errorarr = mat(ones((m,1)))
                errorarr[pridictedvals == labelmat] = 0
                weightederror = D.T*errorarr

                if weightederror < minerror:
                    minerror = weightederror
                    bestclassest = pridictedvals.copy()
                    beststump['dim'] = i
                    beststump['thresh'] = threshval
                    beststump['ineq'] = inequal
    return beststump,minerror,bestclassest

3、完整AdaBoost算法的实现

通过对D的改变,生成多棵决策树。如果当前决策树的错误率等于0,或者超过设定的决策次数,就退出循环。执行完代码得到一组弱分类器

def adaboosttrains(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)))
        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)))
        errorate = aggerrors.sum()/m
        print ("total error:",errorate,"\n")
        if errorate == 0.0: break
    return weakclassarr

4、基于AdaBoost的分类

用数据集和得到的弱分类器集合去测试分类效果

def adaclassify(datatoclass, classifierarr):
        datamatrix = mat(datatoclass)
        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'])
            aggclassest += classifierarr[i]['alpha']*classest
            print (aggclassest)
        return sign(aggclassest)

猜你喜欢

转载自blog.csdn.net/qq_41482837/article/details/82021095