集成方法(Boosting:以AdaBoost为例)原理以及实现

集成方法(boosting又称为提升方法)

提升方法重要概念

  • 1.思路:三个臭皮匠顶个诸葛亮
  • 2.重要概念:
    PAC:(Probably approximately correct):概率近似正确
    强可学习:PAC中,面对假设模型,如果存在一个多项式的学习算法能够学习它,且正确率很高,那么这个概念就是强可学习
    弱可学习:PAC中,面对假设模型,如果存在一个多项式的学习算法能够学习它,且正确率仅仅比随机猜测好,那么这个概念就是弱可学习
    注意:强可学习实质上等价于弱可学习

在PAC学习的框架下,一个概念是强可学习的充分必要条件是这个概念是弱可学习的

问题: 弱可学习如果提升为强可学习?

  • 方案:对分类问题而言,提升方法就是弱学习算法出发,反复学习,得出一系列弱分类器,组合这些弱分类器,构成一个强分类器,
  • 提升方法:为改变训练数据的概率分布(训练数据的权值分布),针对不同的训练数据调用弱分类器算法

  • 给出方案之后,提升方法的两个问题?
    1.在每一轮中如何改变训练数据的权值或概率分布
    2.如何将弱分类器组合成一个强分类器

AdaBoost给出的解决方案
1.提高那些被前一轮弱分类器错误分类样本的权值,降低被正确分类的样本权值
2.加权多数表决的方法 将弱分类器线性组合起来

AdaBoost

Input:DataSet T={(x1,y2),(x2,y2),...,(xn,yn)}xiχR,yiY=1,+1,T={(x1,y2),(x2,y2),...,(xn,yn)}xi∈χ⊆R,yi∈Y=−1,+1,弱学习分类器
Output:G(x)最终分类算法G(x)

算法实现过程:

step1: 初始化训练数据的权值分布
D1=(W11,W12,...,W1i,W1N),W1i=1N,i=1,2,...,ND1=(W11,W12,...,W1i,W1N),W1i=1N,i=1,2,...,N

step2: m=1,2,.....,M对m=1,2,.....,M, 表示有m个弱分类器

  • (a) 使用具有权值分布DmDm的训练数据集学习,得到基本m个基本分类器
    Gm(x):X>1,+1Gm(x):X−>−1,+1
  • (b) 计算Gm(x)Gm(x)在训练集上的分类误差率
    em=P(Gmxiyi=i=1NWmiI(Gm(x)yi)em=P(Gmxi≠yi=∑i=1NWmiI(Gm(x)≠yi)
    实质上是错分数据的权值之和
  • (c) 计算Gm(x)Gm(x)的系数
    αm=12log1ememαm=12log⁡1−emem
  • (d) 更新训练数据集的权值分布
    D(m+1)=(Wm+1,1,Wm+1,2,....,Wm+1,i,.......,Wm+1,ND(m+1)=(Wm+1,1,Wm+1,2,....,Wm+1,i,.......,Wm+1,N
    Wm+1,i=WmiZmexp(αmyiGm(xi))Wm+1,i=WmiZmexp(−αmyiGm(xi))
    实质上是:指数惩罚函数
    yi==Gm(xi):yiGm(xi)=1,αmyiGm(xi)<0,当yi==Gm(xi)时:yiGm(xi)=1,即−αmyiGm(xi)<0,权重减小
    yi!=Gm(xi):yiGm(xi)=1,αmyiGm(xi)>0,当yi!=Gm(xi)时:yiGm(xi)=−1,即−αmyiGm(xi)>0,权重增加

    ZmZm=i=1NWmiexp(alphayiGm(xi))Zm是规范化因子Zm=∑i=1NWmiexp⁡(−alphayiGm(xi))
    这样更新训练数据的权值分布Dm+1Dm+1

step3:构建基本分类器的线性组合
f(x)=m=1MαmGm(x)f(x)=∑m=1MαmGm(x)
得出最终分类器:
G(x)=sign(f(x))=sign(m=1MαmGm(x))G(x)=sign(f(x))=sign(∑m=1MαmGm(x))

AdaBoost算法说明

(1) 假设训练数据集具有均匀的权值分布,即每个训练样本在基本分类器的学习中作用相同===》在此基础上,首先得出基本分类器
(2) AdaBoostAdaBoost反复学习基本分类器,在每一轮m=1,2,...,Mm=1,2,...,M顺次的执行下列操作:

  • (a)使用当前分布DmDm加权的训练数据集,学习基本分类器Gm(x)Gm(x)
  • (b)计算基本分类器Gm(x)Gm(x)在加权训练集上的分类误差率
    em=P(Gm(xi)yi)=Gm(xi)yiWmiem=P(Gm(xi)≠yi)=∑Gm(xi)≠yiWmi
    Wmim,i,i=1NWmi=1Wmi表示在第m轮更新中,第i个实例的权值,∑i=1NWmi=1
    表明:Gm(x)Gm(x)在加权的训练数据集上的分类误差率是被Gm(x)Gm(x)误分类样本的权值之和,由此确定数据权值分布DmDm与基本分类器Gm(x)Gm(x)的分类误差率的关系
  • (c)计算基本分类器Gm(x)αm,αmGm(x)Gm(x)的系数αm,αm表示Gm(x)在最终分类器中的重要性
    αm=12log1ememαm=12log⁡1−emem
    性质: 当em12,αm0,αmem,em≤12时,αm≥0,并且αm随着em的减小而增大,所有分类误差率越小的基本分类器在最终分类器中的作用越大

  • (d)更新训练数据的权值分布为下一轮做准备
    Wm+1,i=WmiZmeαm,Gmxi=yiWm+1,i=WmiZme−αm,Gmxi=yi
    Wm+1,i=WmiZmeαm,Gmxi=yiWm+1,i=WmiZmeαm,Gmxi=yi
    Zm=i=1NWmiexp(alphayiGm(xi))Zm=∑i=1NWmiexp⁡(−alphayiGm(xi))

即: 在上述的迭代更新中, 被基本分类器Gm(x)Gm(x)误分类样本的权值得以扩大,而被正确分类样本的权值得以缩小,实质上e2αm=em1eme2αm=em1−em,使得误分类样本的作用在下一轮的作用中变得更好
不改变训练数据而改变权值分布, 使得训练数据在基本分类器中其不同的作用

(3)线性组合f(x)M,αmGm(x),:αm1f(x)实现M个基本分类器的加权表决,系数αm表示基本分类器Gm(x)的重要性,注意:这里∑αm≠1
- f(x)xf(x)的符号决定实例x的类
- f(x)f(x)的绝对值表示分类的确信度
最终: 利用基本分类器的线性组合构建最终分类器

例题及adaboost算法实现:

这里写图片描述

import numpy as np

D = None
fx = dict()


def loadDataSet(filename):
    dataSet, labelMat = list(), list()
    with open(filename, 'r') as fr:
        for line in fr.readlines():
            dataSet.append([int(line.split(',')[0])])
            labelMat.append([int(line.split(',')[1])])

    return np.mat(dataSet), np.mat(labelMat)


# 三个弱分类器
def weekClassify1(x):
    if x < 2.5:
        return 1
    elif x > 2.5:
        return -1


def weekClassify2(x):
    if x < 8.5:
        return 1
    elif x > 8.5:
        return -1


def weekClassify3(x):
    if x > 5.5:
        return 1
    elif x < 5.5:
        return -1


def calcErrorRate(dataSet, labelMat, func):
    dataSize = np.shape(labelMat)[0]

    errorIndex = list()
    for index in range(len(dataSet)):
        predict = func(dataSet[index])
        if predict * labelMat[index] < 0:
            errorIndex.append(index)
    return errorIndex


def adaBoost(dataSet, labelMat, funcList):
    """

    :param dataSet: 训练数据集 input  特征值
    :param labelMat: 训练数据集 output 类标记
    :param funcList: 弱分类器的列表集合
    :return
        fx 字典形式的基本分类器的线性组合
    """
    # step1 初始化训练数据的权值分布
    global D
    global fx
    if D is None:
        dataSize = np.shape(labelMat)[0]
        D = np.ones((dataSize, 1)) / dataSize
        print(D)  # [[0.1], [0.1], [0.1].....[0.1]]
    else:

        # step2 对m=1,2,....,M
        # (a) 使用具有权值分布D的训练数据集学习 得到基本分类器 Gm(x)
        # funcList = [weekClassify1, weekClassify2, weekClassify3]
        # print(funcList)

        # (b) 计算Gm(x)在训练数据集上的分类误差率 = 错分类数据权值之和

        # fx 基本分类器的线性组合

        errorRateList = list()
        errorIndexList = list()
        for funcIndex in range(len(funcList)):
            errorIndex = calcErrorRate(dataSet, labelMat, funcList[funcIndex])
            errorIndexList.append(errorIndex)
            errorRate = 0

            for index in errorIndex:
                errorRate += float(D[index])
            print('errorRate:', errorRate)
            errorRateList.append(errorRate)


            # print('min_errorRate', min_errorRate)
            # (c) 计算Gm(x)的系数   选择弱分类器中错分率最低的分类器 优先计算系数
        min_errorRate = min(errorRateList)
        min_funcIndex = errorRateList.index(min_errorRate)
        print('min_errorRate', min_errorRate)
        print('min_funcIndex', min_funcIndex)
        print('错分率最低的分类器索引', min_funcIndex)
        alpha = (1 / 2) * np.log((1 - min_errorRate) / min_errorRate)
        # print('alpha1', alpha)


        # print('alpha2', alpha)
        print('计算Gm(x)的系数', alpha)
        # (d) 更新训练数据的权值分布
        print(errorIndexList[min_funcIndex])
        print('更新权重')
        for indexD in range(len(D)):
            if indexD in errorIndexList[min_funcIndex]:
                # print('D indexD', D[indexD])
                D[indexD] = D[indexD] / (2 * min_errorRate)
            else:
                D[indexD] = D[indexD] / (2 * (1 - min_errorRate))
        print(D)
        # step 3 构建基本分类器的线性组合
        print('构建基本分类器的线性组合')
        fx[alpha] = funcList[min_funcIndex]
        # print('fx', fx)
        sign_errorIndex = strongClassify(fx, dataSet, labelMat)
        sign_errorRate = (1 - (float(len(sign_errorIndex)) / len(labelMat))) * 100
        if sign_errorRate > 90.00:
            print("最终分类器正确率率大于0.9, 正确率为%.2f %%" % sign_errorRate)
            # print('fx:', fx)
            return fx
        else:
            print("当前最终分类器正确率为%.2f %%" % sign_errorRate)
            print('当前最终分类器误分类个数为: %d' % len(sign_errorIndex))
            print('继续优化最终分类器fx:', fx)



    return adaBoost(dataSet, labelMat, funcList)



# 最终分类器
def sign(fx, testData):
    result = 0
    for key, value in fx.items():
        result += key * value(testData)
    if result > 0:
        result = 1
    else:
        result = -1

    return result


# 强分类器验证
def strongClassify(fx, testData, labelMat):

    errorIndex = list()
    for index in range(len(testData)):
        predict = sign(fx, testData[index])
        # print(predict)
        if predict != float(labelMat[index]):

            errorIndex.append(index)

    print('strongClassify errorIndex', errorIndex)
    return errorIndex


def main():
    filename = 'test.txt'
    dataSet, labelMat = loadDataSet(filename)
    funcList = [weekClassify1, weekClassify2, weekClassify3]
    fx = adaBoost(dataSet, labelMat, funcList)
    print(fx)
    # correctRate = strongClassify(fx, dataSet, labelMat)
    # print('AdaBoost StrongClassify CorrectRate:%.2f %%' % correctRate)


if __name__ == '__main__':
    main()

AdaBoost算法误差分析

从定理中化简:训练数据的权值分布公式以及ZmZm规范化因子公式

二分类问题Adaboost的训练误差界

Zm=i=1NWmiexp(alphayiGm(xi))Zm=∑i=1NWmiexp⁡(−alphayiGm(xi))
此时存在两种情况::yi=Gm(xi)yi!=Gm(xi)第一种:yi=Gm(xi)第二种:yi!=Gm(xi)

即: Zm=y=Gm(x)Wmieαm+yGm(x)Wmieαm=(1em)expαm+emexpαm=2e(m1em)=14r2mZm=∑y=Gm(x)Wmie−αm+∑y≠Gm(x)Wmieαm=(1−em)exp−αm+emexpαm=2em(1−em)=1−4r2m

其中em(),rm=12emem为误分类权重之和(误分类率),rm=12−em
定理:在二分问题中Adaboost的训练误差为:
m=1MZm=m=1M[2em(1em)=m=1M(14r2m)exp(2m=1Mr2m)∏m=1MZm=∏m=1M[2em(1−em)=∏m=1M(1−4rm2)≤exp⁡(−2∑m=1Mrm2)

Zm,ex1xx=0使前三项展开Zm可得,后两项由ex和1−x在x=0时使用泰勒公式展开推导可得

又由公式:zm=2em(1em)zm=2em(1−em)带入更新训练数据的权值分布中可得
重点:
Gm(xi)=yi,Wm+1,i=Wmi2(1em)Gm(xi)!=yi,Wm+1,i=Wmi2em当Gm(xi)=yi时,Wm+1,i=Wmi2(1−em)当Gm(xi)!=yi时,Wm+1,i=Wmi2em

定理: AdaBoost的训练误差界

1Ni=1N(G(xi)yi)1Niexp(yif(xi))=mZm1N∑i=1N(G(xi)≠yi)≤1N∑iexp(−yif(xi))=∏mZm

其中:G(x)=sign(f(x))=sign(m=1MαmGm(x),f(x)=m=1MαmGm(x),Zm=i=1NWmiexp(alphamyiGm(xi)),G(x)=sign(f(x))=sign(∑m=1MαmGm(x),最终分类器f(x)=∑m=1MαmGm(x),系数∗基本分类器Zm=∑i=1NWmiexp(−alphamyiGm(xi)),规范化因子
证明: G(xi)yi,yif(xi)0,exp(yif(xi))1当G(xi)≠yi时,yif(xi)≤0,此时exp(−yif(xi))≥1
后两项由ZmZm定义式可证明
Zm=i=1NWmiexp(alphayiGm(xi))Zm=∑i=1NWmiexp⁡(−alphayiGm(xi))
将该式变化可得:Zm+1,i=Wmiexp(alphamyiGm(xi)Zm+1,i=Wmiexp(−alphamyiGm(xi)
可证:
1Niexp(yif(xi))=1Niexp(m=1MαmGm(xi)yi=iW1im=1Mexp(αmyiGm(xi))=Z1iW1im=1Mexp(αmyiGm(xi))=m=1MZm1N∑iexp(−yif(xi))=1N∑iexp(−∑m=1MαmGm(xi)yi=∑iW1i∏m=1Mexp(−αmyiGm(xi))=Z1∑iW1i∏m=1Mexp(−αmyiGm(xi))=∏m=1MZm

该定理说明: 在AdaBoost中只关注训练误差界的上确界,并且通过不断的选取适当的GmGm可以使得ZmZm最小,从而使得训练误差最小

参考文献
《统计学习方法》李航著;

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值