Python实现Adaboost

1.Adaboost概念

提升方法的思路是综合多个分类器,得到更准确的分类结果。 即“三个臭皮匠顶个诸葛亮”。《统计学习方法》称AdaBoost是提升算法的代表,所谓提升算法,指的是一种常用的统计学习方法,应用广泛且有效。在分类问题中,它通过改变训练样本的权重,学习多个分类器,并将这些分类器进行线性组合,提髙分类的性能。
AdaBoost算法的基本思想:
1)多轮训练,多个分类器
2)每轮训练增加错误分类样本的权值,降低正确分类样本的权值
3)降低错误率高的分类器的权值,增加正确率高的分类器的权值

2.Adaboost算法流程

给定一个二类分类的训练数据集,T={(x1,y1),(x2,y2),…(xn,yn)}T=\{({x_1},y_1),({x_2},y_2),\dots({x_n},y_n)\}T={(x1,y1),(x2,y2),(xn,yn)},其中χi∈X⊆Rnχ_i∈X⊆ R^nχiXRn表示实例的特征向量,yi∈Y∈{+1,−1}y_i∈Y\in\{+1,-1\}yiY{+1,1},XXX是实例空间,YYY是标记集合。AdaBoost利用以下算法,从训练数据中学习一系列弱分类器或基本分类器,并将这些弱分类器线性组合成为一个强分类器。
AdaBoost算法
输入:训练数据集T={(x1,y1),(x2,y2),…(xn,yn)}T=\{({x_1},y_1),({x_2},y_2),\dots({x_n},y_n)\}T={(x1,y1),(x2,y2),(xn,yn)},其中χi∈X⊆Rnχ_i∈X⊆ R^nχiXRn,yi∈Y∈{+1,−1}y_i∈Y\in\{+1,-1\}yiY{+1,1};弱学习算法;
输出:最终分类器G(x)G(x)G(x)
(1)初始化训练数据的权值分布

D1=(W11,...,W1i,...,W1n)D_1=(W_{11},...,W_{1i},...,W_{1n})D1=(W11,...,W1i,...,W1n)

每个w的下标由两部分构成,前一个数表示当前迭代次数,与D的下标保持一致,后一个数表示第几个权值,与位置保持一致。初始情况下,每个权值都是均等的。
(2)对m=1,2,...Mm=1,2,...Mm=1,2,...M
(这里的M表示训练的迭代次数,是由用户指定的。每轮迭代产生一个分类器,最终就有M个分类器,当然我们也可以设置一些条件,满足某些条件时跳出迭代,例如,所有样本都分对了,误差为0时,跳出迭代):
(a)使用具有权值分布的训练数据集学习,得到基本分类器

Gm(x):X→{+1,−1}G_m(x):X{\rightarrow} \{+1,-1\}Gm(x):X{+1,1}

(b)在Gm(x)G_m(x)Gm(x)训练数据集上的分类误差率

em=∑iNP(Gm(xi)≠yi)=∑iNwmiI(Gm(xi)≠yi))e_m=\sum_i^NP(G_m(x_i){\neq}y_i)=\sum_i^Nw_{mi}I(G_m(x_i){\neq}y_i))em=iNP(Gm(xi)̸=yi)=iNwmiI(Gm(xi)̸=yi))

分类误差率这个名字可能产生误解,这里其实是个加权和。
(c)计算Gm(x)G_m(x)Gm(x)的系数

αm=12log1−emem\alpha_m = \frac{1}{2}log{\frac{1-e_m}{e_m}}αm=21logem1em

这里的对数是自然对数。ama_mam表示Gm(x)G_m(x)Gm(x)在最终分类器中的重要性。由式αm=12log1−emem\alpha_m = \frac{1}{2}log{\frac{1-e_m}{e_m}}αm=21logem1em可知,当em&lt;=1/2e_m&lt;=1/2em<=1/2时,am&gt;=0a_m&gt;=0am>=0,并且ama_mam随着eme_mem的减小而增大,所以分类误差率越小的基本分类器在最终分类器中的作用越大。

(d)更新训练数据集的权值分布

Dm+1=(Wm+1,1,...,Wm+1,i,...,Wm+1,n)D_{m+1}=(W_{m+1,1},...,W_{m+1,i},...,W_{m+1,n})Dm+1=(Wm+1,1,...,Wm+1,i,...,Wm+1,n)

wm+1,i=wm,iZme−αmyiGm(xi)w_{m+1, i}=\frac{w_{m, i}}{Z_m}e^{-\alpha_my_iG_m(x_i)}wm+1,i=Zmwm,ieαmyiGm(xi)

y只有正负一两种取值,所以上式可以写作:

wm+1,i={wmiZme−am,Gm(xi)=yiwmiZmeam,Gm(xi)≠yiw_{m+1,i}=\begin{cases} \frac{w_{mi}}{Z_m}e^{-a_m},G_m(x_i)=y_i \\ \frac{w_{mi}}{Z_m}e^{a_m},G_m(x_i){\neq}y_i \end{cases}wm+1,i={Zmwmieam,Gm(xi)=yiZmwmieam,Gm(xi)̸=yi

这里,ZmZ_mZm是规范化因子

Zm=∑i=1Nwmiexp(−αmyiGm(xi))Z_m=\sum_{i=1}^Nw_{m i}exp({-\alpha_my_iG_m(x_i)})Zm=i=1Nwmiexp(αmyiGm(xi))

它使Dm+1D_{m+1}Dm+1成为一个概率分布。
由此可知,被基本分类器误分类样本的权值得以扩大,而被正确分类样本的权值却得以缩小。两相比较,误分类样本的权值被放大e2am=1−ememe^{2am} = {\frac{1-e_m}{e_m}}e2am=em1em倍。因此,误分类样本在下一轮学习中起更大的作用。不改变所给的训练数据,而不断改变训练数据权值的分布,使得训练数据在基本分类器的学习中起不同的作用,这是AdaBoost的一个特点。

(3)构建基本分类器的线性组合:

f(x)=∑m=1MamGm(x)f(x)=\sum_{m=1}^{M}a_mG_m(x)f(x)=m=1MamGm(x)

得到最终分类器:

G(x)=sign(f(x))=sign(∑m=1MamGm(x))G(x)=sign(f(x))=sign(\sum_{m=1}^{M}a_mG_m(x))G(x)=sign(f(x))=sign(m=1MamGm(x))
这里需要注意的是,我们得到的是M个f(x)方程,需要将每个方程的结果求和,最好只取结果的正负号,在Adaboost中我们的预测结果与数值是无关的。

3.完整代码

代码运行结果:
在这里插入图片描述

# -*- coding: utf-8 -*-
"""@Time    : 2018/12/04 13:58@Author  : hanzi5@Email   : hanzi5@yeah.net@File    : Adaboost.py@Software: PyCharm
"""
import numpy as np
#import pandas as pd
import matplotlib
import matplotlib.pyplot as pltmatplotlib.rcParams['font.family']='SimHei'  # 用来正常显示中文
plt.rcParams['axes.unicode_minus']=False     # 用来正常显示负号def splitDataSet(dataSet, i, value,types='lt'):"""
#划分数据集,只进行一次划分的树,将划分后的结果返回:param dataSet: 数据:param i: 特征的下标:param value: 阈值:param types: 大于或小于:return: 分类结果,注意返回的直接就是1,-1分类结果"""retArray = np.ones((np.shape(dataSet)[0],1))     # 默认类型都为1if types=='lt':   # 使用(小于等于value)划分数据,满足条件的将结果值改为-1retArray[dataSet[:,i]<=value]= -1.0  elif types=='gt': # 使用(大于value)划分数据,满足条件的将结果值改为-1retArray[dataSet[:,i]>value]= -1.0  return retArray def bulidSimpleTree(dataSet,y,D):"""
创建一个最简单的树,只进行一次划分,相当于一个树桩:param dataSet: 数据特征矩阵:param y: 标签向量:param D: 训练数据的权重向量:return: 最佳决策树,最小的错误率加权和,最优预测结果"""m,n=dataSet.shape                      # 样本行数及列数numFeatures = len(dataSet[0]) - 1      # 最后一列为y,计算x特征列数numSteps=10                            # 用于计算步长,进行numSteps等分minError=np.inf                        # 初始化损失值bestTree={}                            # 使用dict存储最优的一系列树for i in range(numFeatures):           # 遍历所有x特征列# i=0rangeMin = dataSet[:, i].min()     # 该xi维的最小值rangeMax = dataSet[:, i].max()     # 该xi维的最大值stepSize = (rangeMax - rangeMin) / numSteps # 步长for j in range(-1,int(numSteps) + 1):    # 循环寻找最优切分点# j=-1for inequal in ['lt', 'gt']:         # 遍历(lt小于等于)及(gt大于)# inequal=1value = (rangeMin + float(j) * stepSize) # 切分值predictedVals = splitDataSet(dataSet, i, value, inequal)  # 获取切分后的数据errArr = np.mat(np.ones((m, 1)))errArr[predictedVals == y] = 0  # 预测正确的样本对应的错误率为0,否则为1weightedError=D.T*errArr        # 《统计学习方法》李航P138,8.1,计算训练数据上的分类误差率if weightedError < minError:    # 记录最优树桩决策树分类器minError = weightedError    # 计算错误率加权和bestClasEst = predictedVals.copy() # 最好的预测结果bestTree['column'] = i             # 维度xbestTree['splitValue'] = value     # 切分值bestTree['ineq'] = inequal         # 切分方法(lt小于等于)及(gt大于)return bestTree, minError, bestClasEst# 基于单层决策树的adaboost分类器
def adaboost(dataSet,maxLoop=100):"""
基于单层决策树的ada训练:param dataSet: 样本x及y:param maxLoop: 迭代次数:return: 一系列弱分类器及其权重,样本分类结果"""adaboostTree=[]m,n=dataSet.shape                     # 样本行数及列数y=dataSet[:,-1].reshape((-1,1))       # 将y提取出来,方便进行计算D = np.array(np.ones((m,1))/m)        # 将每个样本的权重初始化为均等,有多少条数据就有多少个daggClassEst = np.mat(np.zeros((m,1))) # 每个数据点的类别估计累计值for i in range(maxLoop):              # maxLoop超参数,总迭代次数bestTree, minError, bestClasEst=bulidSimpleTree(dataSet,y,D)alpha=0.5*np.log((1-minError)/(minError+0.00001)) # 《统计学习方法》李航P139,8.2,计算Gm的系数,分母加一个小数避免除数为0bestTree['alpha'] = alpha.getA()[0][0]            # 将matrix中的值提取出来,并加入到bestTree中adaboostTree.append(bestTree)                     # 将树存入list中存储D=D*np.exp(-alpha.getA()[0][0]*y*bestClasEst)     # 更新权重D,《统计学习方法》李航P139,8.3-8.5,计算Gm(x)的系数D=D/D.sum()                                       # 归一化权重值,统计学习方法》李航P139,8.5,计算Zm# 计算所有分类器的误差,如果为0则终止训练aggClassEst += alpha.getA()[0][0]*bestClasEst     # 分类估计累计值,adaboost是线性运行的,需要将每次的树预测结果相加aggErrors = np.multiply(np.sign(aggClassEst) != np.mat(y),np.ones((m,1))) # aggClassEst每个元素的符号代表分类结果,如果与y不等则表示错误,统计学习方法》李航P138,8.8errorRate = aggErrors.sum()/m                     # 平均分类误差print( "total error: ",errorRate)if errorRate == 0.0:                              # 平均分类误差等于0的,说明数据已经全部分类正确,跳出循环breakreturn adaboostTree,aggClassEstdef adaClassify(data, adaboostTree):"""
对预测数据进行分类:param data: 预测样本x及y:param adaboostTree: 使用训练数据,训练好的决策树:return: 预测样本分类结果"""dataMatrix = np.mat(data)  m = np.shape(dataMatrix)[0]aggClassEst = np.mat(np.zeros((m, 1)))for i in range(len(adaboostTree)):                     # 遍历所有adaboostTree,将估计值累加classEst = splitDataSet(dataMatrix, adaboostTree[i]['column'], adaboostTree[i]['splitValue'], adaboostTree[i]['ineq'])  aggClassEst += adaboostTree[i]['alpha'] * classEst # 分类估计累计值,adaboost是线性运行的,需要将每次的树预测结果相加result = np.sign(aggClassEst)                          # 只取正负号,《统计学习方法》李航P139,8.8return resultdef plotData(dataSet):"""
数据画图"""type1_x1 = []type1_x2 = []type2_x1 = []type2_x2 = []# 取两类x1及x2值画图type1_x1 = dataSet[dataSet[:,-1] == -1][:,:-1][:,0].tolist()type1_x2 = dataSet[dataSet[:,-1] == -1][:,:-1][:,1].tolist()type2_x1 = dataSet[dataSet[:,-1] == 1][:,:-1][:,0].tolist()type2_x2 = dataSet[dataSet[:,-1] == 1][:,:-1][:,1].tolist()# 画点fig = plt.figure()ax = fig.add_subplot(111)ax.scatter(type1_x1,type1_x2, marker='s', s=90)ax.scatter(type2_x1,type2_x2, marker='o', s=50, c='red')plt.title('Adaboost训练数据')if __name__ == '__main__':print('\n1、Adaboost,开始')dataSet = np.array([[ 1. , 2.1, 1 ],[ 2. , 1.1, 1 ],[ 1.3, 1. , -1],[ 1. , 1. , -1],[ 2. , 1. , 1 ]])#classLabels = [1.0, 1.0, -1.0, -1.0, 1.0]# 画图print('\n2、Adaboost数据画图')plotData(dataSet)print('\n3、计算Adaboost树')adaboostTree,aggClassEst=adaboost(dataSet)# 对数据进行分类print('\n4、对[5,5],[0, 0]点,使用Adaboost进行分类:')print( adaClassify([[5,5],[0, 0]], adaboostTree))    

参考资料:
1、《机器学习实战》Peter Harrington著
2、《机器学习》西瓜书,周志华著
3、 斯坦福大学公开课 :机器学习课程
4、机器学习视频,邹博
5、《统计学习方法》李航
6、提升方法
7、分类——组合算法之提升1:AdaBoost提升算法以及Python实现

转载于:https://www.cnblogs.com/hanzi5/p/10105613.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/450441.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java List<T>去重方法,引用类型集合去重

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一、实体类中要重写比较方法equals&#xff0c;最好也重写hashcode方法 public class WorkWeightDto implements Serializable {privat…

MyBatis知识点

一、MyBatis简介 1.1 框架概念 框架&#xff0c;就是软件的半成品&#xff0c;完成了软件开发过程中的通用操作&#xff0c;程序员只需很少或者不用进行加工就能够实现特定的功能&#xff0c;从而简化开发人员在软件开发中的步骤&#xff0c;提高开发效率。 1.2 常用框架 MVC…

android studio : clang++.exe: error: invalid linker name in argument '-fuse-ld=bfd

公司jenkins上的C编译器最近换成了clang&#xff0c;今天更新了代码发现本地的C/C代码用NDK编译不过了&#xff0c;提示&#xff1a; “clang.exe: error: invalid linker name in argument -fuse-ldbfd” 解决办法&#xff1a; 将Android.mk文件中的“LOCAL_LDFLAGS -fuse-ld…

Git知识点

一、Git简介 1.1 项目的版本管理 在项目开发过程中&#xff0c;项目没开发到一个节点就会对当前项目进行备份&#xff0c;这个备份就是项目的一个版本&#xff1b;当我们继续开发一个阶段后&#xff0c;再次进行备份&#xff0c;就生成新的版本——多个版本的集合就是项目的版…

(1)初始化项目

2019独角兽企业重金招聘Python工程师标准>>> &#xff08;1&#xff09;初始化项目 1 使用vue-cli初始化项目 vue init webpack my-renren得到以下输出&#xff1a; ? Project name my-renren ? Project description A Vue.js project ? Author neumeng <4048…

C语言变量

C语言二进制、八进制、十六进制详解 什么是二制制? 在数学计算中&#xff0c;二进制计数系统的公分母是最小的&#xff0c;它以2为基数。你还记得在小学或中学时所学的不同的计数系统吗?笔者在上小学时&#xff0c;曾在一堂数学课中学过以6为基数的计数系统&#xff1b;你先…

Spring Data JPA - 参考文档 地址

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Spring Data JPA - 参考文档 文档地址

JS内置方法(Array)

concat() 用于连接两个或多个数组&#xff0c;该方法不会改变现有的数组&#xff0c;而是返回被连接数组的一个副本。join() 把数组中的所有元素放入一个字符串&#xff0c;元素是通过指定的分隔符进行分隔的。若省略了分隔符参数&#xff0c;则使用逗号作为分隔符。push() 向…

模切ERP和免费OA系统是互相结合提高效率

模切ERP和免费OA系统是互相结合提高效率在模切行业中&#xff0c;模切ERP在管理上的作用占了很大的比重&#xff0c;但是免费OA在管理上的地位都不容忽视的。点晴OA的核心问题是如何提高日常的办公效率问题。因此点晴OA系统里包含的功能是非常全面&#xff0c;如&#xff1a;办…

maven知识点

一、Maven简介 1.1 在项目中如何导入jar包&#xff1f; 下载jar包 &#xff08;mvn&#xff09;将下载的jar包拷贝到项目中&#xff08;WEB-INF/lib&#xff09;选择jar文件–右键–Add as Library 1.2 传统导入jar包的方式存在什么问题&#xff1f; 步骤多&#xff08;相对…

使用SpringBoot yml配置文件

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1.上一次我们已经使用SpringBoot实现了一个简单的HelloWord程序&#xff0c;辣么接下来我们简单的使用一下他的yml格式的配置文件。 2.在…

软件行业资讯

为什么只有设计师才能发明流行的新语言 先回顾一下知名编程语言的作者和创造时间&#xff1a;Fortran 语言&#xff0c;50年代&#xff0c;IBM 研究员&#xff1b;Lisp 语言&#xff0c;50年代&#xff0c;MIT 的教授和学生&#xff1b;C语言&#xff0c;70年代&#xff0c;贝尔…

spring知识点

一、Spring概述 1.1 web项目开发中的耦合度问题 在Servlet中需要调用service中的方法&#xff0c;则需要在Servlet类中通过new关键字创建Service的实例 public interface ProductService{public List<Product> listProducts(); }public class ProductServiceImpl1 imple…

Linux系统下的权限试题测试

不会做的留言&#xff0c;到时在发布答案&#xff01;一、 有两个参赛团队team1、team2&#xff0c;两个团队各3人, 这两个团队互相竞争&#xff0c;各需提交一份报告&#xff0c;每组成员可以修改自己团队内的所有文件&#xff0c;且不能让其他团队的人修改自己的文件内容&…

电子科大软件系统架构设计——软件建模详细设计

文章目录 软件建模详细设计概述软件建模详细设计目标软件建模详细设计原则开闭原则里氏 (Liskov) 替换原则依赖倒置原则接口分离原则单一职责原则最少知识原则&#xff08;迪米特法则&#xff09;高内聚原则松耦合原则可重用原则 软件建模详细设计内容 UML 软件静态结构视图建模…

YAML文件解析

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 YAML是“另一种标记语言”的外语缩写,YAML 是一种比JSON&#xff08;json多层次{ 与 [ 会被搞晕的&#xff09;更直观的表现形式&#xf…

120分钟React快速扫盲教程

在教程开端先说些题外话&#xff0c;我喜欢在学习一门新技术或读过一本书后&#xff0c;写一篇教程或总结&#xff0c;既能帮助消化&#xff0c;也能加深印象和发现自己未注意的细节&#xff0c;写的过程其实仍然是一个学习的过程。有个记录的话&#xff0c;在未来需要用到相关…

springmvc知识点

一、SpringMVC概述 Spring MVC 是由Spring官方提供的基于MVC设计理念的web框架。 SpringMVC是基于Servlet封装的用于实现MVC控制的框架&#xff0c;实现前端和服务端的交互。 1.1 SpringMVC优势 严格遵守了MVC分层思想 采用了松耦合、插件式结构&#xff1b;相比较于我们封装的…

spring @component的作用

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1、controller 控制器&#xff08;注入服务&#xff09; 2、service 服务&#xff08;注入dao&#xff09; 3、repository dao&#xff…

微信小程序 悬浮按钮

2019独角兽企业重金招聘Python工程师标准>>> 效果视频 https://pan.baidu.com/s/1yfrDaG9YAX0--v0EA3awZA 布局需要按照圆形排列&#xff0c;所以我们需要计算每个点的坐标 代码部分 <view styleposition:fixed; wx:for"{{list}}" wx:for-index"i…