机器学习实战——组合方法与AdaBoost

对于分类问题,在给定数据集前提下,训练比较粗糙的弱分类器比精确的强分类器容易得多。另外,Schapire证明了强可学习与弱可学习是等价的,因此首先学习简单的弱分类器,并进行组合就可以得到强分类器,这就是组合方法的理论基础。

组合(Ensemble)方法是一种提高分类准确率的方法,是一个由多个弱分类器组合的复合模型,其中每个单个分类器都进行投票,组合分类器返回最终组合的结果,这样分类的结果比单个分类器的结果更准确。

组合分类常见的方式有bagging(套袋)、boosting(提升)、random forest(随机森林)。这些方法使用给定的数据集D使用不同的方法创建k个训练集D1,D2...Dk,对每一个数据集Di使用确定的方法创建一个分类器Mi,最终组合分类器将学习到的k个模型使用不同的方式组合在一起,创建一个复合模型。通过上面的描述,可以发现,组合分类方法的关键点如下:

1. 生成k个训练集的方法

2. 每个分类器的训练算法

3. 组合k分类器的方式

bagging使用有放回抽样的方式,从训练集中抽取N次,形成一个和源数据大小相同的数据集,这样重复进行k轮,就可以得到k个训练集。由于是有放回抽样,因此原始数据集中有些样本可能不会出现在Di中,而有些样本可能出现很多次,一个样本被抽取作为训练集的概率为1N,因此不被抽中的为1?1N,抽取N次都不能被抽中的概率为:

(1?1N)N?limN→∞(1?1N)N=e?1≈0.368

因此可以将最终的没有出现在训练集中的36.8%的数据作为测试集进行检验。至于每个分类器的学习算法可以使用决策树、后向传播等算法。组合时采用多数表决方式进行。

random forest也是使用上述有放回抽样的方式得到训练集,但是在每个分类器训练时采用的是构建决策树,使用CART算法进行增长,随机选择给定个属性进行构建,不进行剪枝,称为Forest-RI。还有另外一种形式是对输入属性进行随机线性组合,产生多个线性组合找到最佳划分从而构建决策树。最终进行分类时每一课决策树都进行投票,返回得票数最多的类别。

boosting方法则是对每个训练的样本赋予一个权重,通过每次训练改变每个样本的权重(也就是训练数据的概率分布)得到新的训练集,没有前面所述的有放回抽样得到k训练集的过程,只是进行改变权重的过程进行迭代学习k次,相当于是得到了k个训练集和分类器,每个分类器Mi更新权重之后,将其错分类的样本赋予更高的权重,使得Mi+1分类器更加关注错分的样本。最终组合的分类器是每个分类器的加权结果,这个权重是相应分类器分类的准确率的函数。不同于bagging的组合方式中每个分类器是一样的权重进行投票的。

本文重点关注的是使用最广泛也是被很多人称为最好的监督学习方法——AdaBoost方法,这是一种最流行的boosting方法。

AdaBoost策略

给定训练数据D={(X1,Y1),(X2,Y2),...(XN,YN)},Yj∈{+1,?1}属于二分类问题。初始条件下,赋予每个样本(Xj,Yj)相等的权重w(j)i=1N(下标为训练的轮数,上标为样本标号),也就是数据是均匀分布的。

1. 每一轮如何改变训练数据的权值(概率分布)

第i轮训练中,得到分类器Mi,使用该分类器计算错误率erri:

erri=∑j=1Nw(j)iI(Mi(Xj)≠Yj)

其中I(Mi(Xj)≠Yj)为指示函数,当分类不正确时等于1,否则为0。同时计算当前分类器的权重αi:

αi=12log1?errierri

然后对每个样本,更新权重为wi+1:

w(j)i+1=???w(j)iexp(?αi)Zi,w(j)iexp(αi)Zi,if Yj=Mi(Xj) if Yj≠Mi(Xj)

由于Yj和Mi(Xj)均为分类类别+1,?1,因此上述可以合并为如下公式:

w(j)i+1=w(j)iexp(?αiYjMi(Xj))Zi

其中Zi为当前轮规范化因子,保证权重是一个概率分布:

Zi=∑j=1Nexp(?αiYjMi(Xj))

2. 如何将弱分类器组合成强分类器

根据上述计算,得到了第i轮训练时的分类器权重αi,因此最终构建分类器的加权和:

f(x)=sign(∑i=1kαiMi(x))

这就将k个弱分类器组合得到了最终的强分类器,而且权重αi是与对应的分类器错误率相关的,如果错误率erri越小,则αi=12log1?errierri越大,从而在最终的强分类器中的权重越大。这就正好对应了,错误率小的分类器对最终分类结果的决定性作用更大。

AdaBoost模型解释

AdaBoost是模型为加法模型,学习策略为指数损失函数的经验风险最小化,学习算法为前向分步算法的二分类方法。

加法模型是从前往后,每一轮仅学习一个模型及其系4数,这样逐步逼近最终目标。也就是对应AdaBoost中,每一轮学习一个弱分类器,通过错误率再计算权重αi。记第i?1轮学习到的模型组合为fi?1:

fi?1=α1M1+α2M2+...αi?1Mi?1

那么,在第i轮训练中,得到了分类器Mi和权重αi,这里的目标是为了fi=fi?1+αiMi在训练数据集上的指数损失最小化,指数损失为:

L(y,f(x))=exp(?yf(x))

那么得到:

(αi,Mi)=argminα,M∑j=1Nexp(?Yj(fi?1(Xj)+αM(Xj)))=argminα,M∑j=1Nw^(j)iexp(?YjαM(Xj))

其中,w^(j)i=exp(?Yjfi?1(Xj)),这一项与α,M均无关,最小化时不需要考虑。

对于上述目标函数,最优的分类器由如下确定:

M?i=argminM∑j=1Nw^(j)iI(Yj≠M(Xj))

也就是寻找权重错误率最小的分类器。这个分类器就是AdaBoost算法的基本分类器,第i的加权训练数据分类误差最小的分类器。

对于权重αi有

argminαJ(α)=∑j=1Nw^(j)iexp(?YjαM?i(Xj))=∑Yi=M?i(Xj)w^(j)iexp(?α)+∑Yi≠M?i(Xj)w^(j)iexp(α)=(exp(α)?exp(?α))∑j=1Nw^(j)iI(Yj≠M?i(Xj))+∑j=1Nw^(j)iexp(?α)

上述目标对α求导并使导数为0即可得到最优的α?i:

dJdα=(exp(α)+exp(?α))∑j=1Nw^(j)iI(Yj≠M?i(Xj))?exp(?alpha)∑j=1Nw^(j)i=exp(?α)[(exp(2α)+1)∑j=1Nw^(j)iI(Yj≠M?i(Xj))?∑j=1Nw^(j)i]=0

得到α?i为

α?i=12log(∑Nj=1w^(j)i∑Nj=1w^(j)iI(Yj≠M?i(Xj))?1)=12log(1erri?1)=12log1?errierri

这样就得到,AdaBoost算法中的分类器权重计算公式就是经验风险最小化求导得到的最小值。其中

erri=∑Nj=1w^(j)i∑Nj=1w^(j)iI(Yj≠M?i(Xj))=∑j=1Nw(j)iI(Yj≠M?i(Xj))

也是AdaBoost算法中计算的加权分类误差。

AdaBoost算法实践

根据上述算法,使用之前的垃圾邮件分类数据进行分类,每个分类器构建的都是一个单节点的决策树,也就是一个树桩,在训练数据集中找出加权错误率最小的一个分割点,然后按照上述方法进行分类器权重计算和每个样本的权值更新。

分割点的查找

对数据的每个维度,都要进行查找,在给定维度下,找到最大和最小的数据,每次以给定步骤进行查找,计算错误率,最终找到最佳分割点。具体实现如下:

def findSpliter(ds, labels, weight):
    ‘‘‘find the best spliter for min error rate‘‘‘
    spliter  = {‘featIndex‘: 0, ‘thresh‘: 0, ‘cmp‘: ‘le‘, ‘minErr‘: inf}
    cls      = None
    m,n = ds.shape
    steps = 20.0
    index = range(n); #random.shuffle(index)
    for i in index:
        rangeMin = ds[:, i].min(); rangeMax = ds[:, i].max()
        step = (rangeMax - rangeMin) / steps
        for j in range(-1, int(steps) + 1):
            for comp in [‘le‘, ‘gt‘]:
                thresh   = rangeMin + float(j) * step
                splitCls = spliterClassify(ds, i, thresh, comp)
                err_i    = mat(ones((m, 1)))
                err_i[labels == splitCls] = 0
                err_rate = sum(err_i.transpose() * weight)
                if err_rate < spliter[‘minErr‘]:
                    spliter[‘minErr‘] = err_rate
                    spliter[‘featIndex‘] = i
                    spliter[‘thresh‘] = thresh
                    spliter[‘cmp‘] = comp
                    cls = splitCls.copy()
    return spliter, cls

训练

模型的训练过程就是在给定分类器个数的条件下,每轮寻找最佳分割点构建单节点决策树,同时计算权重 alphai和样本分布w,并进行更新,最后计算出所有基本分类器和权重。

def AdaBoostTrain(ds, labels, maxSteps=200):
    weakClassfier = []
    alpha         = []
    savedWeight   = []
    m,n           = ds.shape
    weight        = mat(zeros((m, 1)))
    weight[:,:]   = 1.0 / m #initial weight

    for i in range(maxSteps):
        savedWeight.append(weight)
        spliter, cls = findSpliter(ds, labels, weight)
        err = spliter[‘minErr‘]
        alpha_i = 0.5 * log((1 - err) / err)
        alpha.append(alpha_i)
        weakClassfier.append(spliter)

        #update weight
        aiYiMi = multiply(-1.0 * alpha_i * labels, cls)
        Z = multiply(exp(aiYiMi), weight)
        weight = Z / Z.sum()

    return weakClassfier, alpha, savedWeight

分类

分类过程就是将训练好的模型对待分类数据进行分类,然后使用训练得到的权重进行加权组合分类结果,最终得到的分类结果由加权组合结果取符号函数得到。实现如下:

def AdaBoostClassify(weak, alpha, ds):
    classes = []
    for i in range(len(alpha)):
        splitCls = spliterClassify(ds, weak[i][‘featIndex‘], weak[i][‘thresh‘], weak[i][‘cmp‘])
        cls = splitCls * alpha[i]
        classes.append(cls)
    predicted = reduce(lambda x,y: x+y, classes)
    predicted[predicted >= 0] = 1
    predicted[predicted < 0] = -1
    return predicted

分类结果

对垃圾邮件数据进行实际训练和分类,最终得到了训练集和测试集的错误率,并绘制了结果图如下所示:

从图中可以看出,随着基本分类器个数的增加,测试集错误率先减小,得到最小错误率后逐步增大,这正是欠拟合和过拟合的表现,最终需要选择分类器个数为30时的泛化误差最小。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-04 11:25:12

机器学习实战——组合方法与AdaBoost的相关文章

机器学习实战笔记7(Adaboost)

1:简单概念描述 Adaboost是一种弱学习算法到强学习算法,这里的弱和强学习算法,指的当然都是分类器,首先我们需要简单介绍几个概念. 1:弱学习器:在二分情况下弱分类器的错误率会高于50%.其实任意的分类器都可以做为弱分类器,比如之前介绍的KNN.决策树.Na?ve Bayes.logiostic回归和SVM都可以.这里我们采用的弱分类器是单层决策树,它是一个单节点的决策树.它是adaboost中最流行的弱分类器,当然并非唯一可用的弱分类器.即从特征中选择一个特征来进行分类,该特征能是错误率

机器学习实战笔记-利用AdaBoost元算法提高分类性能

做重要决定时,大家可能都会考虑吸取多个专家而不只是一个人的意见.机器学习处理问题时又何尝不是如此?这就是元算法(meta-algorithm ) 背后的思路.元算法是对其他算法进行组合的一种方式 7.1 基于数据集多重抽样的分类器 ??我们自然可以将不同的分类器组合起来,而这种组合结果则被称为集成方法(ensemblemethod)或者元算法(meta-algorithm).使用集成方法时会有多种形式:可以是不同算法的集成,也可以是同一算法在不同设置下的集成,还可以是数据集不同部分分配给不同分类

机器学习day12 机器学习实战adaboost集成方法与重新进行疝马病的预测

今天终于完成了分类器的学习,SVM基本不怎么会,很是头疼,先放一下吧,有机会问问大神讲解一下.接下来的几天进行监督学习回归部分的学习,先看看adaboost的理解. 我们再决定一个重要的事情时,往往不是听取一个人的意见,听取大家的意见,然后投票表决最终结果.这一个特点也可以应用于机器学习的算法中来,每一个人都是弱的分类器,若是指一个人的力量很小,很多人汇集在一起就构成了强分类器.好比政府的投票系统. 有一个有趣的现象,若每个人都有51%的几率选择正确,则汇集很多人的投票信息之后选择正确的人比选择

《机器学习实战》AdaBoost算法的分析与实现

===================================================================== <机器学习实战>系列博客是博主阅读<机器学习实战>这本书的笔记也包含一些其他python实现的机器学习算法 github 源码同步:https://github.com/Thinkgamer/Machine-Learning-With-Python 算法实现均采用Python              如需转载请注明出处,谢谢 ========

机器学习实战第7章——利用AdaBoost元算法提高分类性能

将不同的分类器组合起来,这种组合结果被称为集成方法或元算法(meta-algorithm). 使用集成方法时会有多种形式:(1)可以是不同算法的集成(2)可以是同一种算法在不同设置下的集成(3)数据集不同部分分配给不同分类器之后的集成,等等 接下来介绍基于同一种分类器多个不同实例的两种不同计算方法bagging和boosting 1. bagging 原理:从原始数据集选择S次后得到S个新数据集的一种技术.新数据集和原数据集的大小相等.每个数据集都是通过在原始数据集中随机选择一个样本来进行替换而

【机器学习实战】Machine Learning in Action 代码 视频 项目案例

MachineLearning 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远 Machine Learning in Action (机器学习实战) | ApacheCN(apache中文网) 视频每周更新:如果你觉得有价值,请帮忙点 Star[后续组织学习活动:sklearn + tensorflow] ApacheCN - 学习机器学习群[629470233] 第一部分 分类 1.) 机器学习基础 2.) k-近邻算法 3.) 决策树 4.) 基于概率论的分类方法:朴素

机器学习实战笔记之非均衡分类问题

通常情况下,我们直接使用分类结果的错误率就可以做为该分类器的评判标准了,但是当在分类器训练时正例数目和反例数目不相等时,这种评价标准就会出现问题.这种现象也称为非均衡分类问题.此时有以下几个衡量标准. (1)   正确率<precise>和召回率<Recall> 如下图所示:其中准确率指预测的真实正例占所有真实正例的比例,等于TP/(TP+FP),而召回率指预测的真实正例占所有真实正例的比例,等于TP/(TP+FN).通常我们可以很容易的构照一个高正确率或高召回率的分类器,但是很难

机器学习实战笔记(Python实现)-06-AdaBoost

--------------------------------------------------------------------------------------- 本系列文章为<机器学习实战>学习笔记,内容整理自书本,网络以及自己的理解,如有错误欢迎指正. 源码在Python3.5上测试均通过,代码及数据 --> https://github.com/Wellat/MLaction -----------------------------------------------

电子书 机器学习实战.pdf

机器学习是人工智能研究领域中一个极其重要的研究方向,在现今的大数据时代背景下,捕获数据并从中萃取有价值的信息或模式,成为各行业求生存.谋发展的决定性手段,这使得这一过去为分析师和数学家所专属的研究领域越来越为人们所瞩目. <机器学习实战>主要介绍机器学习基础,以及如何利用算法进行分类,并逐步介绍了多种经典的监督学习算法,如k近邻算法.朴素贝叶斯算法.Logistic回归算法.支持向量机.AdaBoost集成方法.基于树的回归算法和分类回归树(CART)算法等.第三部分则重点介绍无监督学习及其一