提升方法(Adaboost算法实现)

提升方法(Adaboost算法实现)


一、提升方法

提升方法基于这样一种思想:对于一个复杂任务来说,将来多个专家的判断进行适当的综合所得出的判断,要比其中任何一个专家单独的判断好,实际就是“三个臭皮匠顶个诸葛亮”的道理。(统计学习方法/李航)
        对于提升方法来说其实就是在解决两个问题的过程:
Q1、如何改变训练数据权值或概率分布?
Q2、如何将弱分类器组合成一个强分类器?
对于这两个问题的回答要根据使用的具体算法才能回答。因为,本文采用的是Adaboost算法,所以就结合该算法回答这两个问题吧。
A1、Adaboost的做法是,提高那些被前一轮分类器错误分类样本的权值,而降低那些被正确分类样本的权值。这样一来,那些没有得到正确分类的数据,由于其权值得加大而受到后一轮的弱分类器的更大关注。于是,分类问题被一系列的弱分类器“分而治之”。
A2、对于弱分类器的组合,Adaboost采取加权多数表决的方法。具体地,加大分类误差率小弱分类的权值,使其在表决中起较大的作用减小分类误差率大弱分类器的权值,使其在表决中起较小的作用

二、Adaboost算法理论

(1)初始化训练数据的权值分布
(1.1)
先初始化一下分类样本数据的权值,初始值设置为平均值。N为特征值的总个数。因为,还有的限制要求。
(2)对m = 1,2,....,M
(a)使用具有全值分布Dm的训练数据集学习,使得基本分类器
1.2
G(x)是弱分类器,不同的分类器具有不同的G(x)形式.

b计算Gm(x)在训练数据集上的分类误差率
(1.3)
(c)计算Gm(x)的系数
(1.4)
其中,系数对应着弱分类器的权值。
(d)更新训练数据集的权值分布
(1.5)
其中,Zm称为规范因子。
(3)构建基本分类器的线性组合
(1.6)
其中G(x)是最终的分类器。

三、Adaboost算法代码实现

整个实现的伪代码如下:
对于每次迭代:
   	利用buildStump()函数找到最佳的单层决策树
	将最佳单层决策树加入到单层决策树数组
	计算alpha
	计算新的权重向量D
	更新累计类别估计值
	如果错误率等于0.0,则退出循环


当看《Machine Learning in action》时候,发现其中有一个处理Dm更容易理解的公式,不过理论还是一样的。
D的计算方法如下:
如果某个样本被正确分类,那么该样本的权重更改为:
(1.7)
如果某个样本被错分,那么样本的权重更改为:
(1.8)
这里的e表示是2.171826....我记得是吧。哈哈 ~这里是二分类问题,所以可以这样处理。而(1.5)的公式是无论是二分类还是多分类问题都可以使用的公式。
提别提示:
因为,本文才采取单层决策树实现算法的。所以,其中的分类函数根据单层决策树的特点写的。采用不同的弱函数会有不同的分类函数,一定要灵活运用!
(1)基于单层决策函数的Adaboost分类函数
#特别说明:
#	根据不同的弱分类器,则分类函数也会有不同的写法!
#@param dataMatrix: 表示输入的数据;type:mat
#@param dimen: 表示第几个特征值
#@param threshVal: 要分类的数值大小(阀值)
#@param threshIneq: 判断是大于号还是小于号
def stumpClassify(dataMatrix, dimen, threshVal, threshIneq):
	retArray = ones((shape(dataMatrix)[0], 1) 				#初始化
	if threshIneq == 'lt':									#判断是大于号还是小于号
		retArray[dataMatrix[:, dimen] <= threshVal] = -1.0	#这是mat数值类型的特殊功能,不是返回bool型。而是满足条件的数据
	else:
		retArray[dataMatrix[:, dimen] > threshVal] = -1.0
	return retArray

(2)单程决策树生成函数
#@param dataArr: 输入数据集
#@param classLabels: 输入数据集的类标签
#@param D: 样本权值
#@return: 建立成功的决策树	
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(); rangMax = dataMatrix[: ,i].max()
		stepSize = (rangMax - 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
				if weightedError < minError:
					minError = weightedError
					bestClasEst = predictedVals.copy()  #最优决策树对应的类标签
					bestStump['dim'] = i
					bestStump['thresh'] = threshVal
					bestStump['ineq'] = inequal
			return bestStump, minError, bestClasEst


(3)基于单层决策树的Adaboost训练过程
#@param numIt:程序最大循环次数 
#return:弱分类器数组			
def adaBoostTrainDS(dataArr, classLabels, numIt = 40):
	weakClassArr = []			#弱基函数存储数组
	m = shape(dataArr)[0]
	D = mat(ones((m, 1)))		#样本权值
	aggClassEst = mat(zeros((m, 1)))
	for i in range(numIt):
		bestStump, error, classEst = buildStump(dataArr, classLabels, D)  	#classEst就是G(x)
		print "D: ", D.T
		alpha = float(0.5 * log((1.0-error) / max(error, 1e-16))			#防止除0!公式(1.4)
		bestStump['alpha'] = alpha
		weakClassArr.append(bestStump)
		print "classEst: ", classEst
		expon = multiply(-1*alpha*mat(classLabels).T, classEst)				#exp(*)的求解
		D = multiply(D, exp(expon))											#(1.7)(1.8)重新计算D
		D = D / D.sum()
		aggClassEst += alpha * classEst										#f(x) (1.6)
		print "aggClassEst: ", aggClassEst
		aggErrors = multiply(sign(aggClassEst) != mat(classLabels).T, ones((m, 1)))  #em (1.3)
		errorRate = aggErrors.sum() / m
		print "total error: ", errorRate, "\n"
		if errorRate == 0.0: break;
	return weakClassArr

(4)AdaBoost分类函数
#@param dataToClass: 一个或多个待分类样例
#@param clasifierArr:多个弱分类器组成的数组		
def adaClassify(dataToClass, classifierArr):
	dataMatrix - mat(dataToClass)
	m = shape(dataMatrix)[0]
	aggClassEst = mat(zeros((m, 1)))		#G(x)
	for i in range(len(classifierArr)):
		classEst = stumpClassify(dataMatrix, classifierArr[i]['dim'], classifierArr[i]['thresh'],classifierArr[i]['ineq']) #Gm(x)
		aggClassEst += classifierArr[i]['alpha'] * classEst  #f(x) ,G(x)
		print aggClassEst
	return sign(aggClassEst)








  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值