adaBoost 源码

#!/usr/python/bin
#-*- coding:utf-8 -*-

from numpy import *

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

def stumpClassify(dataMatrix,dimen,threshVal,threshIneq):		#根据选择的特征,阈值,规则将样本数据dataMatrix进行分类
	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		#将每个特征的最大最小值之间分为10步
	bestStump = {}		#最佳分类时的各种数据,包括维度,阈值,分类采用的符号(大于,小于)
	bestClasEst = mat(zeros((m,1)))
	minError = inf
	for i in range(n):		#从1~n个特征中找第i个特征
		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)))		#初始化错误矩阵均为1
				errArr[predictedVals == labelMat] = 0		#如果预测正确了就改为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

def adaBoostTrainDS(dataArr,classLabels,numIt = 40):		#完整的adaBoost算法
	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)))		#计算这个弱分类器的权重值,1e-16确保在没有错误时不会发生除0溢出
		bestStump['alpha'] = alpha
		weakClassArr.append(bestStump)		#将此弱分类器放到弱分类器数组中
		print "classEst: ",classEst.T 		#输出此弱分类器的分类结果
		expon = multiply(-1*alpha*mat(classLabels).T,classEst)		#更新每个样本的权值
		D = multiply(D,exp(expon))
		D = D/D.sum()			#更新每个样本的权值
		aggClassEst = aggClassEst+alpha*classEst 		#将分类结果加到强分类器中,加入之前要先乘上权值
		print "aggClassEst: ",aggClassEst.T
		aggErrors = multiply(sign(aggClassEst)!=mat(classLabels).T,ones((m,1)))		#计算强分类器的错误个数
		errorRate = aggErrors.sum()/m 		#多个若分类器累加的错误率
		print "total error: ",errorRate,"\n"
		if errorRate == 0.0:		#若错误率为0,则提前退出
			break
	return weakClassArr, aggClassEst

def adaClassify(datToClass, classifierArr):		#输入测试数据和弱分类器数组,输出样本的分类
	dataMatrix = mat(datToClass)
	m = shape(dataMatrix)[0]
	aggClassEst = mat(zeros((m,1)))			#初始化对这m个样本的分类结果
	for i in range(len(classifierArr)):
		classEst = stumpClassify(dataMatrix,classifierArr[i]['dim'],classifierArr[i]['thresh'],classifierArr[i]['ineq']) 	#弱分类器的分类结果
		aggClassEst = aggClassEst+classifierArr[i]['alpha']*classEst 		#累加到强分类器的结果
		print aggClassEst			#打印出中间分类结果
	return sign(aggClassEst)		#根据符号判断分类

def loadDataSet(fileName):		#把数据从文件中导入,返回样本和所属分类
	dataNum = len(open(fileName).readline().split('\t'))		#查找数据中每个样本的特征数目
	dataMat = []
	labelMat = []
	fr = open(fileName)
	for line in fr.readlines():
		lineArr = []
		curLine = line.strip().split('\t')			#当前行
		for i in range(dataNum-1):			#将当前行的前dataNum-1个特征放入当前行数据集中
			lineArr.append(float(curLine[i]))
		dataMat.append(lineArr)			#将当前行数据加入总的数据中
		labelMat.append(float(curLine[-1]))			#将当前行的最后一个特征也就是样本的所属类放到labelMat中
	return dataMat,labelMat

def plotROC(predStrengths, classLabels):		#画ROC曲线并计算AUC的函数,输入预测结果和样本类别
	import matplotlib.pyplot as plt
	cur = (1.0, 1.0)
	ySum = 0.0 			#用于计算AUC的值
	numPosClas = sum(array(classLabels) == 1.0)		#计算样本中正例的数目
	yStep = 1/float(numPosClas)			#1/正例的数目就是y轴上的步长
	xStep = 1/float(len(classLabels)-numPosClas)		#1/负例数目就是x轴上的步长
	sortedIndicies = predStrengths.argsort()		#对分类结果进行排序,每个数字就是为正类的可能性排序(1就是最大可能)(在分类向量中值越大越可能是正类)
	fig = plt.figure()
	fig.clf()
	ax = plt.subplot(111)
	for index in sortedIndicies.tolist()[0]:
		if classLabels[index] == 1.0:		#index为其中的元素,不是从1开始,而是从第一个元素为正类的排名开始
			delX = 0
			delY = yStep
		else:				#根据这个元素的正负情况移动x,y轴坐标的值
			delX = xStep
			delY = 0
			ySum = ySum+cur[1]		#每次x发生变化就累加当前的y值,最后在乘上x的步长,相当于每个小矩形相加了(是从[1,1]向[0,0]开始画的)
		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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值