您的位置:首页 > 编程语言 > Python开发

Adaboost从原理到实现(Python)

2018-03-29 00:00 781 查看
源:机器学习与Python学习首先来回答AdaBoosting的基本思想通俗地讲就是综合某些专家的判断,往往要比一个专家单独的判断要好(三个臭皮匠顶过诸葛亮-周志华《机器学习第八章》)。在”强可学习”和”弱可学习”的概念上来说就是我们通过对多个弱可学习的算法进行”组合提升或者说是强化”得到一个性能赶超强可学习算法的算法。其次回答Boosting的思路
1.找到一个弱分类器,分类器简单,快捷,易操作(如果它本身就很复杂,而且效果还不错,那么进行提升无疑是锦上添花,增加复杂度,甚至上性能并没有得到提升,具体情况具体而论)。2.迭代寻找N个最优的分类器(最优的分类器,就是说这N个分类器分别是每一轮迭代中分类误差最小的分类器,并且这N个分类器组合之后是分类效果最优的。)。在迭代求解最优的过程中我们需要不断地修改数据的权重(AdaBoost中是每一轮迭代得到一个分类结果与正确分类作比较,修改那些错误分类数据的权重,减小正确分类数据的权重 ),后一个分类器根据前一个分类器的结果修改权重在进行分类,因此可以看出,迭代的过程中分类器的效果越来越好,所以需要给每个分类器赋予不同的权重。最终我们得到了N个分类器和每个分类器的权重,那么最终的分类器也得到了。归纳算法流程输入:训练数据集M*N(M为样本数量,N为特征数量)弱,其中xi表示数据i[数据i为N维],yi表示数据的分类为yi,Y={-1,1}表示xi在某种规则约束下的分类。输出:最终的分类器G(x)1. 初始化训练数据的权值分布(每个样本数据权重均等),D1 = (W11,W12,W13,...,W1M), W1i=1/M, ,M表示数据的个数,i=1,2,3…M。 2. j=1,2,3,…,J(表示迭代的次数/或者最终分类器的个数,取决于是否能够使分类误差为0)。(a)使用具有权值分布Dj的训练数据集学习,得到基本的分类器:Gj(x);(b) 计算Gj(x)在训练集上的分类误差率

求的是分错类别的数据的权重值和,表示第i个数据的权重Dj[i];(c)计算Gj(x)第j个分类器的系数,,ej表示的是分类错误率。

(d)更新训练数据集的权重Dj+1,数据集的权重根据上一次权重进行更新, i=1,2,…M

Z是规范化因子,他表示所有数据权重之和,它使Dj+1成为一个概率分布。3. 构建基本分类器的线性组合

得到最终的分类器:

Boosting与Bagging对比:AdaBoost泛化错误率低,易编码,可以应用在大部分分类器上,无参数调整,但是对离群点敏感。Bagging基于数据随机重抽样的分类器构建方法,原始数据集中重新选择S次得到S个新数据集,将磨沟算法分别作用于这个数据集,最后进行投票,选择投票最多的类别作为分类类别。Boosting关注那些已有分类器错分的数据来获得新的分类器,Bagging则是根据已训练的分类器的性能来训练的。Boosting分类器权重不相等,权重对应与上一轮迭代成功度Bagging分类器权重相等。代码实现(由《机器学习实战》改编)# -*- coding:utf-8 -*- from numpy import*class Adaboosting(object):    def loadSimpData(self):        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
    def stumpClassify(self, datMat, dimen, threshVal, threshIneq):        # print "-----data-----"        # print datMat        retArr = ones((shape(datMat)[0], 1))          if threshIneq == 'lt':            retArr[datMat[:, dimen] <= threshVal] = -1.0  # 小于阈值的列都为-1        else:            retArr[datMat[:, dimen] > threshVal] = -1.0  # 大于阈值的列都为-1        # print "---------retArr------------"        # print retArr
4000
        return retArr
    def buildStump(self, dataArr, classLables, D):        """        单层决策树生成函数        """        dataMatrix = mat(dataArr)        lableMat = mat(classLables).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            # j唯一的作用用步数去生成阈值,从最小值大最大值都与数据比较一边了一遍            for j in range(-1, int(numSteps) + 1):                threshVal = rangeMin + float(j) * stepSize  # 阈值                for inequal in ['lt', 'gt']:                    predictedVals = self.stumpClassify(                        dataMatrix, i, threshVal, inequal)                    errArr = mat(ones((m, 1)))                    errArr[predictedVals == lableMat] = 0  # 为1的 表示i分错的                    weightedError = D.T * errArr  # 分错的个数*权重(开始权重=1/M行)                    # print "split: dim %d, thresh %.2f, thresh ineqal:\#%s,the weighted error is %.3f" % (i, threshVal, inequal, weightedError)                    if weightedError < minError:  # 寻找最小的加权错误率然后保存当前的信息                        minError = weightedError                        bestClassEst = predictedVals.copy()  # 分类结果                        bestStump['dim'] = i                        bestStump['thresh'] = threshVal                        bestStump['ineq'] = inequal        # print bestStump        # print minError        # print bestClassEst  # 类别估计        return bestStump, minError, bestClassEst
    def adaBoostingDs(self, dataArr, classLables, numIt=40):        """        基于单层决策树的AdaBoosting训练过程:        """        weakClassArr = []  # 最佳决策树数组        m = shape(dataArr)[0]        D = mat(ones((m, 1)) / m)        aggClassEst = mat(zeros((m, 1)))        for i in range(numIt):            bestStump, minError, bestClassEst = self.buildStump(                dataArr, classLables, D)            print "bestStump:", bestStump            print "D:", D.T            alpha = float(                0.5 * log((1.0 - minError) / max(minError, 1e-16)))            bestStump['alpha'] = alpha            weakClassArr.append(bestStump)            print "alpha:", alpha            print "classEst:", bestClassEst.T  # 类别估计
            expon = multiply(-1 * alpha * mat(classLables).T, bestClassEst)            D = multiply(D, exp(expon))            D = D / D.sum()
            aggClassEst += alpha * bestClassEst            print "aggClassEst ;", aggClassEst.T            # 累加错误率            aggErrors = multiply(sign(aggClassEst) !=                                 mat(classLables).T, ones((m, 1)))            # 错误率平均值            errorsRate = aggErrors.sum() / m            print "total error:", errorsRate, "\n"            if errorsRate == 0.0:                break        print "weakClassArr:", weakClassArr        return weakClassArr
    def adClassify(self, datToClass, classifierArr):        """        预测分类:        datToClass:待分类数据        classifierArr: 训练好的分类器数组        """        dataMatrix = mat(datToClass)        m = shape(dataMatrix)[0]        aggClassEst = mat(zeros((m, 1)))        print        for i in range(len(classifierArr)):  # 有多少个分类器迭代多少次            # 调用第一个分类器进行分类            classEst = self.stumpClassify(dataMatrix, classifierArr[i]['dim'],                                          classifierArr[i]['thresh'],                                          classifierArr[i]['ineq']                                          )            # alpha 表示每个分类器的权重,            print classEst            aggClassEst += classifierArr[i]['alpha'] * classEst            print aggClassEst        return sign(aggClassEst)

if __name__ == "__main__":    adaboosting = Adaboosting()    D = mat(ones((5, 1)) / 5)    dataMat, lableMat = adaboosting.loadSimpData()    # 训练分类器    classifierArr = adaboosting.adaBoostingDs(dataMat, lableMat, 40)    # 预测数据    result = adaboosting.adClassify([0, 0], classifierArr)    print result


加入Python学习微信交流群
请添加微信:AI_doer备注:姓名-单位-研究方向这九位中国人工智能领域杰出女性,你应该知道
关注两会 | 人工智能发展战略
今日头条算法原理(全)深度学习对话系统理论篇--数据集和评价指标介绍
三步走——带你打造一份完美的数据科学求职简历
高盛:79页区块链报告-《从理论到实践》(附下载)
Learn with Google AI上线了! 让Google专家教你AI新技术



请猛戳右边二维码

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: