AdaBoost算法通俗讲解
AdaBoost是元算法中最流行的一种,也被认为是最好的监督学习的方法 。
一、元算法
元算法(meta-algorithm),也被称作集成方法(ensemble method),是对其他算法进行组合的一种方式,将不同的分类器组合起来的结果。使用集成方法时有多种形式:可以是不同算法的集成,也可以是同一算法在不同设置下的集成,还可以是数据集不同部分分配给不同分类器之后的集成。
下面介绍基于同一种分类器多个不同实例的两种计算方法bagging和boosting。
bagging(bootstrap aggregating,自举汇聚法),基于数据随机重抽样的分类器构建方法。以抽样之后又放回的方式在原始数据集中选择S个新数据集,新数据集与原始数据集的大小相等,重抽样机制允许每个新数据集中有重复的值或原始数据集中某值不出现。构建好S个数据集后,将某个学习算法分别作用与每个数据集就得到了S个分类器。当对新数据进行分类时,就可以应用这S个分类器进行分类,选择分类器投票结果中最多的类别作为最后的分类结果。
boosting(adaptive boosting,自适应boosting),与bagging类似,所使用的多个分类器的类型都是一致的。不同之处是,bagging的不同分类器是通过串行训练而获得的,每个新分类器都根据已训练出的分类器的性能来进行训练。boosting是通过集中关注被已有分类器错分的那些数据来获得新的分类器,基于所有分类器的加权求和结果的。bagging中的分类器权重是相等的,而boosting中的分类器权重并不相等,每个权重代表的是其对应分类器在上一轮迭代中的成功度。
boosting方法有多个版本,其中AdaBoost是最流程的版本。AdaBoost的大部分时间都用在训练上,分类器将多次在同一数据集上训练弱分类器。
二、AdaBoost算法理论
AdaBoost算法示意图
AdaBoost算法基于错误提升分类器的性能,其运行过程为:
(1)训练数据中的每个样本,并赋予其一个权重(构成向量D)。一开始,这些权重都初始化成相等值。
(2)在训练数据上训练出一个弱分类器,并计算该分类器的错误率,基于错误率计算弱分类器的权重值alpha,为从所有弱分类器中得到最终的分类结果。
错误率ε的定义为:
权重值alpha计算公式为:
(3)在同一数据集上再次训练弱分类器,重新调整每个样本的权重,对权重向量D进行更新,其中正确分类的样本的权重将会降低,而错分样本的权重将会提高。
如果某个样本被正确分类,则该样本权重更改为:
如果某个样本被错误分类,则该样本权重更改为:
(4)计算出D之后,AdaBoost开始进入下一轮迭代,计算alpha值,更新权重向量D,AdaBoost算法将不断重复训练和调整权重的过程,直到训练错误率为0或者弱分类器的数目达到用户指定值为止。
三、AdaBoost算法实践
(1)首先基于单层决策树构建弱分类器
单层决策树就是仅基于单个特征来做决策,只有一次分裂过程,因此实际上就是一个树桩。实际应用中,单层决策树很难只根据一个特征来判断分类结果,但是通过多棵单层决策树就可以构建出一个能够对数据集完全正确分类的分类器。这就是元算法解决的问题,提高分类性能。
单层决策树生成函数:
#(1)测试是否有某个值小于或大于我们正在测试的阈值
def stumpClassify(dataMatrix, dimen, threshVal, threshIneq): #(待分类的数据,数据的某个特征index,设定的阈值,阈值比较)retArray = ones((shape(dataMatrix)[0], 1)) #将所有数据分类设置为1,矩阵为[m, 1]if threshIneq == 'lt': #如果小于阈值,类别为-1,默认的大于阈值的为1retArray[dataMatrix[:, dimen] <= threshVal] = -1.0 #将数据集中特征为dimen的每行数据与threshVal(阈值)比较,小于的就设为-1else: #另一种情况:如果大于阈值,类别为-1,默认的小于阈值的为1retArray[dataMatrix[:, dimen] > threshVal] = -1.0return retArray #返回分类的结果#(2)遍历stumpClassify()函数所有可能输入值,并找到数据集上最佳(错误率最低)的单层决策树
def buildStump(dataArr, classLabels, D): #D是权重dataMatrix = mat(dataArr) #转换为矩阵labelMat = mat(classLabels).T #纵向量m, n = shape(dataMatrix) #m是行,实例数 n是列,特征数numSteps = 10.0 #用于在特征的所有可能值上进行遍历,步数,目的是在步数以内找到最优的决策树bestStump = {} #空字典,用于存储给定权重向量D时所得到的最佳单层决策树的相关信息bestClasEst = mat(zeros((m, 1))) #全0数组,预测分类空矩阵minError = inf #错误率初始化为正无穷大,之后用于寻找可能的最小错误率for i in range(n): #第一层for循环,遍历数据集的所有特征rangeMin = dataMatrix[:, i].min() #所有数据集的第i个特征的最小值rangeMax = dataMatrix[:, i].max() #所有数据集的第i个特征的最大值stepSize = (rangeMax-rangeMin)/numSteps #第i个特征的步长,计算步长,找到最优的决策for j in range(-1, int(numSteps)+1): #第二层for循环,遍历每个特征的取值,在取值范围内,根据步数依次尝试for inequal in ['lt', 'gt']: #第三层for循环,遍历大于或小于两种情况,lt:less than, gt:greater thanthreshVal = (rangeMin + float(j) * stepSize) #通过设置步和步长计算该步的阈值predictedVals = stumpClassify(dataMatrix, i, threshVal, inequal) #调用函数进行预测分类结果,以阈值为分界线分两类errArr = mat(ones((m, 1))) #错误列向量,初始化为1errArr[predictedVals == labelMat] = 0 #预测结果和真正结果相等,则为0,错误的都为1weightedError = D.T * errArr #错误向量与权重向量D相应元素相乘并求和,得到加权错误率(只保留分错的数据,正确的为0)。这就是AdaBoost和分类器交互的地方。if weightedError < minError: #将当前错误率比之前的小,则更新:就在词典bestStump中保存该单层决策树minError = weightedErrorbestClasEst = predictedVals.copy()bestStump['dim'] = ibestStump['thresh'] = threshValbestStump['ineq'] = inequalreturn bestStump, minError, bestClasEst #返回最佳决策树字典、错误率、类别估计值
第一个函数stumpClassify()测试是否有某个值小于/大于我们正在测试的阈值,通过阈值比较对数据进行分类,所有在阈值一边的数据会分到类别-1,而在另一边的数据分到类别+1。正是单层决策树基于一个特征进行分类的实现。可以基于数据集中的任一元素进行比较,同时也可以将不等号在大于、小于之间切换。为了使单层决策树(每一次的弱分类器)的错误率最低,第二个函数buildStump()会遍历所有可能输入值(不同特征比较,不同特征值大小,比较方式,如大于、小于)。
第二个函数buildStump()将遍历stumpClassify()函数所有可能输入值,并找到数据集上最佳的单层决策树。遍历分3层,第一层是遍历所有不同特征,第二层是在这些特征的取值上遍历,第三层是遍历比较方式,在大于和小于之间切换。最佳是指错误率最低的单层决策树,通过遍历所有可能输入,在一个加权数据集中循环,将错误向量errArr和权重向量D的相应元素相乘并求和,计算出数值weightedError,即是单层决策树的错误率,最低错误率对应的决策树即为最佳决策树。最后函数返回最佳决策树字典、错误率、类别估计值。
(2)到此已构建了单层决策树的弱分类器,接下来就要用多个弱分类器来构建AdaBoost代码了。
基于单层决策树的AdaBoost训练过程:
#完整AdaBoost算法的实现,DS代表decision stump单层决策树,是AdaBoost中最流行的弱分类器,当然并非唯一可用的弱分类器
def adaBoostTrainDS(dataArr, classLabels, numIt=30): #(数据集,类别标签,迭代次数(唯一需要用户指定的参数))weakClassArr = [] #函数会输出一个单层决策树的字典,需要建立一个新的python表来对其进行存储m = shape(dataArr)[0] #数据集的数量mD = mat(ones((m, 1))/m) #每个数据的权重向量,概率分布向量,元素之和为1,初始化为平均值1/m。aggClassEst = mat(zeros((m, 1))) #列向量,记录每个数据点的类别估计累计值for i in range(numIt): #for循环运行numIt次或者直到错误率为0bestStump, error, classEst = buildStump(dataArr, classLabels, D) #调用函数,返回利用D得到的具有最小错误率的单层决策树,最小错误率,估计的类别向量alpha = float(0.5*log((1.0-error)/max(error, 1e-16))) #计算本次单层决策树的alpha权重值,max(error, 1e-16)用于确保在错误率为0时不会发生除零溢出,1e-16就是1乘以10的负16次方,非常小bestStump['alpha'] = alpha #将alpha值加入到bestStump字典中,该字典包括了分类所需要的所有信息weakClassArr.append(bestStump) #将字典加入到weakClassArr列表中print("classEst: ", classEst.T) #输入本次循环最佳分类列表 expon = multiply(-1*alpha*mat(classLabels).T, classEst) #相乘,如果分类错了,-1和+1肯定标签不同,相乘为负值,加上前面-1,所以为正值(alpha),如果分类正确,则为负值(-alpha)。D = multiply(D, exp(expon))D = D/D.sum() #更新权值向量D aggClassEst += alpha*classEst #估计类别乘alpha累加print("aggClassEst: ", aggClassEst.T) aggErrors = multiply(sign(aggClassEst) != mat(classLabels).T, ones((m, 1))) #用类别*alpha的累加结果的符号与真实类别比较errorRate = aggErrors.sum()/m #符号不同的为1,代表错误。print("total error: ", errorRate, "\n")if errorRate == 0.0:break #for循环运行numIt次或者直到错误率为0return weakClassArr
函数adaBoostTrainDS中的DS代表单层决策树(decision stump),它是AdaBoost中最流行的弱分类器,当然并非唯一可用的弱分类器。
函数输入为:数据集、类别标签、迭代次数,最后输出为:单层决策树数组。该数组中每个决策树都对应一个alpha权重值,用于最后的数据分类。
函数根据每一轮的样本权重向量D(第一次相等)进行计算,通过buildStump()函数找到D下的最佳单层决策树,并加入数组中。然后计算该最佳单层决策树的alpha值,再计算新的权重向量D(增加错分数据权重,降低正确分类数据权重),更新累计类别估计值(用该值与真实分类对比,计算错误率,为0则终止)。然后根据新的D再次计算迭代。直到当错误率等于0或者达到用户指定的迭代次数为止。
aggClassEst的奇妙之处。这里使用累计类别估计值aggClassEst与真实类别比较而得出总体错误率aggErrors,而不是通过每轮的类别估计值直接与真实类别比较。试验过,前者通过3次迭代就可达到该数据集上的0.0错误率而终止,而后者怎通过n次(用户指定的迭代次数,远大于3)也不会达到0.0的错误率。
(3)一旦拥有了多个弱分类器和其对应的alpha值,就可以进行测试了。将弱分类器的训练从程序中抽出来,应用到具体实例上。
AdaBoost分类函数:
#AdaBoost分类函数
def adaClassify(datToClass, classifierArr): #(一个或多个待分类样例,多个弱分类器组成的数组)dataMatrix = mat(datToClass) #转换成NumPy矩阵m = shape(dataMatrix)[0] #待分类样例个数aggClassEst = mat(zeros((m, 1))) #m行1列的0向量for i in range(len(classifierArr)): classEst = stumpClassify(dataMatrix, classifierArr[i]['dim'], classifierArr[i]['thresh'], classifierArr[i]['ineq']) #基于stumpClassify对每个弱分类器得到一个类别估计值。aggClassEst += classifierArr[i]['alpha']*classEst #类别估计值乘以alpha权重,累加到aggClassEstprint("第", i, "次迭代结果: aggClassEst:", aggClassEst, ", Class:", sign(aggClassEst))return sign(aggClassEst) #返回aggClassEst符号,大于0即为1,小于0即为-1类别。
所有这些弱分类器的结果加权求和就得到了最后的结果。这里也用到了aggClassEst,通过遍历所有弱分类器,得到一个类别估计值,用类别估计值乘上该单层决策树的alpha权重然后累加到aggClassEst上,最后返回aggClassEst的符号,即类别值。
AdaBoost算法通俗讲解相关推荐
- 人工智能算法通俗讲解系列(二):逻辑回归
2019独角兽企业重金招聘Python工程师标准>>> 今天,我们介绍的机器学习算法叫逻辑回归.它英语名称是Logistic Regression,简称LR. 跟之前一样,介绍这个算 ...
- Adaboost算法详细讲解
转自线上数据建模 Adaboost算法详细讲解 Adaboost(Adaptive Boosting): Adaboost是Boosting模型,和bagging模型(随机森林)不同的是:Adaboo ...
- Adaboost算法——详细讲解
最近在做集成学习的时候,对Adaboost非常感兴趣,就自己复现了这个程序. 首先提升方法是基于这样的一个思想:对于一个复杂的任务来说,通将多个专家的判断进行适当的综合所得到的判断,这样得到的结果会比 ...
- 模拟退火算法通俗讲解
目录 1. 模拟退火算法基本概念 2. 模拟退火算法基本流程 3. 遗传模拟退火算法matlab代码 1. 模拟退火算法基本概念 自然凝结的.不受外界干扰而形成的晶体拥有整齐规则的几何外形.那么从液态 ...
- 朴素贝叶斯分类器算法通俗讲解
首先会用到贝叶斯决策理论,说一下.贝叶斯决策理论的核心思想是:选择具有最高概率的决策.例如一个点(x, y),属于类别1的概率是p1(x, y),属于类别2的概率是p2(x, y),用贝叶斯决策理论来 ...
- FP-growth算法通俗讲解
FP-growth算法是一种高效发现频繁集的方法.例如你在搜索引擎中搜索一个词,它会自从补全查询词项,该处用到了FP-growth算法,通过查看互联网上的用词来找出经常在一块出现的词.[FP(Freq ...
- Hadoop平台K-Means聚类算法分布式实现+MapReduce通俗讲解
Hadoop平台K-Means聚类算法分布式实现+MapReduce通俗讲解 在Hadoop分布式环境下实现K-Means聚类算法的伪代码如下: 输入:参数0--存储样本数据的文本文件inpu ...
- Adaboost 算法的公式推导与讲解
目录 前言 一.Adaboost 算法 1.1 Adaboost 步骤 1.2 公式推导与分析 步骤1. 首先,初始化训练数据的权值分布. 步骤2. 开始迭代 步骤3. 组合各个弱分类器,得到最终分类 ...
- AdaBoost算法讲解
原文:AdaBoost算法讲解.举例 一: 算法介绍 Adaboost算法的目标是提高学习算法(比如说LMS算法)的分类准确率.adaboost算法提供的是框架.可以使用各种学习方法构建子分类器. 对 ...
最新文章
- python登录网页版微信发送消息
- ABAP Write 宝典
- 4k视频写入速度要求_为什么视频工作者需要外置硬盘?
- iOS15仿微信详情二维码支持保存本地相册
- [C++] 如此聪明的C++编译器
- python单词去重及排序_Python实现对文件进行单词划分并去重排序操作示例
- js的异常捕获try和catch语句
- 怎么读 Tomcat 源码?
- 达梦数据库DM8企业版--命令行方式的安装、创建数据库和注册服务
- Excel将数据内容导出为数据库DBF文件的操作
- FleaPHP和ThinkPHP(比较)
- 从上海租房之旅得到的感悟
- 嵌入式Linux入门指南(一)——学习路线篇
- 简易秒表Android源代码
- mui短信验证html,mui登录界面(验证)
- 利用WebView加载HTML代码时解决图片正常显示
- 一篇文章带你搞定 banner 修改 SpringBoot 的默认显示模板
- jffs2文件系统制作与移植(二)
- Mybatis为什么查询结果为空时返回值为NULL或空集合?
- 服务器芯片top10,国内云服务器排名top10