机器学习实战笔记4

来源:互联网 发布:淘宝能买到a碟吗 编辑:程序博客网 时间:2024/05/24 00:42

第七章 AdaBoost

adaBoost算法见统计学习方法P138

下面讲一下机器学习实战中的代码:

首先是求出当层最小误分率,这里用到的是决策树生成函数(其实统计学习方法中一直不明白到底是怎么获取基本分类器的,而且给出的例子维度还是1维的,应该说是就没看懂AdaBoost)

训练集如下矩阵所示:

x(1)1x(1)2.x(1)Nx(2)1x(2)2.x(2)N............x(n)1x(n)2.x(n)N

[y1y2...yN]

代码中给出的求解方法是,对上面的每一列进行分析,选取其中的最小值,最大值,从最小值开始,以指定的步长增加,作为阈值;规定大于该阈值为-1或者小于等于该阈值为-1;这样便得到一列预测矩阵,作为基本分类器G(x),并和y比较,求出在给定权值矩阵下的误差率,找到最小的误差率返回

代码如下:

#根据阈值获取预测列矩阵def stumpClassify(dataMatrix,dimen,threshVal,threshIneq):    retArray=ones((shape(dataMatrix)[0],1))#以dataMatrix为行,1列,值为1的矩阵    if threshIneq=='lt':        retArray[dataMatrix[:,dimen]<=threshVal]=-1.0#表示dataMatrix中第dimen列的元素如果有小于等于threshVal的,就将对应的retArray的值置为-1    else:        retArray[dataMatrix[:,dimen]>threshVal]=-1.0#获取当前弱分类器下的最小误差率对应的信息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)))#m行1列的0矩阵    minError=inf#表示无穷大    #这层循环对每一列(特征)遍历    for i in range(n):        rangeMin=dataMatrix[:,i].min()#表示获取矩阵的第i列的最小值        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)))#获取m行1列值为1的列矩阵                errArr[predictedVals==labelMat]=0#将预测列矩阵和给出的标签矩阵比较,相同的置为0                weightedError=D.T*errArr#计算分类误差率(即误差的权值求和),D表示的时上一回的权值矩阵                #判断是否小于最小误差率,是则更新                if weightedError<minError:                    minError=weightedError#最小误差率                    bestClasEst=predictedVals.copy()#对应的预测列矩阵                    bestStump['dim']=i#该预测矩阵针对的时第几列(哪个特征)                    bestStump['thresh']=threshVal#对该特征的判断阈值                    bestStump['ineq']=inequal#是基于小于该特征还是基于大于该特征来分类-1,1    return bestStump,minError,bestClasEst

AdaBoost算法是求解多个弱分类器,将其相加得到最终的分类器,指标是使最终的分类器误差率最小

第一轮的权值矩阵均分给每个训练数据

D1=(w11,w12,w13,...,w1N)w1i=1N,i=1,2,...,N

对m=1,2,3…,M,做如下循环:

使用权值矩阵Dm通过上述方法学习到Gm(x) ,然后将得到的预测矩阵和y矩阵比较,求出分类误差率em ,计算该分类器的系数αm

αm=12log1emem

em越小,系数越大,即该分类器对于最终分类器而言作用越大;

更新Dm得到Dm+1:

Dm+1=(wm+1,1,wm+1,2,...,wm+1,N)wm+1,i=wmiZmexp(αmyiGm(xi))Zm=m=1Nwmiexp(αmyiGm(xi))

上式中第二个式子可以写为:
wm+1,i=wmiZmeαm,Gm=yiwmiZmeαm,Gmyi

注意到权值更新原理是,当前分类器分类正确的样本权值缩小,而误分类的样本则权值扩大,这样此轮误分类的样本在下一轮学习中就会起更大的作用,这是Adaboost的一个特点

回到循环处

代码如下:

#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)#计算当前分类器下最小误差率        alpha=float(0.5*log((1.0-error)/error))#计算该分类器的系数        bestStump['alpha']=alpha        weakClassArr.append(bestStump)#把每一个弱分类器对应的bestStump添加进去        expon=multiply(-1*alpha*mat(classLabels).T,classEst)#列矩阵内积        D=multiply(D,exp(expon))        D=D/D.sum()#更新权值矩阵        aggClassEst+=alpha*classEst#弱分类器相加        #aggClassEst)!=mat(classLabels).T : 两个列矩阵比较,返回的是一个列矩阵,其中满足条件则为true,否则为false,对应下面的0和1        aggErrors=multiply(sign(aggClassEst)!=mat(classLabels).T,ones((m,1)))#如上,最后的结果为满足条件位置为1,不满足条件的位置为0        errorRate=aggErrors.sum()/m#统计1的个数,占总数的比;        if errorRate==0.0:break    return weakClassArr

完!

原创粉丝点击