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χi​∈X⊆Rn表示实例的特征向量,yi∈Y∈{+1,−1}y_i∈Y\in\{+1,-1\}yi​∈Y∈{+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χi​∈X⊆Rn,yi∈Y∈{+1,−1}y_i∈Y\in\{+1,-1\}yi​∈Y∈{+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​=∑iN​P(Gm​(xi​)̸​=yi​)=∑iN​wmi​I(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​=21​logem​1−em​​

这里的对数是自然对数。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​=21​logem​1−em​​可知,当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​=Zm​wm,i​​e−αm​yi​Gm​(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​={Zm​wmi​​e−am​,Gm​(xi​)=yi​Zm​wmi​​eam​,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=1N​wmi​exp(−αm​yi​Gm​(xi​))

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

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

f(x)=∑m=1MamGm(x)f(x)=\sum_{m=1}^{M}a_mG_m(x)f(x)=∑m=1M​am​Gm​(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=1M​am​Gm​(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

Python实现Adaboost相关推荐

  1. 利用python进行AdaBoost模型预测

    以信用卡违约数据为例,该数据集来源于UCI网站,一共包30 000条记录和25个变量,其中自变量包含客户的性别.受教育水平.年龄.婚姻状况.信用额度.6个月的历史还款状态.账单金额以及还款金额,因变量 ...

  2. python实现AdaBoost算法

    ★  AdaBoost的理解: 对于二分类而言,我们通过一个阈值threshVal将数据集划分为两种分类(正类和负类),而这个阈值就是我们所说的分割线,只不过它总是平行于坐标轴(因为我们取的基分类器是 ...

  3. AdaBoost + iris数据集实现+python

    AdaBoost 关于AdaBoost有很多文章,不多说了: https://www.cnblogs.com/ScorpioLu/p/8295990.html 简单来说就是对数据集取不同的分类做成弱分 ...

  4. 【机器学习实战】第7章 集成方法(随机森林和 AdaBoost)

    第7章 集成方法 ensemble method 集成方法: ensemble method(元算法: meta algorithm) 概述 概念:是对其他算法进行组合的一种形式. 通俗来说: 当做重 ...

  5. 数据挖掘十大经典算法之——AdaBoost 算法

    数据挖掘十大经典算法系列,点击链接直接跳转: 数据挖掘简介及十大经典算法(大纲索引) 1. 数据挖掘十大经典算法之--C4.5 算法 2. 数据挖掘十大经典算法之--K-Means 算法 3. 数据挖 ...

  6. 《零起点,python大数据与量化交易》

    <零起点,python大数据与量化交易>,这应该是国内第一部,关于python量化交易的书籍. 有出版社约稿,写本量化交易与大数据的书籍,因为好几年没写书了,再加上近期"前海智库 ...

  7. 集成方法-随机森林和AdaBoost

    本文转载自:https://github.com/apachecn/MachineLearning 集成方法: ensemble method(元算法: meta algorithm) 概述 概念:是 ...

  8. python算法完整教程专栏完整目录

    python算法完整教程专栏完整目录 专栏说明如下 专栏目录 专栏说明如下 内容:python算法完整教程 数量:692篇博文(2023年2月15日截止) 更新时间至:2023年2月15日(后续加上去 ...

  9. 【机器学习实战】第7章 集成方法 随机森林(RandomForest)和 Adaboost

    第7章 集成方法 ensemble method 集成方法: ensemble method(元算法: meta algorithm) 概述 概念:是对其他算法进行组合的一种形式. 通俗来说: 当做重 ...

最新文章

  1. win32ctypes.pywin32.pywintypes.error: (2, ‘LoadLibraryEx‘, ‘系统找不到指定的文件。‘)
  2. Binary Search O(log n) algorithm to find duplicate in sequential list?
  3. easyui filebox 文件上传
  4. Xilinx IP解析之Processor System Reset v5.0
  5. 蓝桥备赛第一周2021.1.11 递归 枚举 位运算
  6. 为ie和chrome FF单独设置样式的“条件注释法”、“类内属性前缀法”、“选择器前缀法”、实现方法 案例(推荐)
  7. 主题模型TopicModel:LDA中的数学模型
  8. 河南工业大学2017校赛题解
  9. java jdbc 链接pg_使用PostgreSQL JDBC连接池
  10. [python] ylgy攻略 用魔法打败魔法
  11. python爬虫小案例
  12. 【python】一键修改小米运动步数,同步微信、支付宝 运动步数
  13. java 图片导出word_【freemaker实现导出word②】代码实现导出word(包括导出list数据和导出图片到word)...
  14. linux添加菜单栏,Gnome desktop主菜单中添加自己的菜单栏
  15. 如何把MP4转为GIF格式
  16. C++学习笔记(九)——运算符重载
  17. 【洛谷P5514】永夜的报应【模拟】
  18. js如何保留对象中指定字段(太刁了)
  19. 红队武器库-网络安全人员必备
  20. Windows下Armadillo配置及测试

热门文章

  1. CCIE理论-第一篇-SDN概念复习
  2. 【BZOJ - 1305】dance跳舞(拆点网络流,建图,最大流,残留网络上跑最大流)
  3. 【牛客 - 373B】666RPG(线性计数dp)
  4. 【CodeForces - 608D】Zuma(区间dp)
  5. NYOJ-14 会场安排问题(经典贪心,区间完全不覆盖模板)
  6. 1.Hello,Python
  7. mysql权重怎么配置_mysql如何按权重查询数据啊?
  8. android 获取默认程序图标,android – PackageManager.getApplicationIcon()返回默认图标?...
  9. 通过反射创建私有化构造的类,并为私有化属性复制。调用私有化方法
  10. rust 案例_RUST-X气相防锈产品落户中国,助力中国高端制造出口海外