机器学习实战系列(六):Adaboost提升法
我的机器学习教程「美团」算法工程师带你入门机器学习 以及 「三分钟系列」数据结构与算法 已经开始更新了,欢迎大家订阅~这篇专栏整合了这几年的算法知识,简单易懂,也将是我实体书的BLOG版。
欢迎大家扫码关注微信公众号「图灵的猫」,除了有更多AI、算法、Python相关文章分享,还有免费的SSR节点和外网学习资料。其他平台(微信/知乎/B站)也是同名「图灵的猫」,不要迷路哦~
课程的所有数据和代码在我的Github:Machine learning in Action,目前刚开始做,有不对的欢迎指正,也欢迎大家star。除了 版本差异,代码里的部分函数以及代码范式也和原书不一样(因为作者的代码实在让人看的别扭,我改过后看起来舒服多了)。在这个系列之后,我还会写一个scikit-learn机器学习系列,因为在实现了源码之后,带大家看看SKT框架如何使用也是非常重要的。
Adaboost提升算法是机器学习中很好用的两个算法之一,另一个是SVM支持向量机;机器学习面试中也会经常提问到Adaboost的一些原理;另外本文还介绍了一下非平衡分类问题的解决方案,这个问题在面试中也经常被提到,比如信用卡数据集中,失信的是少数,5:10000的情况下怎么准确分类?
元算法(集成算法):
多个弱分类器的组合;弱分类器的准确率很低 50%接近随机了
这种组合可以是 不同算法 或 同一算法不同配置 或是 数据集的不同部分分配给不同分类器;
bagging:
把原始数据集随机抽样成S个与原始数据集一样大新数据集(允许有重复值),然后训练S个分类器,最后投票结果集成;
代表:随机森林
boosting:
关注以后分类器错分的数据,而得到新的分类器;
代表:adaboost
bagging和boosting类似,都是抽样的方式构造多个数据集(特别适用于数据集有限的时候),并且多个组合分类器的类型都相同,但bagging是串行的,下一个分类器在上一个分类器的基础上继续训练得到的,权重均等;而boosting关注的是错分的数据,错分的数据权重大;
adaboost(adaptive boost)自适应提升算法
AdaBoost的一般流程如下所示:
(1)收集数据
(2)准备数据:依赖于所用的基分类器的类型,这里的是单层决策树,即树桩,该类型决策树可以处理任何类型的数据。
(3)分析数据
(4)训练算法:利用提供的数据集训练分类器
(5)测试算法:利用提供的测试数据集计算分类的错误率
(6)使用算法:算法的相关推广,满足实际的需要
原理:为每一个样本赋均等的权重(D = 1/n),先用这个数据集训练第一个弱分类器,计算错误率,错误率是为了计算这个分类器最后投票的权重alpha,错分的样本权重提升,对分的样本权重降低。然后用这个数据集训练第二个若分类器,迭代到弱分类器错误率为0或迭代指定个数的弱分类器停止
构建决策树
import copy
from numpy import *
from math import inf
import numpy as np
"""
#构建单层分类器
#单层分类器是基于最小加权分类错误率的树桩
#伪代码
#将最小错误率minError设为+∞
#对数据集中的每个特征(第一层特征):#对每个步长(第二层特征):#对每个不等号(第三层特征):#建立一颗单层决策树并利用加权数据集对它进行测试#如果错误率低于minError,则将当前单层决策树设为最佳单层决策树
#返回最佳单层决策树
"""
def stumpClassify(dataMatrix,dimen,threshVal,threshIneq):#just classify the dataretArray = ones((shape(dataMatrix)[0],1))if threshIneq == 'lt':retArray[dataMatrix[:,dimen] <= threshVal] = -1.0else:retArray[dataMatrix[:,dimen] > threshVal] = -1.0return retArraydef buildStump(dataArr,classLabels,D):dataMatrix = mat(dataArr); labelMat = mat(classLabels).Tm,n = shape(dataMatrix)numSteps = 10.0; bestStump = {}; bestClasEst = mat(zeros((m,1)))minError = inf #init error sum, to +infinityfor i in range(n):#loop over all dimensionsrangeMin = dataMatrix[:,i].min(); rangeMax = dataMatrix[:,i].max();stepSize = (rangeMax-rangeMin)/numStepsfor j in range(-1,int(numSteps)+1):#loop over all range in current dimensionfor inequal in ['lt', 'gt']: #go over less than and greater thanthreshVal = (rangeMin + float(j) * stepSize)predictedVals = stumpClassify(dataMatrix,i,threshVal,inequal)#call stump classify with i, j, lessThanerrArr = mat(ones((m,1)))errArr[predictedVals == labelMat] = 0weightedError = D.T*errArr #calc total error multiplied by D#print "split: dim %d, thresh %.2f, thresh ineqal: %s, the weighted error is %.3f" % (i, threshVal, inequal, weightedError)if weightedError < minError:minError = weightedErrorbestClasEst = predictedVals.copy()bestStump['dim'] = ibestStump['thresh'] = threshValbestStump['ineq'] = inequalreturn bestStump,minError,bestClasEst
训练ADABOOST
from numpy import *
from Stump_classify import *
#adaBoost算法
#@dataArr:数据矩阵
#@classLabels:标签向量
#@numIt:迭代次数
def adaBoostTrainDS(dataArr,classLabels,numIt=40):'''@adaBoost算法@dataArr:数据矩阵@classLabels:标签向量@numIt:迭代次数 '''#弱分类器相关信息列表weakClassArr=[]#获取数据集行数m=shape(dataArr)[0]#初始化权重向量的每一项值相等D=mat(ones((m,1))/m)#累计估计值向量aggClassEst=mat((m,1))#循环迭代次数for i in range(numIt):#根据当前数据集,标签及权重建立最佳单层决策树bestStump,error,classEst=buildStump(dataArr,classLabels,D)#打印权重向量print("D:",D.T)#求单层决策树的系数alphaalpha=float(0.5*log((1.0-error)/(max(error,1e-16))))#存储决策树的系数alpha到字典bestStump['alpha']=alpha#将该决策树存入列表weakClassArr.append(bestStump)#打印决策树的预测结果print("classEst:",classEst.T)#预测正确为exp(-alpha),预测错误为exp(alpha)#即增大分类错误样本的权重,减少分类正确的数据点权重expon=multiply(-1*alpha*mat(classLabels).T,classEst)#更新权值向量D=multiply(D,exp(expon))D=D/D.sum()#累加当前单层决策树的加权预测值aggClassEst = aggClassEst + alpha * classEst#aggClassEst = array(aggClassEst)print("aggClassEst",aggClassEst.T)#求出分类错的样本个数aggErrors=multiply(sign(aggClassEst)!=\mat(classLabels).T,ones((m,1)))#计算错误率errorRate=aggErrors.sum()/mprint("total error:",errorRate,"\n")#错误率为0.0退出循环if errorRate==0.0:break#返回弱分类器的组合列表return weakClassArr
利用ADA分类
#测试adaBoost,adaBoost分类函数
#@datToClass:测试数据点
#@classifierArr:构建好的最终分类器
def adaClassify(datToClass,classifierArr):#构建数据向量或矩阵dataMatrix=mat(datToClass)#获取矩阵行数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']*classEstprint('aggClassEst',aggClassEst)#通过sign函数根据结果大于或小于0预测出+1或-1return sign(aggClassEst)def loadDataSet(filename):#创建数据集矩阵,标签向量dataMat=[];labelMat=[]#获取特征数目(包括最后一类标签)#readline():读取文件的一行#readlines:读取整个文件所有行numFeat=len(open(filename).readline().split('\t'))#打开文件fr=open(filename)#遍历文本每一行for line in fr.readlines():lineArr=[]curLine=line.strip().split('\t')for i in range(numFeat-1):lineArr.append(float(curLine[i]))#数据矩阵dataMat.append(lineArr)#标签向量labelMat.append(float(curLine[-1]))return dataMat,labelMat#训练和测试分类器
def classify():#利用训练集训练分类器datArr,labelArr=loadDataSet('horseColicTraining.txt')#得到训练好的分类器classifierArray=adaBoostTrainDS(datArr,labelArr,10)#利用测试集测试分类器的分类效果testArr,testLabelArr=loadDataSet('horseColicTest.txt')prediction=adaClassify(testArr,classifierArray)#输出错误率num=shape(mat(labelArr))[1]errArr=mat(ones((num,1)))error=errArr[prediction!=mat(testLabelArr).T].sum()print("the errorRate is: %.2f",errorRate=float(error)/float((num)))
ROC曲线绘制
def plotROC(predStrengths, classLabels):import matplotlib.pyplot as pltcur = (1.0,1.0) #cursorySum = 0.0 #variable to calculate AUCnumPosClas = sum(array(classLabels)==1.0)yStep = 1/float(numPosClas); xStep = 1/float(len(classLabels)-numPosClas)sortedIndicies = predStrengths.argsort()#get sorted index, it's reversefig = plt.figure()fig.clf()ax = plt.subplot(111)#loop through all the values, drawing a line segment at each pointfor index in sortedIndicies.tolist()[0]:if classLabels[index] == 1.0:delX = 0; delY = yStep;else:delX = xStep; delY = 0;ySum += cur[1]#draw line from cur to (cur[0]-delX,cur[1]-delY)ax.plot([cur[0],cur[0]-delX],[cur[1],cur[1]-delY], c='b')cur = (cur[0]-delX,cur[1]-delY)ax.plot([0,1],[0,1],'b--')plt.xlabel('False positive rate'); plt.ylabel('True positive rate')plt.title('ROC curve for AdaBoost horse colic detection system')ax.axis([0,1,0,1])plt.show()print ("the Area Under the Curve is: ",ySum*xStep)
测试函数
def loadSimpData():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,classLabelsif __name__ == '__main__':data, label = loadSimpData()datArr,labelArr = loadDataSet('horseColicTraining.txt')classifierArr = adaBoostTrainDS(datArr,labelArr,9)testArr,testLabelArr = loadDataSet('horseColicTest.txt')prediciton = adaClassify(testArr,classifierArr)error = mat(ones((67,1)))error[prediciton != mat(testLabelArr ).T] .sum()
分类器数目 | 训练错误率(%) | 测试错误率(%) |
1 | 0.28 | 0.27 |
10 | 0.23 | 0.24 |
50 | 0.19 | 0.21 |
100 | 0.19 | 0.22 |
500 | 0.16 | 0.25 |
1000 | 0.14 | 0.31 |
10000 | 0.11 | 0.33 |
机器学习实战系列(六):Adaboost提升法相关推荐
- xen虚拟化实战系列(六)之xen虚拟机破解密码
xen虚拟化实战系列文章列表 xen虚拟化实战系列(一)之xen虚拟化环境安装 xen虚拟化实战系列(二)之xen虚拟机安装 xen虚拟化实战系列(三)之xen虚拟机复制 xen虚拟化实战系列(四)之 ...
- python3《机器学习实战系列》学习笔记----3.2 决策树实战
前言 一.ID3算法构造决策树 1.1 背景 1.2 信息增益计算 1.3 递归生成决策树 二.使用Matplotlib注解绘制树形图 2.1 Matplotlib注解 2.2 构造注解树 三.测试和 ...
- 【Youtobe trydjango】Django2.2教程和React实战系列六【自定义主页、路由与请求】
[Youtobe trydjango]Django2.2教程和React实战系列六[自定义主页.路由与请求] 1. 初始化主页应用 2. 修改视图 3. 项目url增加主页路由 4. 路由 1. 初始 ...
- 机器学习实战(六)AdaBoost元算法
目录 0. 前言 1. AdaBoost 2. 单层决策树 3. 非均衡数据 4. 实战案例 4.1. 马病死亡案例 学习完机器学习实战的AdaBoost元算法,简单的做个笔记.文中部分描述属于个人消 ...
- 机器学习实战(六)——支持向量机
第六章 支持向量机 6.1 什么是支持向量机 6.1.1 线性SVM 6.1.2 函数间隔和几何间隔 6.1.3 最大间隔分离超平面 6.1.4 支持向量和间隔边界 6.1.4 学习的对偶算法 6.2 ...
- B.机器学习实战系列[一]:工业蒸汽量预测(最新版本下篇)重点讲解模型验证、特征优化、模型融合等
[机器学习入门与实践]入门必看系列,含数据挖掘项目实战:数据融合.特征优化.特征降维.探索性分析等,实战带你掌握机器学习数据挖掘 专栏详细介绍:[机器学习入门与实践]合集入门必看系列,含数据挖掘项目实 ...
- 机器学习实战(六)01-模型评价标准
前言 本文内容大部分来自于如下两个博客: http://blog.csdn.net/dinosoft/article/details/43114935 http://my.oschina.net/ ...
- 【CA-TA实战系列六】CA与TA背后的故事一:TEE OS
一.前言 TEE OS就是可信环境的操作系统,这里我们的参考资料是前辈的<手机安全和可信应用开发指南>,因此这里我们的TEE OS就是OP TEE. 那么为什么在搞TA CA的设计实现要关 ...
- 活动目录实战系列六(win98客户端加入域)
局域网中有一台客户机为98,现在不太可能了,在这边就是告诉大家怎么把WIN98加入域. 首先我们建立一个用户win98 我们现在设置WIN98客户端. 我们这里域为51ctolab.com,域控IP地 ...
- 云计算实战系列六(Linux进程管理)
一 .进程管理 关于进程 process ======================================================= 什么是进程 ? 进程的生命周期 Process ...
最新文章
- 十三、序列化和反序列化(部分转载)
- Jsprime——一款JavaScript静态安全分析工具
- shell中遍历目录
- AngularJS学习笔记一:简单入门
- matlab计算斜方差_Matlab求方差,均值,均方差,协方差的函数
- python pip 升级
- OpenCV circle图像上画圆
- 工作经验--他人经验
- excel去重_Python 轻松搞定 Excel 常用的 20 个操作
- 十大震撼谷歌地图卫星照
- 新手小白之学习python一飞冲天日志之—基本数据类型,条件控制语句
- 更改Linux终端用户名显示颜色的PS1的用法
- 真正的程序员到底应该是什么样子的?
- ffmpeg详细安装教程
- 技术驱动创新,带来的创业机遇
- php 短网址 算法,php生成短网址的思路以及实现方法
- 解决Flutter键盘弹起导致与输入框有间距问题(Flutter键盘弹起Scaffold布局流程)解析
- txt文件-英汉字典
- Sqoop实践——原始数据库到大数据时代必备神器
- 谈谈PHP中的trait