AdaBoost分类器
本博客是基于《机器学习实战》中第七章的基础上加上个人理解所做的笔记,其中python程序的注释也是个人的理解,可能有不正确的地方,仅供参考。
环境:win7 64位 python3.5
0、概述
当做重要决定时,大家可能都会考虑吸取多个专家而不只是一个人的意见。机器学习处理问题时又何尝不是如此?这就是元算法(meta-algorithm ) 背后的思路。元算法是对其他算法进行组合的一种方式,即可以将不同的分类器组合起来,这种组合的结果也叫集成方法。其中AdaBoost被称为最流行的元算法。由于某些人认为AdaBoost是最好的监督学习的方法,所以该方法是机器学习工具箱中最强有力的工具之一。
1、bagging与boosting
bagging:自举汇聚(boostrap aggregating),也称为bagging方法,是在从原始数据集选择S次后得到S个新数据集的一种技术。新数据集和原数据集的大小相等。每一个数据集都是由有放回抽样取得的数据集。这样在S个数据集建好之后,将某个学习算法分别作用于每个数据集就得到了S个分类器。每一个分类器都有一个分类的结果,所以在S个分类器的结果中采取投票机制,即多数原则,来确定此次的分类结果。随机森林就是其中之一。
boosting: boosting是一种与bagging很类似的技术。不论是在boosting还是bagging当中,所使用的多个分类器的类型都是一致的。但是在boosting当中,不同的分类器是通过串行训练而获得的,每个新分类器都根据已训练出的分类器的性能来进行训练。boosting是通过集中关注被已有分类器错分的那些数据来获得新的分类器。
由于boosting分类的结果是基于所有分类器的加权求和结果的,因此boosting与bagging不太一样 。bagging中的分类器权重是相等的,而boosting中的分类器权重并不相等,每个权重代表的是其对应分类器在上一轮迭代中的成功度。
boosting方法拥有多个版本,AdaBoost是其最流行版本之一。
2、AdaBoost原理简述
弱分类器:比随机猜测要稍微好,但不会好太多。在二分类情况下,弱分类器的错误率高于50%。
AdaBoost是adaptive boosting(自适应boosting)的缩写,其运行过程如下:训练数据中的每个样本,并赋予其一个权重,这些权重构成了向量D。一开始,这些权重都初始化成相等值。首先在训练数据上训练出一个弱分类器并计算该分类器的错误率,然后在同一数据集上再次训练弱分类器。在分类器的第二次训练当中,将会重新调整每个样本的权重,其中第一次分对的样本的权重将会降低,而第一次分错的样本的权重将会提高。为了从所有弱分类器中得到最终的分类结果 ,AdaBoost为每个分类器都分配了一个权重值alpha,这些alpha值是基于每个弱分类器的错误率进行计算的。其中,错误率的定义为:
而alpha的计算公式如下:
现在分析alpha的公式,由于误差率delta是大于0.5小于1的数值,所以当delta增大时,alpha也是增大的,也就是说一个弱分类器的错误率越大,其获得的权重也是越大的,这就意味着在训练的时候,分类器会更加注重这些错误率比较大的弱分类器。
AdaBoost^% 的流程如图所示。
从图中可以看出,n个加了权重的弱分类器累加,便得到一个强分类器。
计算出alpha值之后,可以对权重向量D进行更新,以使得那些正确分类的样本的权重降低而错分样本的权重升高。D的计算方法如下。
如果某个样本被正确分类,那么该样本的权重更改为:
而如果某个样本被错分,那么该样本的权重更改为:
在计算出D之后,Adaboost对又开始进入下一轮迭代。AdaBoost算法会不断地重复训练和调整权重的过程,直到训练错误率为0或者弱分类器的数目达到用户的指定值为止。
说明:《机器学习实战》在这里对样本权重D的解释与其他的书籍的解释不太一样,其他的解释可以参考博客:http://blog.csdn.net/guyuealian/article/details/70995333
这篇博客写的通俗易懂,非常好。
3、python实现
import numpy as np
import mathdef loadsimpData():dataMat = np.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 dataMat,classLabelsdef loadDataSet(fileName): #general function to parse tab -delimited floatsnumFeat = len(open(fileName).readline().split('\t')) #get number of fields dataMat = []; labelMat = []fr = open(fileName)for line in fr.readlines():lineArr =[]curLine = line.strip().split('\t')for i in range(numFeat-1):lineArr.append(float(curLine[i]))dataMat.append(lineArr)labelMat.append(float(curLine[-1]))return dataMat,labelMat
# 将数据分类
"""
根据某个值是否大于或小于某个阈值进行判断
参数:dataMatrix : 数据集矩阵dimen : 要判断的特征值即为列threshVal : 阈值threshIneq : 大于或小于 ['lt', 'gt']
"""
def stumpClassify(dataMatrix,dimen,threshVal,threshIneq):retArray = np.ones((np.shape(dataMatrix)[0],1)) # 初始化为 m行1列的值为1 的矩阵if threshIneq == 'lt': # less thanretArray[dataMatrix[:,dimen] <= threshVal] = -1.0else:retArray[dataMatrix[:,dimen] > threshVal] = -1.0return retArray"""
在一个加权数据集中循环,并找到具有最低错误率的单层决策树。
伪代码如下:
将最小错误率minError设为+00
对数据集中的每一个特征(第一层循环):对每个步长(第二层循环):对每个不等号(第三层循环):建立一棵单层决策树并利用加权数据集对它进行测试如果错误率低于minError,则将当前单层决策树设为最佳单层决策树
返回最佳单雇决策树该函数的功能就是找出错误率最小的决策树,并记录跟决策有关的信息,并没有对权重向量进行改变,所有一开始要假设所有的数据样本的权重一样
参数:dataArr : 数据集classLabels : 分类标签值D : 权重向量
"""
def buildStump(dataArr,classLabels,D):dataMatrix = np.mat(dataArr)labelMat = np.mat(classLabels).Tm,n = np.shape(dataMatrix) # 返回数据集行、列numSteps = 10.0bestStump = {} # 一个空的字典bestClassEst = np.mat(np.zeros((m,1))) # m行1列的零矩阵minError = np.inffor i in range(n): #遍历列(特征值)为的是找出单层决策树rangeMin = dataMatrix[:,i].min() # 找出第i列的最小值rangeMax = dataMatrix[:,i].max() # 找出第i列的最大值stepSize = (rangeMax - rangeMin)/numSteps # 计算出极差,并以10为间隔分段for j in range(-1,int(numSteps)+1): # 遍历每一个分段for inequal in ['lt','gt']:threshVal = (rangeMin + float(j)*stepSize) # 阈值predictdVals = stumpClassify(dataMatrix,i,threshVal,inequal)errArr = np.mat(np.ones((m,1))) # m行1列 用来保存预测的结果errArr[predictdVals == labelMat] = 0 # 如果与标签值一样,为正确,标0weightedError = D.T*errArr # 得到新的权重向量if weightedError < minError: # 说明这次的错误比上一次低minError = weightedErrorbestClassEst = predictdVals.copy() # 记录下这一次的预测值bestStump['dim'] = i # 记录这次的列 即特征值bestStump['thresh'] = threshVal # 记录阈值bestStump['ineq'] = inequalreturn bestStump,minError,bestClassEst"""
参数:dataArr : 数据集classLabels : 标签值numIt : 迭代次数
如果设置迭代的次数为9,但实际上迭代了3次的错误率就为0了,那就退出迭代
"""
def adaBoostTrainDS(dataArr,classLabels,numIt=40):weakClassArr = []m = np.shape(dataArr)[0]# D 是一个概率分布向量,除以m是为了保障,每一个分量都相等且和为1D = np.mat(np.ones((m,1))/m) # 初始化权重向量aggClassEst = np.mat(np.zeros((m,1))) # 记录每个数据点的类别估计累计值for i in range(numIt): # 遍历迭代# 建立单层决策树,返回最小错误率以及估计的类别向量bestStump,error,classEst = buildStump(dataArr,classLabels,D)alpha = float(0.5*np.log((1.0-error)/max(error,1e-16)))# 本次单层决策树输出结果的权重bestStump['alpha'] = alpha# 存储每一层最佳决策树的决策信息weakClassArr.append(bestStump)"""由于样本被正确分类权重D乘以一个以e为底的负系数,错误分类样本乘以正系数。且预测值与标签值都是用-1,和1表示,如果正确双方成绩同号,错误双方成绩为负所以考虑将两个分类的问题的两个公式使用一个公式来表示,那么两个的成绩是最好的了。""" expon = np.multiply(-1*alpha*np.mat(classLabels).T,classEst)D = np.multiply(D,np.exp(expon)) D = D/D.sum() # 不同书籍上的表达不一样。"""通过aggClasSESt 变量保持一个运行时的类别估计值来实现的.该值只是一个浮点数,为了得到二值分类结果还需要调用sign()函数。如果总错误率为0 ,则由break中止sign(n)取数字n的符号,大于0返回1,小于0返回-1,等于0返回0"""# 强分类器等于每一次弱分类器乘以权重之和aggClassEst += alpha*classEstaggErrors = np.multiply(np.sign(aggClassEst) != np.mat(classLabels).T,np.ones((m,1)))errorRate = aggErrors.sum()/mprint("total error: ",errorRate)if errorRate == 0.0: breakreturn weakClassArr,aggClassEst"""
需要做的就只是将弱分类器的训练过程从程序中抽出来,然后应用到某个具体的实例上去。
每个弱分类器的结果以其对应的alpha值作为权重。
所有这些弱分类器的结果加权求和就得到了最后的结果。参数:datToClass : 一个或者多个待分类样例classifierArr : 个弱分类器组成的数组
"""
def adaClassify(datToClass,classifierArr):dataMatrix = np.mat(datToClass) # 转换成numpy矩阵m = np.shape(dataMatrix)[0] # 取出带分类的样例数aggClassEst = np.mat(np.zeros((m,1))) # 初始化用于存放alpha的矩阵for i in range(len(classifierArr)): # 遍历classifierArr中的所有弱分类器# 根据阈值分类,单层决策树classEst = stumpClassify(dataMatrix,classifierArr[i]['dim'],classifierArr[i]['thresh'],classifierArr[i]['ineq'])# alpha加权每一次单层分类器并累加aggClassEst += classifierArr[i]['alpha']*classEstprint(aggClassEst)return sign(aggClassEst) # 返回强分类器
AdaBoost分类器相关推荐
- OpenCV学习记录(二):自己训练haar特征的adaboost分类器进行人脸识别
上一篇文章中介绍了如何使用OpenCV自带的haar分类器进行人脸识别(点我打开). 这次我试着自己去训练一个haar分类器,前后花了两天,最后总算是训练完了.不过效果并不是特别理想,由于我是在自己的 ...
- 使用opencv_traincascade训练Haar、HOG、LBP Adaboost分类器
opencv_traincascade.exe默认表格 训练正样本2400,负样本3300 1.opencv_traincascade.exe -data traincascade -vec pos ...
- 使用 AdaBoost 元算法提高分类器性能
转自穆晨 阅读目录 前言 一种原始的元算法 - bagging (自举汇聚法) boost (提高任意给定学习算法精确度算法) vs bagging (自举汇聚法) AdaBoost 元算法的基本原理 ...
- 人脸检测:经典的VJ人脸检测器(类Harr特征,积分图加速法,级联的Adaboost强分类器)
著名的VJ人脸检测算法就是一种基于Adaboost分类器的方法.该检测器由Paul Viola和Michael Jones在2001年的 Robust Real-Time Face Detection ...
- haar分类器详解(Haar特征,积分图,adaboost算法,筛选式级联分类器),DCG介绍 --文献阅读报告《基于素描对视频的人脸识别研究》
基于素描对视频的人脸识别--haar分类器详解,haar特征,adaboost,级联强分类器,积分图,DCG 背景 算法总体流程 1.预处理--识别出人脸并将人脸图像标准化 haar特征 积分图--加 ...
- 机器学习算法——利用AdaBoost元算法提高分类性能(基于单层决策树构建的弱分类器)
当做出重要决定时,我们往往会听取多个专家而不只是一个人的意见.元算法正是采用这种思路,元算法是对其他算法进行组合的一种方式,本篇博文主要介绍AdaBoost元算法,该算法是机器学习工具箱中最强有力的工 ...
- 机器学习经典算法详解及Python实现--元算法、AdaBoost
http://blog.csdn.net/suipingsp/article/details/41822313 第一节,元算法略述 遇到罕见病例时,医院会组织专家团进行临床会诊共同分析病例以判定结果. ...
- EL之AdaBoost:集成学习之AdaBoost算法的简介、应用、经典案例之详细攻略
EL之AdaBoost:集成学习之AdaBoost算法的简介.应用.经典案例之详细攻略 目录 AdaBoost算法的简介 1.理解AdaBoost算法 1.1.从前向逐步递增角度来看理解AdaBoos ...
- 集成学习-Boosting集成学习算法AdaBoost
Boosting是一族将弱学习器提升为强学习器的算法,适用于个体学习器间存在强依赖关系.必须串行生成序列化方法.最著名的代表是AdaBoost. Boosting的工作机制:从初始的训练集中训练出一个 ...
最新文章
- Django:永别了pycrypto库~
- 江阴市职称计算机考试,要评职称的人请注意!!江阴这些新变化了解一下
- 【ZooKeeper Notes 28】ZooKeeper典型应用场景一览
- 通过蜜罐技术获取攻击者手机号、微信号【网络安全】
- 建立openstack quantum开发环境 .
- 集成 Tomcat、 Servlet 的生命周期
- java的addattribute_Java AttributeSet.addAttributeListener方法代码示例
- Ubuntu打印到pdf文件
- 官方正式(简/繁/英/日/韩文) Windows XP sp3 下载
- Win10截屏快捷键
- 电路图:MC34063 2.2V-6V升压到7V电路
- 计算机无法连接网络显示错误651,电脑连接路由器提示错误651解决办法
- BZOJ 4327 【JSOI 2012】 玄武密码 AC自动机+dfs
- 海外游戏代投需要注意的
- php注册验证用户名已存在,php ajax注册验证用户名是否存在代码_PHP教程
- 如何解决海康大华摄像头接入国标GB28181协议视频平台EasyGBS播放视频流,出现多个播放器的问题?
- Java 条件语句 - if...else
- 三种方法:写一个函数,每调用一次函数,就会将num的值增加1,&&可能遇到的问题
- #今日论文推荐# 多边形战士模型,微软提出19亿参数的超大通用模型BEIT-3,刷榜多个CV和多模态任务
- nginx隐藏版本号和标识