【Python机器学习】利用AdaBoost元算法提高分类性能——完整的AdaBoost算法的实现

上一篇记录了简化的单词决策树函数(buildStump())的实现。下面实现完整AdaBoost算法。

完整AdaBoost算法的伪代码:

对每次迭代:

利用buildStump()函数找到最佳的单层决策树

将最佳单层决策树加入到单层决策树数组

计算alpha

计算新的权重向量D

更新累计类别估计值

如果错误率等于0.0,退出循环

具体实现代码:

python 复制代码
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


dataMat,classLabels=loadSimpData()
D=mat(ones((5,1))/5)
classifierArray=adaBoostTrainDS(dataMat,classLabels,9)

AdaBoost算法的输入参数包括数据集、类别标签以及迭代次数numIt,其中numIt是在整个AdaBoost算法中唯一需要用户指定的参数。

我们假设迭代次数为9,如果算法在第三次迭代之后错误量为0,那么就会退出迭代过程,这时就不需要执行所有的9次迭代。

函数名称尾部的DS代表的就是单层决策树,它是AdaBoost中最流行的弱分类器(当然并非唯一可用的弱分类器)。上述函数是建立与单层决策树之上的,但是我们也可以很容易对此进行修改以引入其他基分类器。实际上,任意分类器都可以作为基分类器。上述算法会输出一个单层决策树的数组,因此首先需要建立一个新的Python表来对其进行存储。然后,得到数据集中的数据点的数据m,并建立一个列向量D。

向量D非常重要,它包含了每个数据点的权重。一开始,这些权重都赋予了相等的值。在后续的迭代中,AdaBoost算法会在增加错分数据的权重的同时,降低正确分类的权重。D是一个概率分布向量,因此其所有的元素之和为1.0。为了满足要求,一开始的所有元素都会被初始化乘1/m,同时,程序还会建立另一个列向量aggClassEsr,记录每个数据点的类别估计累计值。

AdaBoost算法的核心在于for循环,该循环运行numIt次或者直到训练错误率为0为止。循环中的第一件事就是利用buildStump()函数建立一个单层决策树。该函数的输入为权重向量D,返回的则是利用D而得到的具有最小错误率的单层决策树,同时返回的还有最小错误率以及估计的类别向量。

加下来,需要计算的则是alpha值。该值会告诉总分类器本次单层决策树输出结果的权重。其中的语句max(error,1e-16)用于确保在没有错误时不会发生除零溢出。而后,alpha值加入到bestStump字典中,该字典又添加到列表中。该字典包含了分类所需要的所有信息。

接下来则是计算下一次迭代中需要的新权重向量D。在训练错误率为0时,就要提前结束for循环。此时程序是通过aggClassEst变量保持一个运行时的类别估计值来实现的。该值只是一个浮点数,为了得到二值分类结果还需要调用sign函数,如果总错误率为0,则由break语句中止for循环。

最后输出结果:

python 复制代码
dataMat,classLabels=loadSimpData()
D=mat(ones((5,1))/5)
classifierArray=adaBoostTrainDS(dataMat,classLabels,9)
print(classifierArray)

该数组包含3部词典,其中包含了分类所需要的所有信息。

相关推荐
旧故新长6 分钟前
支持Function Call的本地ollama模型对比评测-》开发代理agent
人工智能·深度学习·机器学习
明月与玄武14 分钟前
Python编程的真谛:超越语法,理解编程本质
python·编程语言
我真的不会C16 分钟前
QT窗口相关控件及其属性
开发语言·qt
CodeCraft Studio16 分钟前
Excel处理控件Aspose.Cells教程:使用 Python 在 Excel 中进行数据验
开发语言·python·excel
火柴盒zhang22 分钟前
websheet之 编辑器
开发语言·前端·javascript·编辑器·spreadsheet·websheet
景天科技苑29 分钟前
【Rust】Rust中的枚举与模式匹配,原理解析与应用实战
开发语言·后端·rust·match·enum·枚举与模式匹配·rust枚举与模式匹配
知来者逆30 分钟前
计算机视觉——速度与精度的完美结合的实时目标检测算法RF-DETR详解
图像处理·人工智能·深度学习·算法·目标检测·计算机视觉·rf-detr
阿让啊34 分钟前
C语言中操作字节的某一位
c语言·开发语言·数据结构·单片机·算法
এ᭄画画的北北35 分钟前
力扣-160.相交链表
算法·leetcode·链表
椰羊~王小美40 分钟前
LeetCode -- Flora -- edit 2025-04-25
java·开发语言