机器学习——AdaBoost元算法
当做重要决定时,我们可能会考虑吸取多个专家而不只是一个人的意见。机器学习处理问题也是这样,这就是元算法(meta-algorithm)背后的思路。
元算法是对其他算法进行组合的一种方式,其中最流行的一种算法就是AdaBoost算法。某些人认为AdaBoost是最好的监督学习的方法,所以该方法是机器学习工具箱中最强有力的工具之一。
集成学习或者元算法的一般结构是:先产生一组“个体学习器”,再用某种策略将他们结合起来。个体学习器通常是由一个现有的学习算法从训练数据产生。
根据个体学习器的生成方式,目前的集成学习方法大致可分为两大类,即
1.个体学习器间存在强依赖关系、必须串行生成的序列化方法,典型的代表是Boosting,其中AdaBoost就是Boosting的最流行的一个版本
2.个体学习器间不存在强依赖关系、可同时生成的并行化方法,典型的代表是Bagging和“随机森林”(Random Forest)
AdaBoost
优点:泛化错误率低,易编码,可以应用在大部分分类器上,无参数调整
缺点:对离群点敏感
使用数据类型:数值型和标称型数据
bagging:基于数据随机重抽样的分类器构建方法
自举汇聚法(bootstrap aggregating),也称为bagging方法,它直接基于自助采样法(bootstrap samping)。
给定包含m个样本的数据集,我们先随机取出一个样本放入采样集中,再把该样本放回初始数据集,使得下次采样时该样本仍有可能被选中,这样,经过m次随机采样操作,我们得到了含m个样本的采样集。这样从原始数据集选择T次后得到T个新数据集,且每个新数据集的大小和原数据集的大小相等。在T个新数据集建好之后,将某个学习算法分别作用于每个数据集就得到了T个分类器。当我们要对新数据集进行分类时,就可以应用这T个分类器进行分类。与此同时,选择分类器投票结果中最多的类别作为最后的分类结果(权重相等)。
Boosting
boosting是一种和bagging很类似的技术。其使用的多个分类器的类型都是一致的。
在boosting中,不同的分类器是通过串行训练而获得的,每个新分类器都根据已训练出的分类器的性能来进行训练。boosting是通过集中关注被已有分类器错分的那些数据来获得新的分类器。
boosting分类的结果是基于所有分类器的加权求和结果的,在bagging中的分类器权重是相等的,而boosting中的分类器权重并不相等,每个权重代表的是其对应分类器在上一轮迭代中的成功度。
现在介绍其中的AdaBoost
弱分类器的“弱”意味着分类器的性能比随机猜测要略好,但是也不会好太多。这就是说,在二分类情况下,弱分类器的错误率会高于50%,而强分类器的错误率会低很多。
AdaBoost是adaptive boosting(自适应boosting)的缩写,其运行过程如下:
假设一个二类分类的训练数据集
<1>训练数据中的每个样本,并赋予其一个权重,这些权重构成了初始向量D。一开始,这些权重都初始化成相等值。
AdaBoost算法多种推导方式,比较容易理解的是基于“加性模型”,即基学习器的线性组合
,其中 为基学习器, 为系数
来最小化指数损失函数(exponential loss function),损失函数见 机器学习-损失函数 (转)
,其中f(x)是正确的分类,等于-1或者1,H(x)是分类器的分类结果,等于-1或者1
,所以对该式子求的偏导,得 ,并令其等于0,得
<2>首先在训练分类器上训练出一个弱分类器并计算该分类的错误率,然后在同一数据集上再次训练弱分类器。
在分类器的第二次训练中,将会重新调整每个样本的权重,其中第一次分对的样本的权重将会降低,而第一次分错的样本的权重将会提高。为了从所有弱分类器中得到最终的分类结果,AdaBoost为每个分类器都分配了一个权重值alpha,这些alpha值是基于每个弱分类器的错误率进行计算的。
其中,错误率 的定义为
= 为正确分类的样本数目/所有样本数目
而alpha的计算公式如下:
计算出alpha值之后,可以对权重向量D进行更新,以使得那些正确分类的样本的权重降低而错分样本的权重升高。D的计算方法如下:
其中,,是规范化因子
它使得成为一个概率分布
如果某个样本被正确分类,那么该样本的权重更改为
如果某个样本被错误分类,那么该样本的权重更改为
在计算出D之后,AdaBoost算法又开始进入下一轮迭代。
AdaBoost算法会不断地重复训练和调整权重的过程,直到训练错误率为0或者弱分类器的数目达到用户的指定值为止。
from numpy import * def loadSimpData():
datMat = 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 datMat,classLabels
def plotBestFit(weakClassArr): #画出数据集和所有的基学习器
#import matplotlib.pyplot as plt
dataMat,labelMat=loadSimpData() #数据矩阵和标签向量
dataArr = array(dataMat) #转换成数组
n = shape(dataArr)[0]
xcord1 = []; ycord1 = [] #声明两个不同颜色的点的坐标
xcord2 = []; ycord2 = []
for i in range(n):
if int(labelMat[i])== 1:
xcord1.append(dataArr[i,0]); ycord1.append(dataArr[i,1])
else:
xcord2.append(dataArr[i,0]); ycord2.append(dataArr[i,1])
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
ax.scatter(xcord2, ycord2, s=30, c='green')
print "weakClassArr[0]['thresh']",weakClassArr[0]['dim']
for j in range(len(weakClassArr)):
if(weakClassArr[j]['dim'] == 1):
x = arange(-0.0, 2.5, 0.1)
y = x*0+weakClassArr[j]['thresh']
ax.plot(x, y)
else:
y = array(arange(-0.0, 2.5, 0.1))
x = y*0+weakClassArr[j]['thresh']
ax.plot(x, y)
plt.xlabel('X1'); plt.ylabel('X2');
plt.show() def stumpClassify(dataMatrix,dimen,threshVal,threshIneq): #通过阈值比较对数据进行分类
retArray = ones((shape(dataMatrix)[0],1)) #首先将返回的数组的全部元素设置为1
if threshIneq == 'lt':
retArray[dataMatrix[:,dimen] <= threshVal] = -1.0 #将满足<=不等式的元素设为-1
else:
retArray[dataMatrix[:,dimen] > threshVal] = -1.0 #将满足>不等式的元素设为-1
return retArray def buildStump(dataArr,classLabels,D): #遍历stumpClassify()函数所有的可能输入值,并找到数据集上最佳的单层决策树
dataMatrix = mat(dataArr); labelMat = mat(classLabels).T
m,n = shape(dataMatrix) #m=5,n=2
numSteps = 10.0; bestStump = {}; bestClasEst = mat(zeros((m,1)))
minError = inf #初始误差总和,为无穷大
for i in range(n): #循环X和Y两个维度
rangeMin = dataMatrix[:,i].min(); rangeMax = dataMatrix[:,i].max(); #取得X和Y两个维度的最大值和最小值特征
stepSize = (rangeMax-rangeMin)/numSteps #步进长度
for j in range(-1,int(numSteps)+1): #从-1到10步进
for inequal in ['lt', 'gt']: #"lt"为满足<=不等式,"gt"为满足>不等式
threshVal = (rangeMin + float(j) * stepSize) #当前阈值
predictedVals = stumpClassify(dataMatrix,i,threshVal,inequal) #根据阈值和不等式,计算预测的分类
errArr = mat(ones((m,1)))
errArr[predictedVals == labelMat] = 0 #样本估计错误的标记为1
weightedError = D.T*errArr #通过权重和错误标记,计算泛化误差
#print "split: dim %d, thresh %.2f, thresh ineqal: %s, the weighted error is %.3f" % (i, threshVal, inequal, weightedError)
if weightedError < minError: #如果泛化误差是最小的
minError = weightedError
bestClasEst = predictedVals.copy() #保存最佳预测结果
bestStump['dim'] = i #保存维度、阈值、不等式符号
bestStump['thresh'] = threshVal
bestStump['ineq'] = inequal
return bestStump,minError,bestClasEst def adaBoostTrainDS(dataArr,classLabels,numIt=40): #基于单层决策树的AdaBoost训练
weakClassArr = []
m = shape(dataArr)[0] #需要分类的数据量,m=5
D = mat(ones((m,1))/m) #D为权重向量,初始D1...D5的和等于1
aggClassEst = mat(zeros((m,1))) #基分类器的线性组合
for i in range(numIt):
#建立单层决策树,bestStump包括维度,不等式,阈值,error泛化误差,classEst是每个基分类器
bestStump,error,classEst = buildStump(dataArr,classLabels,D)
print "最佳决策树=",bestStump,"泛化误差=",error,"更新前的分类器预测结果=",classEst.T
#print "D:",D.T
alpha = float(0.5*log((1.0-error)/max(error,1e-16))) #根据泛化误差,计算基分类器的权重α值
bestStump['alpha'] = alpha #把权重α值添加到最佳决策树的列表中
print "最佳决策树=",bestStump
weakClassArr.append(bestStump) #保存单层最佳决策树参数到数组中
print "预测分类: ",classEst.T
expon = multiply(-1*alpha*mat(classLabels).T,classEst) #权重α×真实分类×预测分类,multiply为对应元素相乘,不是矩阵相乘
D = multiply(D,exp(expon)) #Calc New D for next iteration
D = D/D.sum() #更新D,D.sum()为规范化因子
#calc training error of all classifiers, if this is 0 quit for loop early (use break)
aggClassEst += alpha*classEst
print "更新后的分类器预测结果: ",aggClassEst.T
aggErrors = multiply(sign(aggClassEst) != mat(classLabels).T,ones((m,1))) #boolean值和1相乘
errorRate = aggErrors.sum()/m #计算错误率
print "total error: ",errorRate
if errorRate == 0.0: break
return weakClassArr,aggClassEst def adaClassify(datToClass,classifierArr): #AdaBoost分类函数
dataMatrix = mat(datToClass) #输入[0,0]转换成[[0,0]]矩阵
m = shape(dataMatrix)[0]
aggClassEst = mat(zeros((m,1)))
for i in range(len(classifierArr)):
classEst = stumpClassify(dataMatrix,classifierArr[i]['dim'],\
classifierArr[i]['thresh'],\
classifierArr[i]['ineq']) #维度、阈值、不等式符号
aggClassEst += classifierArr[i]['alpha']*classEst #计算在每一个基分类器上的预测值的累加和
print "aggClassEst=",aggClassEst
return sign(aggClassEst)
main.py
# coding:utf-8
# !/usr/bin/env python import adaboost if __name__ == '__main__':
datMat,classLabels = adaboost.loadSimpData()
weakClassArr,aggClassEst = adaboost.adaBoostTrainDS(datMat,classLabels)
print "弱分类器组合:",weakClassArr
print adaboost.adaClassify([[0,0],[5,5]],weakClassArr)
adaboost.plotBestFit(weakClassArr)
1个分类器———— 2个分类器———— 3个分类器————
机器学习——AdaBoost元算法的更多相关文章
- 机器学习实战 - 读书笔记(07) - 利用AdaBoost元算法提高分类性能
前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习笔记,这次是第7章 - 利用AdaBoost元算法提高分类性能. 核心思想 在使用某个特定的算法是, ...
- 【转载】 机器学习实战 - 读书笔记(07) - 利用AdaBoost元算法提高分类性能
原文地址: https://www.cnblogs.com/steven-yang/p/5686473.html ------------------------------------------- ...
- 机器学习技法-AdaBoost元算法
课程地址:https://class.coursera.org/ntumltwo-002/lecture 重要!重要!重要~ 一.Adaptive Boosting 的动机 通过组合多个弱分类器(hy ...
- 在Titanic数据集上应用AdaBoost元算法
一.AdaBoost 元算法的基本原理 AdaBoost是adaptive boosting的缩写,就是自适应boosting.元算法是对于其他算法进行组合的一种方式. 而boosting是在从原始数 ...
- 使用 AdaBoost 元算法提高分类器性能
前言 有人认为 AdaBoost 是最好的监督学习的方式. 某种程度上因为它是元算法,也就是说它会是几种分类器的组合.这就好比对于一个问题能够咨询多个 "专家" 的意见了. 组合的 ...
- 第九篇:使用 AdaBoost 元算法提高分类器性能
前言 有人认为 AdaBoost 是最好的监督学习的方式. 某种程度上因为它是元算法,也就是说它会是几种分类器的组合.这就好比对于一个问题能够咨询多个 "专家" 的意见了. 组合的 ...
- 机器学习算法( 七、AdaBoost元算法)
一.概述 当做重要决定时,大家可能都会考虑吸取多个专家而不只是一个人的意见.机器学习处理问题时又何尝不是如此?这就是元算法(meta-algorithm)背后的思路.元算法是对其他算法进行组合的一种方 ...
- 利用AdaBoost元算法提高分类性能
当做重要决定时,大家可能都会吸取多个专家而不只是一个人的意见.机器学习处理问题时又何尝不是如此?这就是元算法背后的思路.元算法是对其他算法进行组合的一种方式. 自举汇聚法(bootstrap aggr ...
- 监督学习——AdaBoost元算法提高分类性能
基于数据的多重抽样的分类器 可以将不通的分类器组合起来,这种组合结果被称为集成方法(ensemble method)或者元算法(meta-algorithom) bagging : 基于数据随机抽样的 ...
随机推荐
- 最新Android系统版本与API等级对应关系表
最新Android系统版本与API等级对应关系表 从Android官网拷过来的,方便查阅... 官网地址:https://developer.android.com/guide/topics/mani ...
- C#初步应用
首先,此次编程是第一次尝试结对编程,我的结对对象博客园地址:http://www.cnblogs.com/cbb111/ 他的源代码链接:https://coding.net/u/cao1417146 ...
- 关于在安装MySQL时报错"本地计算机上的mysql服务启动后停止,某些服务在未由其他服务或程序使用时将自动停止"的解决方法
首先将你下载的MySQL安装或者解压(对应安装版和解压版),下载地址http://dev.mysql.com/downloads/mysql/ 然后复制你安装目录中的my-default.ini,更改 ...
- apachetop 实时监测web服务器运行状况
apachetop 实时监测web服务器运行状况 我们经常会需要知道服务器的实时监测服务器的运行状况,比如哪些 URL 的访问量最大,服务器每秒的请求数,哪个搜索引擎正在抓取我们网站?面对这些问题 ...
- 《Ansible权威指南》笔记(4)——Playbook
七.Playbook1.语法特性如下:(1)"---"首行顶格开始(2)#号注释(3)缩进统一,不同的缩进代表不同的级别,缩进要对齐,空格和tab不能混用(4)区别大小写,键值对k ...
- [iOS]技巧集锦:UICollectionView在旋转屏幕后Cell中的约束不起作用或自动布局失效
这似乎是iOS的一个BUG(ref: stackoverflow的大神们讲的) 解决方案 在继承自UITableViewCell的子类中的init方法中加入如下设置: self.contentView ...
- Windows操作系统下远程连接MySQL数据库
用Eclipse做一个后台项目,但是数据库不想放在本地电脑,于是买了一个腾讯云服务器(学生有优惠,挺便宜的),装上MySQL数据库,但是测试连接的时候,发现总是连接不是上,但是本地数据库可以连接,于是 ...
- js小技巧
js判断字符长度 直接使用String对象的属性,空格亦算一个字符 myString = "Hello world"; length = myString.length js比较字 ...
- 新手!mass 设置问题
mass就是你那个物体的质量啊质量越大,惯性也越大重力也越大.假如你的刚体的mass为1,那么你只要给这个物体9.81N向上的力,你就可以抵消重力,让这个物体悬浮着:但假如这个物体的mass为10,你 ...
- 使用串口线真机调试Linux内核
一.环境 ubuntu 14.04 一台有串口的PC(编号PC1,被调试机器) 另一台PC通过USB转串口线连接PC1(编号PC2,发起调试命令的机器) 二.串口线配置及测试 安装cutecom US ...