机器学习十大算法之Adaboost

来源:互联网 发布:linux中的telnet命令 编辑:程序博客网 时间:2024/06/05 12:00

 

 --基本概念:


Adaboost是一种迭代算法,其核心思想是针对同一个训练集训练不同的弱分类器,然后把这些弱分类器集合起来,构成一个更强的最终分类器 (强分类器)。其算法本身是通过改变数据分布来实现的,它根据每次训练集之中每个样本的分类是否正确,以及上次的总体分类的准确率,来确定每个样本的权值。将修改过权值的新数据集送给下层分类器进行训练,最后将每次训练得到的分类器最后融合起来,作为最后的决策分类器。使用adaboost分类器可以排除一些不必要的训练数据特征,并将关键放在关键的训练数据上面。
  
该算法其实是一个简单的弱分类算法提升过程,这个过程通过不断的训练,可以提高对数据的分类能力。整个过程如下所示:
  1. 先通过对N个训练样本的学习得到第一个弱分类器 ;
  2. 将分错的样本和其他的新数据一起构成一个新的N个的训练样本,通过对这个样本的学习得到第二个弱分类器 ;
  3. 将和都分错了的样本加上其他的新样本构成另一个新的N个的训练样本,通过对这个样本的学习得到第三个弱分类器 ;
  4. 最终经过提升的强分类器 (多数表决)。
2.3 Adaboost(Adaptive Boosting)算法
对于boosting算法,存在两个问题:
  Q1. 如何调整训练集,使得在训练集上训练的弱分类器得以进行;

       Answer1: 使用加权后选取的训练数据代替随机选取的训练样本,这样将训练的焦点集中在比较难分的训练数据样本上;
  Q2. 如何将训练得到的各个弱分类器联合起来形成强分类器。
       Answer2. 将弱分类器联合起来,使用加权的投票机制代替平均投票机制。让分类效果好的弱分类器具有较大的权重,而分类效果差的分类器具有较小的权重。
  与Boosting算法不同的是,adaboost算法不需要预先知道弱学习算法学习正确率的下限即弱分类器的误差,并且最后得到的强分类器的分类精度依赖于所有弱分类器的分类精度, 这样可以深入挖掘弱分类器算法的能力。
  Adaboost算法中不同的训练集是通过调整每个样本对应的权重来实现的。开始时,每个样本对应的权重是相同的,即其中n为样本个数,在此样本分布下训练出一弱分类器 。对于分类错误的样本,加大其对应的权重;而对于分类正确的样本,降低其权重,这样分错的样本就突出来,从而得到一个新的样本分布 。在新的样本分布下,再次对弱分类器进行训练,得到弱分类器。依次类推,经过 T 次循环,得到 T 个弱分类器,把这 T 个弱分类器按一定的权重叠加(boost)起来,得到最终想要的强分类器。
  

--算法流程

 


--例子:


http://www.360doc.com/content/14/1109/12/20290918_423780183.shtml



--形象化流程:


我就把我上课报告的数据挖掘的ppt贴上来吧偷笑


Ø“+”和“-”分别表示两种类别             Ø水平或者垂直的直线作为分类器             Ø简单分类器:C4.5、ID3

弱分类器:CartSvmdecision stump【最简单等(可以最小化加权的损失函数都可以)






--Adaboost的误差界


http://www.cnblogs.com/zy230530/p/6909288.html


--算法练习

# coding:utf-8import numpy as np#加载数据def loadSimpData():    dataMat = np.matrix( [ [ 1., 2.1],[ 4., 3.1],[ 5., 1.1],[ 7., 4.1],[ 1.1, 4.1],[ 1.3, 7.1],                           [ 2., 1.1],[ 1.3, 1.],[ 1., 1. ],[ 2., 1. ] ] )    classLabels = [ 1.0, 1.0, -1.0, -1.0, 1.0,1.0, 1.0, -1.0, -1.0, 1.0 ]    return dataMat, classLabelsdef stumpClassify( dataMatrix, dimen, threshVal, threshIneq ):    '''    (数组矩阵,维度,阈值,阈值判断)    通过阈值比较对数据进行分类,所有在阈值一边的数据会分到类别-1,而在    另外一边的数据分到类别+1.        '''    retArray = np.ones( ( np.shape( dataMatrix )[ 0 ], 1 ) )    #(第一维度的长度)个1矩阵    if threshIneq == 'lt':#小于        retArray[ dataMatrix[ :, dimen ] <= threshVal ] = -1.0    else:        retArray[ dataMatrix[ :, dimen ] > threshVal ] = -1.0    return retArray#建立弱分类器(decision tree)def buildStump( dataArr, classLabels, D ):    dataMatrix = np.mat(dataArr)  #10x2    labelMat = np.mat(classLabels).T  #1x10--->10x1    m,n = np.shape(dataMatrix)# 特征数目(m=10,n=2)    numSteps = 10.0 #用于在特征的所有可能值上进行遍历    bestStump = {} #存储给定权重向量 D 时所得到的最佳单层决策树的信息    bestClassEst = np.mat( np.zeros( (m, 1) ) )  #mx1    minError = np.inf#初始值设置为无穷大    for i in range( n ):#特征的循环 n=2 ; i=1,2        # 对于每一维的特征        rangeMin = dataMatrix[:, i].min()        rangeMax = dataMatrix[:, i].max()        stepSize = ( rangeMax - rangeMin ) / numSteps        for j in range( -1, int( numSteps ) + 1 ): #从1-10个样本            # 对于每一个阈值            for inequal in [ 'lt', 'gt' ]:                #确定阈值                threshVal = rangeMin + float( j ) * stepSize                #进入到弱分类器进行分类(1次若干类)                predictedVals = stumpClassify( dataMatrix, i,threshVal, inequal )                errArr = np.mat( np.ones( ( m, 1 ) ) )                #弱分类器预测的label若等于初始化label则误差置为0                errArr[ predictedVals == labelMat ] = 0                #计算分错类的误差                weightedError = D.T * errArr                print "所有样本第%d维特征,阈值为%.2f,阈值判断类型:%s,权值误差:%.3f" %( i, threshVal, inequal, weightedError )                if weightedError < minError:                    minError =  weightedError                    bestClassEst = predictedVals.copy()                    bestStump[ 'dim' ] = i                    bestStump[ 'thresh' ] = threshVal                    bestStump[ 'ineq' ] = inequal    #返回最好的弱分类器的,最小误差,最好的预测类    return bestStump, minError, bestClassEst#Adaboost算法主体def adaBoostTrainDS(dataArr, classLabels, numIt=40):    #初始化    weakClfArr = []    m = np.shape(dataArr)[0]    D = np.mat(np.ones((m, 1)) / m)    aggClassEst = np.mat(np.zeros((m, 1)))    #进行迭代    for i in range(numIt):        # 弱分类器的训练:每一次循环 只有样本的权值分布 D 发生变化        #计算出若干弱分类器        bestStump, error, classEst = buildStump(dataArr, classLabels, D)        print " 初始化权重: ", D.T        # 计算弱分类器的权重        alpha = float(0.5 * np.log((1 - error) / max(error, 1e-16)))#对最大误差进行限制        #alpha = float(0.5 * np.log((1 - error) /error))        bestStump['alpha'] = alpha        weakClfArr.append(bestStump)        print "类别: ", classEst.T        # 更新训练数据集的权值分布(正则化)        expon = np.multiply(-1 * alpha * np.mat(classLabels).T, classEst)        D = np.multiply(D, np.exp(expon))        Zm=D.sum()        D = D /Zm        # 记录对每个样本点的类别估计的累积值        aggClassEst += alpha * classEst        print "类别估计: ", aggClassEst.T        # 计算分类错误率 true =1        aggErrors = np.multiply(np.sign(aggClassEst) != np.mat(classLabels).T, np.ones((m, 1)))        errorRate = aggErrors.sum() / m        print "误差率: ", errorRate, "\n"        # 如果完全正确,终止迭代        if errorRate == 0.0:            break    return weakClfArrif __name__ == '__main__':    datMat, classLabels = loadSimpData()    print adaBoostTrainDS(datMat, classLabels, 9)


参考资料:

http://www.360doc.com/content/14/1109/12/20290918_423780183.shtml