python实现adaBoost

from numpy import *
import matplotlib.pyplot as plt

#比较阈值,进行分类 threshVal 是阈值,即对某个特征的分割,threshIneq为不等号,确定是大于为-还是小于为-1
def stumpClassify(dataMtrix,dimen,threshVal,threshIneq): #dim为那一列(那个属性)
    retArray = ones((shape(dataMtrix)[0],1))  #把类别都先设置为1
    if threshIneq == 'lt':
        retArray[dataMtrix[:,dimen] <= threshVal] = -1
    else:
        retArray[dataMtrix[:,dimen] > threshVal] = -1

    return retArray

#单层决策树 D为权重
def buildStump(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 inequel in ['lt','gt']:
                threshVal = rangeMin + float(j)*stepSize  #每一步划分的阈值
                predictedVals = stumpClassify(dataMAtrix,i,threshVal,inequel) #预测的分类值

                errArr = mat(ones((m,1))) #假全错了
                errArr[predictedVals == labelMat] = 0 #分正确的变为0
                weightError = D.T*errArr #errArr为1的位置说明是分错的,则对应位子的样本的权重相加

                #保存信息
                if weightError < minError:
                    minError = weightError
                    bestClassEst = predictedVals.copy() #保存最好的分类预测值
                    bestStump['dim'] = i #最好的列(最好的属性)
                    bestStump['thred'] = threshVal #属性列最好的分割阈值
                    bestStump['ineq'] = inequel  #最好的符号
        return bestStump,minError,bestClassEst

#数据集
def loadData():
    dataMat = 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 dataMat,classLabels
#绘制数据集
def plotData(dataMat,classLabels):
    for index,data in enumerate(dataMat):
        # print(data)[[1.  2.1]]
        #            [[2.  1.1]]
        #            [[1.3 1. ]]
        #            [[1. 1.]]
        #            [[2. 1.]]
        if classLabels[index] > 0:
            plt.plot(data[0,0],data[0,1],'or')
        else:
            plt.plot(data[0,0],data[0,1],'ob')
    plt.show()

#基于单层的决策树AdaBoost训练函数 numIt指的迭代的次数
def adaBoost(dataArr,classLabels,numIt = 40):
    weakClassArr = [] #保存每次迭代器的信息
    m = shape(dataArr)[0]
    D = mat(ones((m,1))/float(m)) #初始化权重
    aggClassESt = mat(zeros((m,1))) #累计每次分类的结果
    for i in range(numIt):
        bestStump,error,classEst = buildStump(dataArr,classLabels,D)
        alpha = float(0.5*log((1 - error)/max(error,1e-16))) #函数的权重
        bestStump['alpha'] = alpha  #记录权重
        weakClassArr.append(bestStump) #保存每一轮的结果信息

        #更新权重
        expon = multiply(-1 * alpha * mat(classLabels).T, classEst)  # 计算指数
        D = multiply(D, exp(expon))
        D = D / D.sum()  # 归一化
        #累计每个函数的预测值 (权重 * 预测的类)
        aggClassESt += alpha *classEst
        errorRate = 1.0 * sum(sign(aggClassESt) != mat(classLabels).T)/m  #预测的和真实的标签不应样的个数/总的个数
        if errorRate == 0.0:
            break  #如果提前全部分类真确,则提前停止循环
    return weakClassArr

#分类
def adaClassify(datatoClass,classifierArr):#大分类的数据,训练好的分类器
    dataMatrix = mat(datatoClass)
    m = shape(dataMatrix)[0]
    aggClassEst = mat(zeros((m,1)))  #保存预测的值 m个数据m个预测值
    for i in range(len(classifierArr)): #循环遍历所有的分类器
        classEst = stumpClassify(dataMatrix,classifierArr[i]['dim'],
                                 classifierArr[i]['thred'],
                                 classifierArr[i]['ineq'])
        aggClassEst += classifierArr[i]['alpha'] * classEst #第i个分类器的预测值*他的权重
    return sign(aggClassEst)
if __name__=='__main__':
    dataSet,classLabels = loadData()
    weakClassArr = adaBoost(dataSet,classLabels)
    data = [
                         [2.,1.1],
                         [1.3,1.],
                         [1.,1.],
                         [2.,1.]]
    ada = adaClassify(data,weakClassArr)
    print(ada)

关键点:每个单层的决策树,遍历每个属性,在每个属性上遍历不同的阈值,在每个阈值上确定符号(是大于为-1还是小于为-1)求解某个特征上,某个阈值,某个符号最小的分类器,因为为单层决策树,所以智能选择一个属性进行划分,就看那个属性上划分的分类错误最小,就在那个划分,所有遍历属性,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值