欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

集成算法——Adaboost代码

程序员文章站 2022-07-13 08:52:29
...

     集成算法是我们将不同的分类器组合起来,而这种组合结果就被称为集成方法或者是元算法。使用集成方法时会有多种形式:可以是不同算法的集成,也可以是同意算法在不同设置下的集成,还可以是数据集不同部分分配给不同分类器之后的集成。

两种形式:

bagging方法:从原始数据集选择S次后得到S个新数据集,之后将某个学习算法分别作用于数据集,就得到了S个分类器,在对新的数据集进行分类时,使用这些分类器进行分类,同时,选择分类器投票结果中最多的类别作为最后的分类结果。不同的分类器是通过串行训练而获得的,每个新分类器都根据已训练出来的分类器的性能来进行训练。分类器的权重是相等的。

例子:随机森林

boosting方法:使用多个分类器,它是通过集中关注被已有分类器错分的那些数据来获得新的分类器,boosting分类的结果是基于所有分类器的加权求和结果的,权重不相等,每个权重代表的是其对应分类器在上一轮迭代中的成功度。

例子:Adaboost,GBDT

AdaBoost的思想:

    1.训练数据中的每一个样本,并赋予一个权重,初始化为相等值,这些权重构成了向量D

    2.首先在训练数据上训练出一个弱分类器并计算该分类器的错误率,然后在同一个数据集上再次训练弱分类器。在分类器的第     二次训练中,将会重新调整每个样本的权重。其中第一次分对的样本的权重会降低,而第一次分错的样本的权重会提高。

    3.为了从所有弱分类器中得到最终的分类结果,Adaboost为每个分类器分配了一个权重alpha,这些alpha值是基于每个弱分类器的错误率进行的

                               集成算法——Adaboost代码集成算法——Adaboost代码

4.计算出alpha值后,可以对权重向量D进行更新,以使得那些正确分类的样本的权重降低而错分样本的权重升高。

 正确分类:集成算法——Adaboost代码


错误分类:集成算法——Adaboost代码


计算出D之后,在进行下一轮的迭代,会不断地重复训练和调整权重的过程,直到训练集错误率为0或者是弱分类器的数目达到用户的指定值为止。

代码实现:

import numpy as np
import matplotlib.pyplot as plt
def loadSimpData():
    dataMat=np.matrix([[1.,2.1],
                  [1.5,1.6],
                   [1.3,1.],
                   [1.,1.],
                   [2.,1.]
                  ])
    classLabels=[1.0 , 1.0 , -1.0 ,-1.0 ,1.0]
    return dataMat,classLabels
#数组过滤  将数据分成正好相反的两类
def  stumpClassify(dataMatrix,dimen,threshVal,threshIneq): # dimen特征值  threshVal 阈值  threshIneq 代表是lt或者是gt
    retArray=np.ones((np.shape(dataMatrix)[0],1))  #数组元素全部设置为1
    if threshIneq=='lt':
        retArray[dataMatrix[:,dimen]<= threshVal]=-1.0
    else:
        retArray[dataMatrix[:,dimen]> threshVal]=-1.0
    return retArray

构建单层决策树,找到错误率最小的特征和索引

def buildStump(dataArr, classLabels,D): #最佳基于数据的权重向量D来定义的
    dataMatrix=np.mat(dataArr);labelMat=np.mat(classLabels).T
    m,n=np.shape(dataMatrix)
    numSteps=10.0;bestStump={};bestClasEst= np.mat(np.zeros((m,1)))  #bestStump空字典
    minError = float('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= np.mat(np.ones((m,1)))
                errArr[predictedVals== labelMat]=0
                weightedError=D.T*errArr  
                print("split:dim %d, thresh %.2f ,thresh ineqal : %s, the weighted error is %.3f" % (i, threshVal,inequal,weightedError))
                # inequal 类型
                if weightedError<minError:
                    minError = weightedError
                    bestClasEat = predictedVals.copy()
                    bestStump['dim']=i
                    bestStump['thresh']=threshVal
                    bestStump['ineq']=inequal
    return bestStump,minError,bestClasEat
首先第一次训练计算出该分类器的错误率,然后继续训练,调整权重,
def adaBoostTrains(dataArr,classLabels,numIt=40):
    weakClassArr = []
    m=np.shape(dataArr)[0]
    D=np.mat(np.ones((m,1))/m)
    aggClassEst=np.mat(np.zeros((m,1)))
    for i in range (numIt):
        #利用buildStump()找到最佳的单层决策树
        bestStump,error,classEst = buildStump(dataArr,classLabels,D) #D 权重
        print("D: ",D.T)
        alpha=float(0.5*np.log((1.0-error)/max(error,1e-16)))  #alpha公式 1e是科学计数法   max确保在没有错误时除以0不会溢出
        bestStump['alpha']=alpha
        weakClassArr.append(bestStump)#  转化为list
        print("classEst:", classEst.T) #特征
        #权重的分布
        expon=np.multiply(-1*alpha*np.mat(classLabels).T,classEst)#如果分对了,则同号,分错了异号,正好对应公式
        D=np.multiply(D,np.exp(expon))
        D=D/D.sum()   
        #  ai*yi
        aggClassEst += alpha*classEst
        print("aggClassEst :" ,aggClassEst.T)
        #  sign将aggClassEst转化为[1,-1.....]的m*1的矩阵,再与特征矩阵对比,得出[1,0....],其中1为错误分类,转置之后与ones相乘得到错误分类的个数
        aggErrors=np.multiply(np.sign(aggClassEst)!= np.mat(classLabels).T,np.ones((m,1)))
        #计算错误率
        errorRate = aggErrors.sum()/m
        print("total error:",errorRate,"\n")
        if errorRate == 0.0 :break
    return weakClassArr
dataArr,classLabels=loadSimpData()
weakClassArr,aggClassEst = adaBoostTrains(dataArr,classLabels)
print(weakClassArr)
print(aggClassEst)

输出结果:

集成算法——Adaboost代码