您的位置:首页 > 其它

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

2018-03-08 17:10 711 查看

一,AdaBoost概述

AdaBoost是adaptive boosting(自适应boosting)的缩写。

AdaBoost是一种Boosting族的集成学习方法。弱学习器之间是强依赖序列化的,即不同的学习器是通过串行训练而获得的,每个新分类器都根据已训练出来的分类器的性能来进行训练。Boosting是通过集中关注被已有分类器错分的那些数据来获得新的分类器。

AdaBoost特点如下:

优点:泛化错误率低,易编码,可以应用在大部分分类器上,无参数调整。

缺点:对离群点敏感。

适用数据类型:数值型和标称型。

二,AdaBoost具体流程:基于错误提升分类器的性能

1,具体流程

训练数据中的每个样本并赋予其一个权重, 这些权重构成了样本权重向量D。一开始这些样本权重都是初始化为相等值。

首先在训练数据上训练出一个弱分类器,并计算弱分类器的错误率,然后在同一数据集再次训练弱分类器。

在分类器的第二次训练当中,将会重新调整每个样本的权重, 其中第一次分对的样本的权重将会降低,而第一次分错的样本的权重将会提高。

最终的分类结果是所有弱分类器的线性加权求和的结果,其中每个弱分类器的权重α是基于每个弱分类器的错误率来进行计算的。具体如下:

错误率ε定义如下:

ε=错误分类样本数所有样本分类数

则α的计算公式如下(由最小化指数损失函数得到):

α=12ln1−εε

函数图像如下:



即错误率越大权重越小。

计算出α之后,就可以对样本权重向量进行更新,上一次正确分类的样本权重降低,错误分类的样本权重升高。

正确分类的样本权重更改为:

D(t+1)i=D(t)ie−αSum(D)

错误分类的样本权重更改为:

D(t+1)i=D(t)ieαSum(D)

这些计算公式也是由最小化分类误差确定的,具体推导过程省略。

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

如下图所示:



2,伪代码



三,AdaBoost的实现

1,基于单层决策树构建弱分类器

单层决策树也成决策树桩,是最简单的一种决策树。

构建伪代码如下:



Python代码如下:

def buildStump(dataArray,classLabels,D):
dataMat = mat(dataArray)
labelsMat = mat(classLabels).T
m,n = shape(dataMat)
numSteps = 10.0
bestStump = {}
minError = inf
bestclasEst = mat(zeros((m,1)))
for i in range(n):
rangeMin = dataMat[:,i].min()
rangeMax = dataMat[:,i].max()
stepSize = (rangeMax-rangeMin)/numSteps
for j in range(-1,int(numSteps)+1):
for inequal in ['lt','gt']:
threshVal = rangeMin+float(j)*stepSize
predictedVal = ones((m,1))
if inequal == 'lt':
predictedVal[dataMat[:,i]<=threshVal] = -1.0
else:
predictedVal[dataMat[:,i]>threshVal] = -1.0
errorArr = ones((m,1))
errorArr[predictedVal==labelsMat] = 0
weightedError = float(D.T*errorArr)
print("dimen:%d,thresh:%.2f,thresh inequal:,%s,weighted error: %.3f"%(i,threshVal,inequal,weightedError))
if weightedError < minError:
minError = weightedError
bestclasEst = predictedVal.copy()
bestStump['dim'] = i
bestStump['thresh'] = threshVal
bestStump['ineq'] = inequal
return bestStump,minError,bestclasEst


单层决策树只需要保存Dim、ThreshVal、InEquality和alpha即可。

单层决策树的生成函数是决策树的一个简化版本,也就是所谓的弱分类器,下面就将使用多个弱分类器来构建AdaBoost算法。

2,AdaBoost算法的实现

伪代码如下:



Python代码如下:

def adaBoostTrainsDS(dataArr,classLabels,numIt=40):
weakClassArr = []
dataMat = mat(dataArr)
m = shape(dataMat)[0]
D = mat(ones((m,1))/m)
aggClassEst = mat(zeros((m,1)))
for i in range(numIt):
bestStump,error,classEst = buildStump(dataMat,classLabels,D)
alpha = 0.5*log((1-error)/max(error,1e-16))
bestStump['alpha'] = alpha
weakClassArr.append(bestStump)
expon = multiply(-alpha*mat(classEst),mat(classLabels).T)
D = multiply(D,exp(expon))
D = D/D.sum()
aggClassEst += alpha*classEst
aggError = multiply(sign(aggClassEst)!=mat(classLabels).T,ones((m,1)))
errorRate = aggError.sum()/m
print('the total error is:%.2f'%(errorRate))
if errorRate==0:
break
return weakClassArr


用户需要指定训练的迭代次数。

3,测试算法:基于AdaBoost的分类

Python代码如下:

def stumpClassify(dataMatrix,dimen,threshVal,threshIneq):
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 adaClassify(datToClass,classifierArr):
dataMat = mat(datToClass)
m = shape(dataMat)[0]
aggClassEst = mat(zeros((m,1)))
for i in range(len(classifierArr)):
classEst = stumpClassify(dataMat,classifierArr[i]['dim'],classifierArr[i]['thresh'],classifierArr[i]['ineq'])
aggClassEst += classEst*classifierArr[i]['alpha']
print(aggClassEst)
return sign(aggClassEst)


4,在一个难的数据集上应用AdaBoost

读文件数据的代码:

def loadDataSet(filename):
numFeat = len(open(filename).readline().split('\t'))-1
fr = open(filename)
dataArr = []
classLabels = []
for line in fr.readlines():
lineArr = line.strip().split('\t')
featureArr = []
for j in range(numFeat):
featureArr.append(float(lineArr[j]))
dataArr.append(featureArr)
classLabels.append(float(lineArr[-1]))
dataMat = mat(dataArr)
return dataMat,classLabels


使用AdaBoost进行预测的过程如下:

>>> datArr,labelArr = adaboost.loadDataSet('horseColicTraining2.txt')
>>> classifierArray = adaboost.adaBoostTrainDS(datArr,labelArr,10)
total error: 0.284280936455
total error: 0.284280936455
.
.
total error: 0.230769230769
>>> testArr,testLabelArr = adaboost.loadDataSet('horseColicTest2.txt')
>>> prediction10 = adaboost.adaClassify(testArr,classifierArray)
To get the number of misclassified examples type in:
>>> errArr=mat(ones((67,1)))
>>> errArr[prediction10!=mat(testLabelArr).T].sum()
16.0
>>> 16/67
0.23880597014925373


四,AdaBoost总结

通常情况下,AdaBoost会达到一个稳定的测试错误率,而并不会随着弱分类器数目的增多而增加。

很多人认为,AdaBoost和SVM是监督机器学习中最强大的两种方法。

AdaBoost这种针对错误的调节能力正是它的强大之处。

总之,AdaBoost算法十分强大,它能快速处理其他分类器很难处理的数据集。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  机器学习