您的位置:首页 > 其它

《机器学习实战》笔记之七——利用AdaBoost元算法提高分类性能

2017-12-22 21:54 423 查看
第七章 利用AdaBoost元算法提高分类性能


7.1 基于数据集多重抽样的分类器

基于数据集多重抽样的分类器

集成方法(ensemble method)或者元算法(meta-algorithm):将不同的分类器组合起来。使用集成方法时会有多种形式:可以是不同算法的集成,也可以是同一算法在不同设置下的集成,还可以是数据集不同部分分配给不同分类器之后的集成。

bagging:基于数据随机重抽样的分类器构建方法

自举汇聚法(bootstrap aggregating),也即bagging方法:从原始数据集选择S次后得到S个新数据集的一种计数。S个新数据集和原始数据集的大小相等,每个数据集都是通过原始数据集中随机选择一个样本来进行替换而得到的。在S个数据集建好之后,将某个学习算法分别作用于每个数据集就得到了S个分类器。当我们要对新数据进行分类时,就可以应用这S个分类器进行分类。选择分类器投票结果中最多的类别作为最后的分类结果。

boosting

boosting是通过集中关注被已有分类器错分的那些数据来获得新的分类器。boosting分类的结果是基于所有分类器的加权求和结果的,分类器每个权重代表的是其对应分类器在上一轮迭代中的成功度。而bagging中的分类器权重是相等的。这里关注boosting最流行的版本AdaBoost。


7.2 训练算法:基于错误提升分类器的性能

AdaBoost(adaptive boosting):训练数据中的每个样本,并赋予其一个权重,这些权重构成了向量D。一开始,这些权重都初始化成相等值。首先在训练数据上训练出一个弱分类器并计算该分类器的错误率,然后在同一数据集上再次训练弱分类器。重新调整每个样本的权重,第一次分对的样本的权重将会降低,分错的样本的权重将会提高。AdaBoost为每个分类器都分配了一个权重值alpha,其基于每个弱分类器的错误率进行计算的。错误率的定义:



alpha的计算公式:



AdaBoost算法的流程图



对权重向量D更新,如果某个样本被正确分类,那么该样本的权重改为:



如果被错分,样本权重为:



计算出D后,AdaBoost继续迭代重复训练调整权重,直到训练错误率为0或者弱分类器的数据达到用户指定值为止。


7.3 基于单层决策树构建弱分类器

单层决策树(decision stump):基于单个特征来做决策。只有一次分裂过程。通过使用多颗单层决策树,就可以构建出一个能够对该数据集完全正确分类的分类器。



伪代码:

将最小错误率minError设为正无穷

对数据集中的每一个特征

对每个步长

对每个不等号

建立一颗单层决策树并利用加权数据集对它进行测试

如果错误率低于minError,则将当前单层决策树设为最佳单层决策树

返回最佳单层决策树

coding:

[python] view
plain copy

#!/usr/bin/env python  

# coding=utf-8  

from numpy import *  

import matplotlib.pyplot as plt  

  

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  

  

#===========单层决策树生成函数=======================  

def stumpClassify(dataMatrix, dimen, threshVal, threshIneq):  

    retArray = ones((shape(dataMatrix)[0],1))  

    if threshIneq == "lt":  

        retArray[dataMatrix[:,dimen] <= threshVal] = -1.0       #对dimen维的所有值小于等于阈值  

    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  

                predictedVals = stumpClassify(dataMatrix, i, threshVal, inequal)#对于大于和小于两种情况都预测数据的类别  

                errArr        = mat(ones((m,1)))  

                errArr[predictedVals == labelMat] = 0               #预测对了,误差为0,否则为1  

                weightedError                     = D.T*errArr      #计算权重误差  

                print "split: dim %d, thresh %.2f, thresh inequal: %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  

    return bestStump, minError, bestClassEst  

  

  

datMat, classLabels = loadSimpData()  

D = mat(ones((5,1))/5)  

print buildStump(datMat, classLabels, D)  

效果:



Figure 7-2: 单层决策树构建的结果

buildStump函数得到构建AdaBoost算法需要所有信息,字典、错误率、类别估计值等。


7.4 完整AdaBoost算法的实现

伪代码

对每次迭代:

利用buildStump()函数找到最佳的单层决策树

将最佳单层决策树加入到单层决策树数组

计算alpha

计算新的权重向量D

更新累计类别估计值

如果错误率等于0.0,则退出循环

coding

[python] view
plain copy

#=======基于单层决策树的AdaBoost训练过程=====================  

def adaBoostTrainDS(dataArr, classLabels, numIt = 40):              #DS:decision stump单层决策树,  

    weakClassArr = []  

    m = shape(dataArr)[0]  

    D = mat(ones((m,1))/m)                                          #初始权重  

    aggClassEst = mat(zeros((m,<span class="number" style="box-sizing: border-box; margin: 0px; padding: 0px;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: