【Python机器学习】利用AdaBoost元算法提高分类性能——在数据集上应用AdaBoost

在之前用过的马疝病数据集上应用AdaBoost。

在一个难数据集上的AdaBoost应用步骤:

1、收集数据:提供的文本文件

2、准备数据:确保类别标签是+1河-1而不是1和0

3、分析数据:手工检查数据

4、训练算法:在数据上,利用adaBoostTrainDS()函数训练出一系列的分类器

5、测试算法:我们拥有两个数据集,在不采用随机抽样的方法下,我们对AdaBoost和Logistic回归的结果进行比较

6、使用算法:观察该例子上的错误率。

在完成上述步骤之前,要有一个向文件中加载数据的方法:

def loadDataSet(fileName):
    numFeat=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(numFeat-1):
            lineArr.append(float(curLine[i]))
        dataMat.append(lineArr)
        labelMat.append(float(curLine[-1]))
    return dataMat,labelMat

这里,不必要指定每个文件中的特征数目。函数能够自动检测出特征的数目,同时,该函数也假定最后一个特征是类别标签。

使用基于单层决策树的AdaBoost算法:

from numpy import *

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 builsStump(dataArr,classLabels,D):
    dataMatrix=mat(dataArr)
    labelMat=mat(classLabels).T
    m,n=shape(dataMatrix)
    numSteps=10.0
    bestStump={}
    bestClassEst=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):
            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
                    bestClassEst=predictedVals.copy()
                    bestStump['dim']=i
                    bestStump['thresh']=threshVal
                    bestStump['ineq']=inequal
    return bestStump,minError,bestClassEst
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=builsStump(dataArr,classLabels,D)
        #print('D:',D.T)
        alpha=float(0.5*log((1.0-error)/max(error,1e-16)))
        bestStump['alpha']=alpha
        weakClassArr.append(bestStump)
        #print('classEst:',classEst)
        #为下一次迭代计算D
        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('错误率:',errorRate)
        if errorRate==0.0:
            break
    return weakClassArr

def adaClassify(datToClass,classifierArr):
    dataMatrix=mat(datToClass)
    m=shape(dataMatrix)[0]
    aggClassEst=mat(zeros((m,1)))
    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)

执行代码,计算错误率:

datArr,labelArr=loadDataSet('horseColicTraining2.txt')
classifierArray=adaBoostTrainDS(dataArr=datArr,classLabels=labelArr,numIt=10)
print(classifierArray)

testArr,testLabelArr=loadDataSet('horseColicTest2.txt')
prediction10=adaClassify(testArr,classifierArray)
errArr=mat(ones((67,1)))
print(errArr[prediction10!=mat(testLabelArr).T].sum())

将弱分类器的数目设定为1-10000之间的不同数字,并重复上述过程,就会得到不同的错误率结果。

可以看到,测试错误率在达到了一个最小值之后又开始上升。这类现象被称为过拟合(也称过学习)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值