adaBoost

原创 2015年07月09日 21:39:12
# -*-coding:utf-8-*-
'''
Adaboost
'''
from __future__ import division 
import numpy as np

def LoadSimpleData():
    dataMat = np.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,classLabels

def loadDataSet(fileName):
    '''
        加载数据
    '''
    f = open(fileName)
    _numFeat = len(f.readline().split('\t'))
    dataMat = []
    labelMat = []
    for _line_ in f.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 stumpClassify(dataMatrix,dimen,threshVal,threshIneq):
    '''
        数据集 | 特征 | 阈值 | 分类
        通过阈值比较对数据分类,以1和-1表示分类值返回
    '''
    retArray = np.ones((np.shape(dataMatrix)[0],1))   # 返回数组初始化为全1
    if threshIneq == 'lt':
        # >阈值为1;<=阈值为-1
        retArray[dataMatrix[:,dimen] <= threshVal] = -1.0
    else:
        # >阈值为-1;<=阈值为1
        retArray[dataMatrix[:,dimen] > threshVal] = -1.0
    return retArray

def buildStump(dataArr,classLabels,D):
    '''
        找错误率最小的决策树
        将最小错误率minError设为+无穷
        对数据集中的每一个特征(第一层循环):
            对每个步长(第二层循环):
                对每个不等号(第三层循环):
                    建立一棵单层决策树并利用加权数据集对它进行测试
                    如果错误率低于minError,则将当前单层决策树设为最佳单层决策树
    '''
    _dataMatrix = np.mat(dataArr)
    _labelMat = np.mat(classLabels).T
    m,n = np.shape(_dataMatrix)
    _numSteps = 10.0 # 按步长与训练数据比较,
    bestStump = {} # 存储给定权重向量D时所得到的最佳单层决策树
    bestClassEst = np.mat(np.zeros((m,1)))  
    minError = np.inf
    for i in range(n):  # 对每一个数据特征
        _rangeMin = _dataMatrix[:,i].min()  # 特征最小值
        _rangeMax = _dataMatrix[:,i].max()  # 特征最大值
        _stepSize = (_rangeMax-_rangeMin)/_numSteps # 步长,比较值的每次改变量
        for j in range(-1,int(_numSteps)+1):  
            for _inequal_ in ['lt','gt']:   # 分别比较与阈值的大小,类似于左右支树
                _threshVal = (_rangeMin + float(j) * _stepSize)     # 比较的值每次按步长增加
                _predictedVals = stumpClassify(_dataMatrix,i,_threshVal,_inequal_)  # 与阈值相比后的1.-1分类向量
                _errArr = np.mat(np.ones((m,1)))    # 初始化误差矩阵为全1
                _errArr[_predictedVals == _labelMat] = 0    # 预测分类与实际类,正确=0
                _weightedError = D.T * _errArr # 误差率 e
                if _weightedError < minError:   # 选择最小错误率的决策树
                    minError = _weightedError
                    bestClassEst = _predictedVals.copy()
                    bestStump['dim'] = i
                    bestStump['thresh'] = _threshVal
                    bestStump['ineq'] = _inequal_
    return bestStump,minError,bestClassEst  # 返回构建的单层决策树,最小的错误率和分类向量

def adaBoostTrainDS(dataArr,classLabels,numIt=40):
    '''
        基于当成决策树的AdaBoost训练过程
    '''
    weakClassArr=[]
    m,n = np.shape(dataArr)
    _D = np.mat(np.ones((m,1))/m)   # 训练数据权重初始为全1
    _aggClassEst = np.mat(np.zeros((m,1)))  # 按照权重计算出每个数据的分类估计累计值
    for i in range(numIt):  # 循环,直到最大循环次数或错误率为0
        '''
                    构建一个单层决策树
                    返回的是利用D而得到的具有最小错误率的单层决策树,最小的误差率,估计的类别向量
        '''
        _bestStump, _error, _classEst = buildStump(dataArr,classLabels,_D)
        #print "D: ",_D.T
        _alpha = float(0.5 * np.log((1.0-_error) / max(_error,1e-16))) # 根据错误率计算分类器输出结果的权重
        _bestStump['alpha'] = _alpha    # 存储该单层决策树的权重
        weakClassArr.append(_bestStump)  
        #print "classEst: ",_classEst.T
        _expon = np.multiply(-1 * _alpha * np.mat(classLabels).T,_classEst)    # 更新数据的权重分布
        _D = np.multiply(_D,np.exp(_expon))
        _D = _D/_D.sum()
           
        _aggClassEst += _alpha * _classEst  # 记录运行时的估计值  
        #print "aggClassEst: ",_aggClassEst.T
        _aggErrors = np.multiply(np.sign(_aggClassEst) != np.mat(classLabels).T,np.ones((m,1))) # 
        errorRate = _aggErrors.sum()/m
        print "total error: ",errorRate,"\n"
        if errorRate == 0.0:
            break
    return weakClassArr

def adaClassify(datToClass,classifierArr):
    '''
        带分类样例  | 多个弱分类器组成的数组
        利用训练出的多个弱分类器进行分类
    '''
    _dataMatrix = np.mat(datToClass)
    m,n = np.shape(_dataMatrix) 
    _aggClassEst = np.mat(np.zeros((m,1)))   # 全0列向量,存储累计的分类结果
    for i in range(len(classifierArr)):     #  对每一训练好的弱分类器
        classEst = stumpClassify(_dataMatrix,classifierArr[i]['dim'],classifierArr[i]['thresh'],classifierArr[i]['ineq'])    # 类别估计值
        _aggClassEst += classifierArr[i]['alpha']*classEst
    return np.sign(_aggClassEst)
            
dataArr,labelArr = loadDataSet('horseColicTraining2.txt')
classifierArr = adaBoostTrainDS(dataArr,labelArr,10)
testArr,testLabelArr = loadDataSet('horseColicTest2.txt')
predict = adaClassify(testArr,classifierArr)
errArr = np.mat(np.ones((67,1)))
print errArr[predict != np.mat(testLabelArr).T].sum()

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

基于adaboost的人脸检测

  • 2017-07-14 19:40
  • 3.98MB
  • 下载

Adaboost提升方法

该算法是Adaptive Boosting的缩写 算法思想:三个臭皮匠,顶个诸葛亮,也就是说对于一个复杂的任务来说,将多个专家的判断进行适当的综合所得出的判断,要比其中任何一个专家的判断好。 从软学习...

Adaboost算法详解

  • 2016-12-20 20:35
  • 609KB
  • 下载

Haar特征、积分图、Adaboost算法、分类器训练

一、Haar-like特征 Haar特征值反映了图像分度变化的情况。 Haar-like特征最早是由Papageorgiou等应用于人脸表示,Viola和Jones在此基础上,使用3种类型4种形式...

adaboost的简单证明

  • 2014-03-10 14:36
  • 842KB
  • 下载

AdaBoost算法简介

  • 2013-02-05 09:26
  • 206KB
  • 下载

提升方法AdaBoost算法完整python代码

提升方法AdaBoost算法提升方法简述俗话说,“三个臭皮匠顶个诸葛亮”,对于一个复杂的问题,一个专家的判断往往没有多个专家的综合判断来得好。通常情况下,学习一个弱学习算法比学习一个强学习算法容易得多...

AdaBoost算法

  • 2014-08-06 21:18
  • 63KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)