news 2026/10/23 3:34:49

【python】python机器学习实战6:利用adaBoost元算法提高分类性能

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【python】python机器学习实战6:利用adaBoost元算法提高分类性能

1.adaBoost元算法简介

在之前我们LZ介绍了不同的分类器,如果我们根据实际的要求对这些分类器进行组合,这种组合的结果则被称为集成算法(ensemble method)或者元算法(meta-method)。

我们这次使用的算法就是adaBoost,先给小伙伴一个直观的印象,该算法的优点是:泛化错误率低,易编码,可以应用在大部分分类器上,无参数调整。缺点是对离群点敏感,适用的数据类型:数值型和标称型数据。

自举汇聚法(bootstrap aggregating),也称为bagging方法,是在从原始数据集选择S次后得到S个新数据集的一种技术。bagging中的数据集相当于是有放回取样,比如要得到一个大小为n的新数据集,该数据集中的每个样本都是在原始数据集中随机抽样(有放回),也就是说原始数据集中的样本有部分可能就不会出现在新的数据集中,而有些样本可能会出现不止一次。

在S个数据集建立好之后,就会应用某种算法产生S个分类器,然后对每个分类器附上对应权重,加权求和后获得最后的结果。

bagging算法有很多种:例如随机森林等就自行研究

boosting是一种与bagging很类似的技术,这两种技术使用的分类器的类型都是一致的,前者是通过不同的分类器串行训练得到的,每个分类器都根据已训练出的分类器的性能来进行训练。boosting是通过集中关注被已有分类器错分的哪些数据来获得新的分类器。由于boosting分类结果是基于所有分类器的加权求和结果的,因此和bagging不太一样,bagging中的分类器的权重是相等的。boosting中的分类器权重并不相等,每个权重代表的是其对应分类器在上一轮迭代中的成功度。

adaBoost是adaptive boosting(自适应boosting)的缩写,而其想法就是如果我们能够建立一些弱分类器,这些分类器的性能比随机猜测要略好,但也不会好很多,那么如果我们把多个弱分类器构建成一个强分类器,那么结果会怎么样呢?

AdaBoost的运行过程如下:训练数据中的每个样本,并赋予其一个权重,这些权重构成了向量D。一开始这些权重都初始化相等值。首先在训练数据上训练出一个弱分类器并计算该分类器的错误率,然后在统一数据上再次训练弱分类器。在分类器的第二次训练当中,将会重新调整每个样本的权重,其中每一次分对的样本的权重将会降低,而第一次分错的样本的权重就会提高。为了从所有弱分类器中得到最终的分类结果,Adaboost为每个分类器都分配了一个权重值alpha,这些alpha值是基于每个弱分类器的错误率进行计算的。其中,错误率ϵ\epsilonϵ的定义为:

ϵ=未正确分类的样本数目所有样本数目\epsilon=\frac{未正确分类的样本数目}{所有样本数目}ϵ=所有样本数目未正确分类的样本数目​

而α\alphaα的计算公式如下:

α=12In(1−ϵϵ)\alpha = \frac{1}{2}In(\frac{1-\epsilon}{\epsilon})α=21​In(ϵ1−ϵ​)

计算出α\alphaα值后,可以对权重向量D进行更新,以使得那些正确的分类的样本的权重降低而错分样本的权重升高。D的计算方法如下.

如果某个样本被正确分类,那么样本的权重更新为:

Dit+1=Dite−αSum(D)D^{t+1}_i = \frac{D^{t}_{i}e^{-\alpha}}{Sum(D)}Dit+1​=Sum(D)Dit​e−α​

如果某个样本被错分,那么样本的权重更新为:
Dit+1=DiteαSum(D)D^{t+1}_i = \frac{D^{t}_{i}e^{\alpha}}{Sum(D)}Dit+1​=Sum(D)Dit​eα​

在计算出D之后,AdaBoost又开始进入下一轮迭代。AdaBoost算法会不断地重复训练和调整权重的过程,直到训练错误率为0或者弱分类器的数目达到用户的指定值为止。

2.adaBoost的代码实现

#coding:utf-8#导入numpy依赖库fromnumpyimport*#创建简单数据集,后面会用到比较复杂的数据集defloadSimpData():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]returndatMat,classLabels#读取数据集的函数defloadDataSet(fileName):#general function to parse tab -delimited floatsnumFeat=len(open(fileName).readline().split('\t'))#get number of fieldsdataMat=[];labelMat=[]fr=open(fileName)forlineinfr.readlines():lineArr=[]curLine=line.strip().split('\t')foriinrange(numFeat-1):lineArr.append(float(curLine[i]))dataMat.append(lineArr)labelMat.append(float(curLine[-1]))returndataMat,labelMat#单层决策树生成函数#单层决策树仅基于单个特征来做决策defstumpClassify(dataMatrix,dimen,threshVal,threshIneq):#just classify the dataretArray=ones((shape(dataMatrix)[0],1))ifthreshIneq=='lt':retArray[dataMatrix[:,dimen]<=threshVal]=-1.0else:retArray[dataMatrix[:,dimen]>threshVal]=-1.0returnretArray#遍历stumpClassify()函数所有的可能输入值,并找到数据集上最佳的单层决策树defbuildStump(dataArr,classLabels,D):dataMatrix=mat(dataArr);labelMat=mat(classLabels).T m,n=shape(dataMatrix)numSteps=10.0;bestStump={};bestClasEst=mat(zeros((m,1)))minError=inf#init error sum, to +infinityforiinrange(n):#loop over all dimensionsrangeMin=dataMatrix[:,i].min();rangeMax=dataMatrix[:,i].max();stepSize=(rangeMax-rangeMin)/numStepsforjinrange(-1,int(numSteps)+1):#loop over all range in current dimensionforinequalin['lt','gt']:#go over less than and greater thanthreshVal=(rangeMin+float(j)*stepSize)predictedVals=stumpClassify(dataMatrix,i,threshVal,inequal)#call stump classify with i, j, lessThanerrArr=mat(ones((m,1)))errArr[predictedVals==labelMat]=0weightedError=D.T*errArr#calc total error multiplied by D#print "split: dim %d, thresh %.2f, thresh ineqal: %s, the weighted error is %.3f" % (i, threshVal, inequal, weightedError)ifweightedError<minError:minError=weightedError bestClasEst=predictedVals.copy()bestStump['dim']=i bestStump['thresh']=threshVal bestStump['ineq']=inequalreturnbestStump,minError,bestClasEst#基于单层决策树的AdaBoost训练过程,指定迭代次数numIt,DS代表的就是单层决策树defadaBoostTrainDS(dataArr,classLabels,numIt=40):weakClassArr=[]m=shape(dataArr)[0]D=mat(ones((m,1))/m)#init D to all equalaggClassEst=mat(zeros((m,1)))foriinrange(numIt):bestStump,error,classEst=buildStump(dataArr,classLabels,D)#build Stump#print "D:",D.Talpha=float(0.5*log((1.0-error)/max(error,1e-16)))#calc alpha, throw in max(error,eps) to account for error=0bestStump['alpha']=alpha weakClassArr.append(bestStump)#store Stump Params in Array#print "classEst: ",classEst.Texpon=multiply(-1*alpha*mat(classLabels).T,classEst)#exponent for D calc, getting messyD=multiply(D,exp(expon))#Calc New D for next iterationD=D/D.sum()#calc training error of all classifiers, if this is 0 quit for loop early (use break)aggClassEst+=alpha*classEst#print "aggClassEst: ",aggClassEst.TaggErrors=multiply(sign(aggClassEst)!=mat(classLabels).T,ones((m,1)))errorRate=aggErrors.sum()/mprint"total error: ",errorRateiferrorRate==0.0:breakreturnweakClassArr,aggClassEst#AdaBoost分类函数defadaClassify(datToClass,classifierArr):dataMatrix=mat(datToClass)#do stuff similar to last aggClassEst in adaBoostTrainDSm=shape(dataMatrix)[0]aggClassEst=mat(zeros((m,1)))foriinrange(len(classifierArr)):classEst=stumpClassify(dataMatrix,classifierArr[i]['dim'],\ classifierArr[i]['thresh'],\ classifierArr[i]['ineq'])#call stump classifyaggClassEst+=classifierArr[i]['alpha']*classEstprintaggClassEstreturnsign(aggClassEst)#画出ROC函数defplotROC(predStrengths,classLabels):importmatplotlib.pyplotasplt cur=(1.0,1.0)#cursorySum=0.0#variable to calculate AUCnumPosClas=sum(array(classLabels)==1.0)yStep=1/float(numPosClas);xStep=1/float(len(classLabels)-numPosClas)sortedIndicies=predStrengths.argsort()#get sorted index, it's reversefig=plt.figure()fig.clf()ax=plt.subplot(111)#loop through all the values, drawing a line segment at each pointforindexinsortedIndicies.tolist()[0]:ifclassLabels[index]==1.0:delX=0;delY=yStep;else:delX=xStep;delY=0;ySum+=cur[1]#draw line from cur to (cur[0]-delX,cur[1]-delY)ax.plot([cur[0],cur[0]-delX],[cur[1],cur[1]-delY],c='b')cur=(cur[0]-delX,cur[1]-delY)ax.plot([0,1],[0,1],'b--')plt.xlabel('False positive rate');plt.ylabel('True positive rate')plt.title('ROC curve for AdaBoost horse colic detection system')ax.axis([0,1,0,1])plt.show()print"the Area Under the Curve is: ",ySum*xStep

好久没更新这个系列了,前阵子也是各种杂事,现在收心,好好学习啦O(∩_∩)O

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 3:34:48

【cmake】CMake实践二:hello world(v2.0) 第二部分

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/23 3:34:10

Ubuntu 20.04 配置IC617/Spectre18/Calibre19全套EDA工具链要点

简介&#xff1a;在Ubuntu 20.04中部署Cadence IC617(HotFix)、Spectre18、Calibre19与XCELIUMMAIN_18常因依赖库、AVX2指令集和许可证问题受阻&#xff0c;这份安装笔记正是为解决这一难题而整理&#xff0c;适合集成电路设计工程师、研究生、运维人员以及具备一定Linux基础、…

作者头像 李华
网站建设 2026/10/23 3:33:24

Linux下启动Redis的完整实践指南与常见坑位排查

很多后端项目跑起来之后&#xff0c;第一件事不是写代码&#xff0c;而是把基础设施准备好。Redis 就是其中最常用的一环。标题写的是“Linux下启动redis”&#xff0c;看起来很基础&#xff0c;但实际运维过的人都知道&#xff0c;这个“启动”背后藏着不少门道&#xff1a;配…

作者头像 李华
网站建设 2026/10/23 3:32:58

Agent记忆架构实战:情景记忆与语义记忆如何协同构建Memory Stack

做Agent开发也有一段时间了&#xff0c;从最早的“提示词外部工具”的玩法&#xff0c;到后面开始碰记忆模块&#xff0c;中间踩了不少坑。最近在重构一个知识型Agent的底层架构&#xff0c;正好做到Episodic Semantic Memory Stack这一层&#xff0c;很多朋友问我这两类记忆到…

作者头像 李华
网站建设 2026/10/23 3:32:51

ISO 21448-2022 SOTIF 预期功能安全标准解读与工程落地实践

简介&#xff1a;ISO 21448-2022《道路车辆——预期功能的安全性》是国际标准化组织发布的SOTIF领域核心标准&#xff0c;面向汽车制造商、零部件供应商、软件开发商及道路安全监管机构&#xff0c;用于评估和缓解自动驾驶与辅助驾驶系统在正常运行条件下因功能局限、传感器失效…

作者头像 李华
网站建设 2026/10/23 3:32:39

Qlib量化投资实战:港股因子选股与LightGBM模型全流程

简介&#xff1a;这份PDF文档是华泰证券金工研究团队出品的深度研究报告《微软AI量化投资平台Qlib体验》&#xff0c;面向量化投资研究者、金融工程从业者及希望入门AI选股的学生群体。报告系统梳理了Qlib的基础与进阶功能&#xff0c;对比传统量化策略开发流程&#xff0c;提炼…

作者头像 李华