集成学习—Boosting实现
弱学习器我们选用单层决策树,亦称为决策树桩,意思就是只有一个分支,要选取一个属性使得分类结果最好,这里不同于决策树常用的信息增益算法。
AdaBoosting实现有两个步骤
- 实现决策树桩
- 算出弱学习器的权重和更新数据集的权重
1. 首先处理数据:
from numpy import *
#def loadData():
# 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 loadDataSet(fileName):
numFeat = len(open(fileName).readline().split('\t'))
dataMat = []; labelMat = []
fr = open(fileName) #数据的格式是[属性,标签]
for line in fr.readlines(): #要求标签为1或-1
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
2. 首先实现决策树桩:
这里的算法本质是遍历所有属性的所有取值,取出有最好的决策结果的那一组。
def stumpClassify(dataMatrix,dimen,threshVal,threshIneq):
retArray = ones((shape(dataMatrix)[0],1)) #5*1
if threshIneq == 'lt': #布尔索引 dataMartix[:dimen]是每个样本的第dimen个属性的取值
retArray[dataMatrix[:,dimen] <= threshVal] = -1.0 #该取值若小于threshVal的话,retArray对应的位置为-1,否则是1
else:
retArray[dataMatrix[:,dimen] > threshVal] = -1.0
return retArray
def buildStump(dataArr,classLabels,D):#D是数据集的权重
dataMatrix = mat(dataArr);labelMat = mat(classLabels).T
m,n = shape(dataMatrix) #m=5个样本,n=2个属性
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): #threshVAl就是分段值,小于Val的和大于Val的分支到不同节点,这里不同于离散型的信息熵算法
for inequal in ['lt','gt']:
threshVal = (rangeMin+float(j)*stepSize)
predictedVals = stumpClassify(dataMatrix,i,threshVal,inequal) #给定分段值threshVal,求预测的决策结果
errArr = mat(ones((m,1)))
errArr[predictedVals == labelMat] = 0 #如果预测准确则该位置的误差为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. AdaBoosting算法:
def adaBoostTrainDS(dataArr,classLabels,numIt=40):
weakClassarr=[] #记录弱分类器的信息
m=shape(dataArr)[0] #m=5
D=mat(ones((m,1))/m) #一开始的权重
aggClassEst = mat(zeros((m,1))) #一开始的预测全0
for i in range(numIt): #循环次数
bestStump,error,classEst = buildStump(dataArr,classLabels,D) #决策树桩
alpha = float(0.5*log((1.0-error)/max(error,1e-16)))#避免除0 #得到该分类器的权重
bestStump['alpha'] = alpha #记录下来
weakClassarr.append(bestStump)
expon = multiply(-1*alpha*mat(classLabels).T,classEst) #下面3行更新权重D
D = multiply(D,exp(expon))
D = D/D.sum()
aggClassEst += alpha*classEst #最终预测结果加上这次预测的结果
aggErrors = multiply(sign(aggClassEst)!=mat(classEst),ones((m,1))) #计算误差
errorRate = aggErrors.sum()/m #如果没有误差则结束
if errorRate == 0.0:
break
return weakClassarr,aggClassEst
4. 结果:
参考《机器学习实战》第7章