AdaBoost

1 AdaBoost算法总结

   AdaBoost算法:通过样本来训练数据,主要是将训练过程中分类正确的样本点权值降低,反之则增加;各个弱分类器训练结束后加大分类错误率小的权重,反之增加权重。最终构成各个分类能力较强的分类器。

2 AdaBoost的应用场景和优缺点

   应用场景:1)用于二分类或多分类的应用场景;2)用于做分类任务的baseline;3)用于特征选择(feature selection)等

   优点:1)很好的利用了弱分类器进行级联;2)可以将不同的分类算法作为弱分类器;3)AdaBoost具有很高的精度;4)相对于bagging算法和Random Forest算法,AdaBoost充分考虑的每个分类器的权重等

   缺点:1) AdaBoost迭代次数也就是弱分类器数目不太好设定,可以使用交叉验证来进行确定; 2) 数据不平衡导致分类精度下降;3) 训练比较耗时,每次重新选择当前分类器最好切分点等

3 AdaBoost的算法过程

       通过训练样本将弱的的分类器进行叠加,用残差缩小的来提高分类的准确性。样本通过对错误率的计算,不断改变权值,然后对弱分类器也改变权重,最终变成一个强的分类器。

4 具体实例

  4.1 实现简单数据数据的分类

from numpy import *

'''
#添加数据函数
'''
def loadSimpData():
    datMat = matrix([[ 1. ,  2.1],  #创建数据
        [ 2. ,  1.1],
        [ 1.3,  1. ],
        [ 1. ,  1. ],
        [ 2. ,  1. ]])
    classLabels = [1.0, 1.0, -1.0, -1.0, 1.0] #数据标签列
    return datMat,classLabels #返回数据和标签

'''
#找到最低错误率的单层决策树
 # dataMatrix : 输入数据矩阵
 # dimen      : 维度
 # threshVal  : 阈值
 # threshIneq : 决定不等号的大小
'''	
def stumpClassify(dataMatrix,dimen,threshVal,threshIneq):
    retArray = ones((shape(dataMatrix)[0],1)) #读取其行列,构建以行为长度的单位向量
    if threshIneq == 'lt':  #然后根据阈值和不等号将满足要求的都设为-1
        retArray[dataMatrix[:,dimen] <= threshVal] = -1.0
    else:
        retArray[dataMatrix[:,dimen] > threshVal] = -1.0
    return retArray
    
'''
#通过阈值对数据分类函数
 # dataArr     : 输入数据矩阵
 # classLabels : 输入数据标签
 # D           : 数据集权重 用于计算加权错误率
'''	
def buildStump(dataArr,classLabels,D):
    dataMatrix = mat(dataArr); # mat()转换成矩阵类型
	#将标签列表转置成一个行向量
	labelMat = mat(classLabels).T
    m,n = shape(dataMatrix)  # 得到数据矩阵的大小m行,n列
    numSteps = 10.0;         #初始化步数,用于在特征的所有可能值上进行遍历
	bestStump = {};          #存储给定权重向量 D 时所得到的最佳单层决策树的信息
	bestClasEst = mat(zeros((m,1))) #初始化类别估计值
    minError = inf       #最小误差率初值设为无穷大
    for i in range(n):   #第一层循环 对数据集中的每一个特征 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)   #计算阈值
				#通过阈值比较对数据进行分类
                predictedVals = stumpClassify(dataMatrix,i,threshVal,inequal)
                errArr = mat(ones((m,1)))   #初始化错误计数向量
                errArr[predictedVals == labelMat] = 0 #然后把预测结果正确的标记为0
                weightedError = D.T*errArr   #计算权值误差,这就是AdaBoost和分类器交互的地方
                #将加权错误率最小的结果保存下来
				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 #分类结果,最小错误率,最佳单层决策树


'''
#ada的训练函数
 # dataArr     : 输入数据矩阵
 # classLabels : 输入数据标签
 # numIt       : 迭代次数
'''	
def adaBoostTrainDS(dataArr,classLabels,numIt=40):
    weakClassArr = [] #初始化列表,用来存放单层决策树的信息
    m = shape(dataArr)[0] #获取数据集行数
    D = mat(ones((m,1))/m)   #初始化向量D每个值均为1/m,D包含每个数据点的权重
    aggClassEst = mat(zeros((m,1))) #初始化列向量,记录每个数据点的类别估计累计值
    for i in range(numIt):   #开始迭代
	    #利用buildStump()函数找到最佳的单层决策树
        bestStump,error,classEst = buildStump(dataArr,classLabels,D)
        #print "D:",D.T
		#根据公式计算alpha的值,max(error, 1e-16)用来确保在没有错误时不会发生除零溢出
        alpha = float(0.5*log((1.0-error)/max(error,1e-16)))
        bestStump['alpha'] = alpha  #保存alpha的值
        weakClassArr.append(bestStump) #填入数据到列表                
        #print "classEst: ",classEst.T
		#为下一次迭代计算D
        expon = multiply(-1*alpha*mat(classLabels).T,classEst) 
        D = multiply(D,exp(expon))                              
        D = D/D.sum()
		#累加类别估计值
        aggClassEst += alpha*classEst
        #print "aggClassEst: ",aggClassEst.T
		#计算错误率,aggClassEst本身是浮点数,需要通过sign来得到二分类结果
        aggErrors = multiply(sign(aggClassEst) != mat(classLabels).T,ones((m,1)))
        errorRate = aggErrors.sum()/m
        print ("total error: ",errorRate)
		#如果总错误率为0则跳出循环
        if errorRate == 0.0: break
    return weakClassArr,aggClassEst #返回单层决策树列表和累计错误率

'''
#ada的分类函数
 # datToClass    : 输入待分类库数据矩阵
 # classifierArr : 多个弱分类器组成的数组
'''	
def adaClassify(datToClass,classifierArr):
    dataMatrix = mat(datToClass) #初始化数据集
    m = shape(dataMatrix)[0]     #获得待分类样例个数
    aggClassEst = mat(zeros((m,1)))  #构建一个初始化为0的列向量,记录每个数据点的类别估计累计值
    for i in range(len(classifierArr)):  #遍历每个弱分类器
	    #基于stumpClassify得到类别估计值
        classEst = stumpClassify(dataMatrix,classifierArr[i]['dim'],\
                                 classifierArr[i]['thresh'],\
                                 classifierArr[i]['ineq'])
		#累加类别估计值						 
        aggClassEst += classifierArr[i]['alpha']*classEst  
        print (aggClassEst)
    return sign(aggClassEst) #返回分类结果,aggClassEst大于0则返回+1,否则返回-1

以上程序可以在jupyter中实现,可以实现简单数据的分类,类别分别用0和1进行表示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值