adaboost原理和实现
上两篇说了决策树到集成学习的大概,这节我们通过adaboost来具体了解一下集成学习的简单做法。
集成学习有bagging和boosting两种不同的思路,bagging的代表是随机森林,boosting比较基础的adaboost,高级一点有GBDT,在这里我也说下我理解的这两个做法的核心区别:
随机森林的bagging是采用有放回抽样得到n个训练集,每个训练集都会有重复的样本,每个训练集数据都一样,然后对每个训练集生成一个决策树,这样生成的每个决策树都是利用了整个样本集的一部分,也就说每棵决策树只是学习了大部分,然后决策的时候综合每棵决策树的评分,最终得出一个总的评分
boosting的adaboost每次训练的时候用的是同一个数据集,但是前一棵决策树分错的样本在后面的权重会升高,相当于说,后面的决策树利用了前面决策树学习的结果,不断的优化这个结果,也就是说,后面的决策树恰恰擅长的是前面决策树不擅长(分错)的样本,相当于说,boosting的每棵决策树擅长的“领域”不一样,并且在擅长的领域都很厉害
而对比bagging,bagging中的每一棵树都是同样普通的决策树,相当于每棵决策树擅长的“领域”区分不大,也没有很擅长。
下面我们看下adaboost是如何工作的吧,这次我们使用更简单的例子。
这是二维平面的上的两个点,红色是正样本,绿色是负样本,如果使用强分类器,例如深度大于1的决策树,很简单就可以区分开了,或者使用逻辑回归,计算一下,就可以轻松得到一条直线把这两个类别的点区分开了,我们这里主要是先学习adaboost是如何把弱分类器组装成强大的强分类器以及boosting的学习效果
类别和之前不一样,这里的正负样本的类似是1,-1,原因是预测结果的分界线不一样,决策树是没有对类别做任何的操作,adaboost设计到多棵树的权重相加,使用0作为正负样本的分界线会更好
def loadSimpData():
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]
return datMat,classLabels
选择弱分类器:深度为1的决策树无疑是很弱的分类器,深度为1的决策树我们一般称为决策树墩,决策树墩在二维平面上是一条平行坐标轴的直线
对于我们的数据集,决策树墩是没有办法正确划分的,除非能学习出直线之间的组合关系
决策树墩做什么事情:决策树墩做的事情是根据特征的特征值给出判断错误的列表(个数)
def stumpClassify(dataMatrix,dimen,threshVal,threshIneq):#just classify the data
retArray = ones((shape(dataMatrix)[0],1))
if threshIneq == 'lt':
retArray[dataMatrix[:,dimen] <= threshVal] = -1.0
else:
retArray[dataMatrix[:,dimen] > threshVal] = -1.0
return retArray
构建决策树墩:设定步伐,遍历所有的特征和步伐(阀值)和方向(大于阀值还是小于阀值),找到最好的特征以及步伐和方向
得到错误率最小的特征,步伐和方向
def buildStump(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 #初始化为无穷大
for i in range(n):#遍历所有的特征
rangeMin = dataMatrix[:,i].min(); rangeMax = dataMatrix[:,i].max();
stepSize = (rangeMax-rangeMin)/numSteps
for j in range(-1,int(numSteps)+1):#遍历当前特征的所有步伐
for inequal in ['lt', 'gt']: #遍历当前特征当前步伐的所有方向
threshVal = (rangeMin + float(j) * stepSize)
predictedVals = stumpClassify(dataMatrix,i,threshVal,inequal)#用该决策树墩去预测,返回预测的结果
errArr = mat(ones((m,1)))
errArr[predictedVals == labelMat] = 0
weightedError = D.T*errArr #每个样本的权重*每个样本划分对错(对的为零,错的为一,所以这里计算的是错误的权重)
# print "split: dim %d, thresh %.2f, thresh ineqal: %s, the weighted error is %.3f" % (i, threshVal, inequal, weightedError)
if weightedError < minError:
minError = weightedError
bestClasEst = predictedVals.copy()
bestStump['dim'] = i
bestStump['thresh'] = threshVal
bestStump['ineq'] = inequal
return bestStump,minError,bestClasEst
下面是adaboost的核心内容:如何提高划分错的样本的权重
首先用当前划分的错误计算得到一个α值(每个决策树墩的权重),然后对每个样本根据区分对错改变其权重值,最后最改变权重后的样本的权重做归一化
def adaBoostTrainDS(dataArr,classLabels,numIt=40):
weakClassArr = []
m = shape(dataArr)[0]
D = mat(ones((m,1))/m) #一开始所有样本的权重一样
aggClassEst = mat(zeros((m,1)))
for i in range(numIt):
bestStump,error,classEst = buildStump(dataArr,classLabels,D)#构建决策树墩,找到最优的决策树墩
#print "D:",D.T
alpha = float(0.5*log((1.0-error)/max(error,1e-16)))#计算α值
bestStump['alpha'] = alpha
#print "classEst: ",classEst.T
expon = multiply(-1*alpha*mat(classLabels).T,classEst) #计算新的权重
D = multiply(D,exp(expon)) #权重归一化
D = D/D.sum()
#每个样本到当前的评分
aggClassEst += alpha*classEst
#得到分类错误的列表(分对为零,分错为1,计算内积,得到分错的个数)
aggErrors = multiply(sign(aggClassEst) != mat(classLabels).T,ones((m,1)))
errorRate = aggErrors.sum()/m
print "total error: ",errorRate
bestStump['error_rate']=errorRate
weakClassArr.append(bestStump) #记录每一棵最优的决策树墩
if errorRate == 0.0: break
return weakClassArr,aggClassEst
下面我们看每一棵决策树墩的分类的效果吧:样本类别如下:
[1.0, 1.0, -1.0, -1.0, 1.0]
每个样本的权重如下
[ 0.2 0.2 0.2 0.2 0.2]
第一棵决策树,X1小于等于1.3为负样本,这棵树的权重为0.69,错误率0.2(分错了一个),每个样本被预测的结果如下:
[-0.69314718 0.69314718 -0.69314718 -0.69314718 0.69314718]
第一次权重调整:可以发现第一个样本(被分错的)权重升高了
[ 0.5 0.125 0.125 0.125 0.125]
两棵决策树:第二棵决策树X2小于等于1.0为负样本,权重0.97,错误率还是0.2,样本预测总评分如下
[ 0.27980789 1.66610226 -1.66610226 -1.66610226 -0.27980789]
第二次调整权重,可以看到最后一次被分错的权重最高,前一次被分错的稍小,一直被分对的概率最小
[ 0.28571429 0.07142857 0.07142857 0.07142857 0.5 ]
看下三棵决策树墩的效果:X1小于等于0.9的为负样本,权重0.9,错误率0,所有样本评分如下:可以发现虽然每个正样本的评分都大于0,但是有些评分已经高达2.5了,不过我们也发现,最后的评分跟一直分对或者分错没什么关系
[ 1.17568763 2.56198199 -0.77022252 -0.77022252 0.61607184]
在这个简单的数据中,错误率可以降到0,但是不是所有的数据集都可以达到错误率为0的,比如我们前面的100个点的实验
真正的原因在于数据集在特征维度是否是超平面可分的,如果可以,adaboost理论上可以把错误率降到0
希望到这里大家可以理解adaboost,理解集成学习。
adaboost原理和实现的更多相关文章
- Adaboost原理及目标检测中的应用
Adaboost原理及目标检测中的应用 whowhoha@outlook.com Adaboost原理 Adaboost(AdaptiveBoosting)是一种迭代算法,通过对训练集不断训练弱分类器 ...
- 集成学习之Boosting —— AdaBoost原理
集成学习大致可分为两大类:Bagging和Boosting.Bagging一般使用强学习器,其个体学习器之间不存在强依赖关系,容易并行.Boosting则使用弱分类器,其个体学习器之间存在强依赖关系, ...
- 机器学习之AdaBoost原理与代码实现
AdaBoost原理与代码实现 本文系作者原创,转载请注明出处: https://www.cnblogs.com/further-further-further/p/9642899.html 基本思路 ...
- AdaBoost原理详解
写一点自己理解的AdaBoost,然后再贴上面试过程中被问到的相关问题.按照以下目录展开. 当然,也可以去我的博客上看 Boosting提升算法 AdaBoost 原理理解 实例 算法流程 公式推导 ...
- 机器学习-分类器-Adaboost原理
Adaboost原理 Adaboost(AdaptiveBoosting)是一种迭代算法,通过对训练集不断训练弱分类器,然后把这些弱分类器集合起来,构成强分类器.adaboost算法训练的过程中,初始 ...
- AdaBoost原理,算法实现
前言: 当做重要决定时,大家可能综合考虑多个专家而不是一个人的意见.机器学习处理问题也是如此,这就是元算法背后的思路.元算法是对其他算法进行组合的一种方式,前几天看了一个称作adaboost方法的介绍 ...
- adaboost原理与实践
Adaboost是一种迭代算法,其核心思想是针对同一个训练集训练不同的分类器(弱分类器),然后把这些弱分类器集合起来,构成一个更强的最终分类器(强分类器).其算法本身是通过改变数据分布来实现的,它根据 ...
- Adaboost原理推导
Adaptive Boosting是一种迭代算法.每轮迭代中会在训练集上产生一个新的学习器,然后使用该学习器对所有样本进行预测,以评估每个样本的重要性(Informative).换句话来讲就是,算法会 ...
- Adaboost原理及相关推导
提升思想 一个概念如果存在一个多项式的学习算法能够学习它,并且正确率很高,那么,这个概率是强可学习的.一个概念如果存在一个多项式的学习算法能够学习它,并且学习的正确率仅比随机猜测略好,那么,这个概念是 ...
随机推荐
- iptables不生效解决办法
修改完iptables之后,如果不生效,需要修改一下这个参数 echo 1 > /proc/sys/net/ipv4/ip_forward 使iptables转发开启生效,如果设置为0,则不 ...
- 十大免费教程资源帮助新手快速学习JavaScript
“JavaScript”的名头相信大家肯定是耳熟能详,但只有一小部分人群了解它的使用与应用程序构建方式.这“一小部分”人指的当然是技术过硬的有为青年.网络程序员以及IT专业人员.但对于一位新手或者说外 ...
- DATE_FORMAT函数用法
一.在oracle中,当想把字符串为‘2011-09-20 08:30:45’的格式转化为日期格式,我们可以使用oracle提供的to_date函数. sql语句为: SELECT to_date(' ...
- ubuntu下matplotlib画图中文乱码问题
最近因为论文原因在学习机器学习,看的一本叫做<机器学习实战>的书,看了看还是不错的,因为其中既有原理又有实例.今天载使用matplotlib进行画图时,发现中文会显示为小方块,这个问题真是 ...
- PropertyPlaceholderConfigurer的用法:
用法1: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://w ...
- R语言之中文分词:实例
一.说明 网上提供的一个例子,做了修改与订正. 二.程序 #调入分词的库 library("rJava") library("Rwordseg") #调入绘制词 ...
- 日暮·第二章·烽烟传讯
第二章 烽烟传讯 夜幕降临,整个泉州府更见喧闹,那些个白日里将养了一日的花红柳绿再也耐不住寂寞,招招摇摇着在人来人往的主街上舒展着自己的风情,妖妖娆娆地换却春风一度. 城东的招福客栈在经过了 ...
- iOS项目立项
哎,计划总是赶不上变化,仿佛又回到了十年前高三的时候,每月.每周.每天都有计划,但是每周.每天都有计划外的因素导致了计划时时变,唯一不变的就只有变化了. 想了许久,中期计划内还是转回iOS吧,说转回其 ...
- wndows系统命令总结
window8系统下 打开运行窗口----------鼠标放到任务栏的windows图标下,右击,弹出菜单中如上图或者 打开运行窗口---------按“WIN+R”键, cmd-------打开命令 ...
- Normalize.css
根据之前的一些项目,总结了一下重置CSS: @charset "UTF-8"; html { background: #FFF; font-size: 62.5%; -ms-tex ...