问题: 马疝气病判断
训练数据: 299行, 22列, 其中最后一列为标签, 例:
2.000000 1.00000038.500000 66.00000028.000000 3.0000003.000000 0.0000002.000000 5.0000004.000000 4.0000000.000000 0.0000000.000000 3.0000005.000000 45.0000008.400000 0.0000000.000000 -1.000000
1.000000 1.00000039.200000 88.00000020.000000 0.0000000.000000 4.0000001.000000 3.0000004.000000 2.0000000.000000 0.0000000.000000 4.0000002.000000 50.00000085.000000 2.0000002.000000 -1.000000
2.000000 1.00000038.300000 40.00000024.000000 1.0000001.000000 3.0000001.000000 3.0000003.000000 1.0000000.000000 0.0000000.000000 1.0000001.000000 33.0000006.700000 0.0000000.000000 1.000000

先上代码:

#!/usr/bin/python
# coding:utf8'''
Created on Nov 28, 2010
Update  on 2017-05-18
Adaboost is short for Adaptive Boosting
@author: Peter/片刻
《机器学习实战》更新地址:https://github.com/apachecn/MachineLearning
'''
from numpy import *# ==fc==
def loadSimpData():""" 测试数据Returns:dataArr   feature对应的数据集labelArr  feature对应的分类标签"""dataArr = array([[1., 2.1], [2., 1.1], [1.3, 1.], [1., 1.], [2., 1.]])labelArr = [1.0, 1.0, -1.0, -1.0, 1.0]return dataArr, labelArr# ==fc==
# general function to parse tab -delimited floats
def loadDataSet(fileName):# get number of fieldsnumerOfFeature = len(open(fileName).readline().split('\t'))dataArr = []labelArr = []fr = open(fileName)for line in fr.readlines():lineArr = []curLine = line.strip().split('\t')for i in range(numerOfFeature-1):lineArr.append(float(curLine[i]))dataArr.append(lineArr)labelArr.append(float(curLine[-1]))return dataArr, labelArr# ==fc==
def stumpClassify(dataMat, dimen, threshVal, threshIneq):"""stumpClassify(将数据集,按照feature列的value进行 二分法切分比较来赋值分类)Args:dataMat    Matrix数据集dimen      特征列threshVal  特征列要比较的值Returns:retArray 结果集"""# 默认都是1retArray = ones((shape(dataMat)[0], 1))# dataMat[:, dimen] 表示数据集中第dimen列的所有值# threshIneq == 'lt'表示修改左边的值,gt表示修改右边的值# print '-----', threshIneq, dataMat[:, dimen], threshValif threshIneq == 'lt':retArray[dataMat[:, dimen] <= threshVal] = -1.0else:retArray[dataMat[:, dimen] > threshVal] = -1.0return retArray# ==fc== 找出以某列的某个中间值为threshold进行简单分类错误率最好的情况
def buildStump(dataArr, labelArr, D):"""buildStump(得到决策树的模型)Args:dataArr   特征标签集合labelArr  分类标签集合D         最初的特征权重值Returns:bestStump    最优的分类器模型minError     错误率bestClasEst  训练后的结果集"""# 转换数据dataMat = mat(dataArr)labelMat = mat(labelArr).T# m行 n列m, n = shape(dataMat)# 初始化数据numSteps = 10.0bestStump = {}bestClasEst = mat(zeros((m, 1)))# 初始化的最小误差为无穷大minError = inf# 循环所有的feature列,将列切分成 若干份,每一段以最左边的点作为分类节点for i in range(n):rangeMin = dataMat[:, i].min()rangeMax = dataMat[:, i].max()# print 'rangeMin=%s, rangeMax=%s' % (rangeMin, rangeMax)# 计算每一份的元素个数stepSize = (rangeMax-rangeMin)/numSteps# 例如: 4=(10-1)/2   那么  1-4(-1次)   1(0次)  1+1*4(1次)   1+2*4(2次)# 所以: 循环 -1/0/1/2for j in range(-1, int(numSteps)+1):# go over less than and greater thanfor inequal in ['lt', 'gt']:# 如果是-1,那么得到rangeMin-stepSize; 如果是numSteps,那么得到rangeMaxthreshVal = (rangeMin + float(j) * stepSize)# 对单层决策树进行简单分类,得到预测的分类值predictedVals = stumpClassify(dataMat, i, threshVal, inequal)# print predictedValserrArr = mat(ones((m, 1)))# 正确为0,错误为1errArr[predictedVals == labelMat] = 0# 计算 平均每个特征的概率0.2*错误概率的总和为多少,就知道错误率多高# 例如: 一个都没错,那么错误率= 0.2*0=0 , 5个都错,那么错误率= 0.2*5=1, 只错3个,那么错误率= 0.2*3=0.6weightedError = D.T*errArr'''dim            表示 feature列threshVal      表示树的分界值inequal        表示计算树左右颠倒的错误率的情况weightedError  表示整体结果的错误率bestClasEst    预测的最优结果'''# 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'] = inequal# bestStump 表示分类器的结果,在第几个列上,用大于/小于比较,阈值是多少return bestStump, minError, bestClasEst# ==fc==
def adaBoostTrainDS(dataArr, labelArr, numIt=40):"""adaBoostTrainDS(adaBoost训练过程放大)Args:dataArr   特征标签集合labelArr  分类标签集合numIt     实例数Returns:weakClassArr  弱分类器的集合aggClassEst   预测的分类结果值"""weakClassArr = []m = shape(dataArr)[0]# 初始化 D,设置每个特征的权重值,平均分为m份D = mat(ones((m, 1))/m)aggClassEst = mat(zeros((m, 1)))for i in range(numIt):# 得到决策树的模型bestStump, error, classEst = buildStump(dataArr, labelArr, D)# alpha 目的主要是计算每一个分类器实例的权重(加和就是分类结果)# 计算每个分类器的 alpha 权重值alpha = float(0.5*log((1.0-error)/max(error, 1e-16)))bestStump['alpha'] = alpha# store Stump Params in ArrayweakClassArr.append(bestStump)# print "alpha=%s, classEst=%s, bestStump=%s, error=%s " % (alpha, classEst.T, bestStump, error)# 分类正确:乘积为1,不会影响结果,-1主要是下面求e的-alpha次方# 分类错误:乘积为 -1,结果会受影响,所以也乘以 -1expon = multiply(-1*alpha*mat(labelArr).T, classEst)# print '\n'# print 'labelArr=', labelArr# print 'classEst=', classEst.T# print '\n'# print '乘积: ', multiply(mat(labelArr).T, classEst).T# 判断正确的,就乘以-1,否则就乘以1, 为什么? 书上的公式。# print '(-1取反)预测值expon=', expon.T# 计算e的expon次方,然后计算得到一个综合的概率的值# 结果发现: 判断错误的样本,D对于的样本权重值会变大。D = multiply(D, exp(expon))D = D/D.sum()# print "D: ", D.T# print '\n'# 预测的分类结果值,在上一轮结果的基础上,进行加和操作# print '当前的分类结果:', alpha*classEst.TaggClassEst += alpha*classEst# print "叠加后的分类结果aggClassEst: ", aggClassEst.T# sign 判断正为1, 0为0, 负为-1,通过最终加和的权重值,判断符号。# 结果为:错误的样本标签集合,因为是 !=,那么结果就是0 正, 1 负aggErrors = multiply(sign(aggClassEst) != mat(labelArr).T, ones((m, 1)))errorRate = aggErrors.sum()/m# print "total error=%s " % (errorRate)if errorRate == 0.0:breakreturn weakClassArr, aggClassEstdef adaClassify(datToClass, classifierArr):# do stuff similar to last aggClassEst in adaBoostTrainDSdataMat = mat(datToClass)m = shape(dataMat)[0]aggClassEst = mat(zeros((m, 1)))# 循环 多个分类器for i in range(len(classifierArr)):# 前提: 我们已经知道了最佳的分类器的实例# 通过分类器来核算每一次的分类结果,然后通过alpha*每一次的结果 得到最后的权重加和的值。classEst = stumpClassify(dataMat, classifierArr[i]['dim'], classifierArr[i]['thresh'], classifierArr[i]['ineq'])aggClassEst += classifierArr[i]['alpha']*classEst# print aggClassEstreturn sign(aggClassEst)def plotROC(predStrengths, classLabels):"""plotROC(打印ROC曲线,并计算AUC的面积大小)Args:predStrengths  最终预测结果的权重值classLabels    原始数据的分类结果集"""# print 'predStrengths=', predStrengths# print 'classLabels=', classLabelsimport matplotlib.pyplot as plt# variable to calculate AUCySum = 0.0# 对正样本的进行求和numPosClas = sum(array(classLabels)==1.0)# 正样本的概率yStep = 1/float(numPosClas)# 负样本的概率xStep = 1/float(len(classLabels)-numPosClas)# argsort函数返回的是数组值从小到大的索引值# get sorted index, it's reversesortedIndicies = predStrengths.argsort()# 测试结果是否是从小到大排列# print 'sortedIndicies=', sortedIndicies, predStrengths[0, 176], predStrengths.min(), predStrengths[0, 293], predStrengths.max()# 开始创建模版对象fig = plt.figure()fig.clf()ax = plt.subplot(111)# cursor光标值cur = (1.0, 1.0)# loop through all the values, drawing a line segment at each pointfor index in sortedIndicies.tolist()[0]:if classLabels[index] == 1.0:delX = 0delY = yStepelse:delX = xStepdelY = 0ySum += cur[1]# draw line from cur to (cur[0]-delX, cur[1]-delY)# 画点连线 (x1, x2, y1, y2)# print cur[0], cur[0]-delX, cur[1], cur[1]-delYax.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')# 设置画图的范围区间 (x1, x2, y1, y2)ax.axis([0, 1, 0, 1])plt.show()'''参考说明:http://blog.csdn.net/wenyusuran/article/details/39056013为了计算 AUC ,我们需要对多个小矩形的面积进行累加。这些小矩形的宽度是xStep,因此可以先对所有矩形的高度进行累加,最后再乘以xStep得到其总面积。所有高度的和(ySum)随着x轴的每次移动而渐次增加。'''print "the Area Under the Curve is: ", ySum*xStepif __name__ == "__main__":# # 我们要将5个点进行分类# dataArr, labelArr = loadSimpData()# print 'dataArr', dataArr, 'labelArr', labelArr# # D表示最初值,对1进行均分为5份,平均每一个初始的概率都为0.2# # D的目的是为了计算错误概率: weightedError = D.T*errArr# D = mat(ones((5, 1))/5)# print 'D=', D.T# # bestStump, minError, bestClasEst = buildStump(dataArr, labelArr, D)# # print 'bestStump=', bestStump# # print 'minError=', minError# # print 'bestClasEst=', bestClasEst.T# # 分类器:weakClassArr# # 历史累计的分类结果集# weakClassArr, aggClassEst = adaBoostTrainDS(dataArr, labelArr, 9)# print '\nweakClassArr=', weakClassArr, '\naggClassEst=', aggClassEst.T# """# 发现:# 分类的权重值:最大的值,为alpha的加和,最小值为-最大值# 特征的权重值:如果一个值误判的几率越小,那么D的特征权重越少# """# # 测试数据的分类结果, 观测:aggClassEst分类的最终权重# print adaClassify([0, 0], weakClassArr).T# print adaClassify([[5, 5], [0, 0]], weakClassArr).T# 马疝病数据集# 训练集合dataArr, labelArr = loadDataSet("input/7.AdaBoost/horseColicTraining2.txt")weakClassArr, aggClassEst = adaBoostTrainDS(dataArr, labelArr, 40)print weakClassArr, '\n-----\n', aggClassEst.T# 计算ROC下面的AUC的面积大小plotROC(aggClassEst.T, labelArr)# 测试集合dataArrTest, labelArrTest = loadDataSet("input/7.AdaBoost/horseColicTest2.txt")m = shape(dataArrTest)[0]predicting10 = adaClassify(dataArrTest, weakClassArr)errArr = mat(ones((m, 1)))# 测试:计算总样本数,错误样本数,错误率print m, errArr[predicting10 != mat(labelArrTest).T].sum(), errArr[predicting10 != mat(labelArrTest).T].sum()/m

主要思想:

弱分类器构造强分类器,弱分类器的特点就是非常容易找,这里的找法就很简单,遍历所有的feature,训练数据里每个feature都有个最大值和最小值,在最大值和最小值之间等分为n段,段与段之间的连接点为threshold,比threashold小的分为一类,比threashold大大分为一类,这就是一个弱分类器,分完后,跟实际label比,计算误差率,选取误差率最下的那个弱分类器,也就是说选了一个feature(列)和该列的一个threshold, 思路就是这样。

buildStump函数就是用类构造弱分类器,但是每次执行它都更新权重列表参数D,这样下一次又构造出一个新的弱分类器,每个弱分类器还要计算其对应的alpha,以组合成最终的分类器。

训练完后实际上得到的就是一组弱分类器和其对应的alpha,然后在测试阶段,就是用这一堆分类器的加权组合去计算测试数据,得到最终结果。这段代码基本上是网上能找到的最简单的理解adaboost的案例了。

adaboost是一种思想,处理不同的问题方法不尽相同,尤其是处理原始数据的权重参数的方法不太一样,我看过的几个例子是根据情况对D进行的不同处理, 比如这里是用来计算weightederror,弱分类器本身的权重相对来说容易处理一些,有固定的公式

ref:

这篇讲得比较好理解: http://blog.csdn.net/v_july_v/article/details/40718799

老外的这篇更清晰: http://mccormickml.com/2013/12/13/adaboost-tutorial/

然后github上有一个可读性比较好的案例: https://github.com/fengchangfight/NaiveBayesSpamFilter

来自机器学习实战的案例: https://github.com/apachecn/MachineLearning/tree/master/src/python/7.AdaBoost

转载于:https://www.cnblogs.com/huangzifu/p/7601941.html

adaboost案例源码解析相关推荐

  1. 0基础快速入门WebPack(3)——图解详述plugins(插件)的安装及sourceMap的使用及WebpackDevServer正向代理和模块热更新等(附详细案例源码解析过程及版本迭代过程)

    文章目录 1. 重点提炼 2. 配置环境 3. Plugins(插件) 3.1 HtmlWebpackPlugin 3.1.1 example01 3.1.1.1 example01-1 3.1.1. ...

  2. 0基础快速入门CSS技术栈(3)—图解详细阐述CSS文字文本样式及综合案例、样式调试工具、快速开发html的emment语法(附详细案例源码解析过程)

    文章目录 1. CSS字体样式属性调试工具 2. font字体 2.1 font-size:大小 2.2 font-family:字体 2.2.1 CSS Unicode字体 2.3 font-wei ...

  3. 0基础快速入门CSS技术栈(6)—图解详细阐述说透CSS的浮动及应用、浮动的扩展及清除浮动和详解快速·1photoshop切图(附详细案例源码解析过程)2021-01-07更新

    文章目录 1. 浮动(float)重点提炼 2. CSS 布局的三种机制 3. 为什么需要浮动? 3.1 example01 4. 什么是浮动(float) 4.1 作用 4.1.1 example0 ...

  4. 0基础快速入门CSS技术栈(4)—图解详细阐述CSS的复合选择器、标签显示模式、行高、CSS背景,及最为重要的CSS三大特性附带权重计算笔试题(附详细案例源码解析过程)

    文章目录 1. 0基础快速入门CSS技术栈(4) 2. 重点提炼 3. CSS复合选择器 3.1 后代选择器(重点) 3.1.1 example01 3.2 子元素选择器 3.2.1 exmaple0 ...

  5. 0基础快速入门CSS技术栈(5)—图解详细阐述说透CSS的盒子模型(超级重要)、圆角边框、盒子阴影及相关重要的笔试题——css的核心中的核心(附详细案例源码解析过程)2021.01.07更新

    文章目录 1. 盒子模型(CSS重点) 1.1 看透网页布局的本质 1.2 盒子模型(Box Model) 1.3 盒子边框(border) 1.3.1 边框综合设置 1.3.2 example01 ...

  6. Java线程池源码解析及高质量代码案例

    引言 本文为Java高级编程中的一些知识总结,其中第一章对Jdk 1.7.0_25中的多线程架构中的线程池ThreadPoolExecutor源码进行架构原理介绍以及源码解析.第二章则分析了几个违反J ...

  7. 高并发之深度解析CAS [理论+案例+源码]

    目录 1.理论 2.问题 3.实操--Atomic打头的类 4.原理:基于类Striped64分散热点[空间换时间] 1.理论 CAS,即compare and swap,比较并交换,包含三个操作数, ...

  8. 设计模式 结构型模式 -- 装饰者模式(概述 快餐店案例 模式优点 使用场景 源码解析 BufferedWriter 和代理模式的区别)

    1. 装饰者模式 1.1 概述 我们先来看一个快餐店的例子: 快餐店有炒面.炒饭这些快餐,可以额外附加鸡蛋.火腿.培根这些配菜,当然加配菜需要额外加钱,每个配菜的价钱通常不太一样,那么计算总价就会显得 ...

  9. spring MVC cors跨域实现源码解析

    spring MVC cors跨域实现源码解析 名词解释:跨域资源共享(Cross-Origin Resource Sharing) 简单说就是只要协议.IP.http方法任意一个不同就是跨域. sp ...

最新文章

  1. Pytorch:使用DCGAN实现数据复制
  2. python开发工程师面试题-分析经典Python开发工程师面试题
  3. SpringMVC工作原理之一:DispatcherServlet
  4. window 系统上传文件到linux 系统出现dos 格式换行符
  5. 【英语学习】【Daily English】U05 Places L04 Can I have some painkillers?
  6. 黑客购买恶意软件攻击航空航天和交通行业,潜伏5年+
  7. Java集合框架源码解读(5)——TreeMap
  8. 74cms3.0 SQL注入
  9. 图像检索系列——利用深度学习实现以图搜图
  10. 电商收付通系列⑤,商户进件之二级商户进件申请
  11. GAN for Image-to-image translation 2019年文章综述
  12. 互金累计融资近千例 借贷行业融资数量居首位
  13. 【工业革命】第四次工业革命:自主经济的崛起
  14. 实验四:app内页面跳转
  15. NAS不够快?那就上SSD享受如火箭般的体验吧!
  16. java基础知识粗略整理
  17. 数据结构与算法《二分查找》
  18. 2021-10-27 - 开发人员将大多数时间花到了探究系统本身上
  19. SVPWM的一些理解
  20. 苹果手机怎样添加无线网服务器,如何让苹果手机网速提升三倍?

热门文章

  1. 写一段C sharp 语言的攻击怪物代码
  2. Ubuntu + CUDA 8.0 + GTX960M
  3. halcon 深度学习标注_HALCON深度学习工具0.4 早鸟版发布了
  4. NOIP2013 花匠 题解(方法全面)
  5. vue $broadcast
  6. 智云物业v5.0.7
  7. ELK日志分析系统及相关
  8. 深度学习UFLDL教程翻译之自动编码器
  9. 计算机动画可分为哪两大类,人物跑常见的绘画方法动态人物动作中间画绘制中动画有()类型。...
  10. 设计模式的总览与分类