adaBoost

来源:互联网 发布:jdk源码怎么看 编辑:程序博客网 时间:2024/06/05 23:30
# -*-coding:utf-8-*-'''Adaboost'''from __future__ import division import numpy as npdef 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,classLabelsdef 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 retArraydef 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 weakClassArrdef 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()

0 0
原创粉丝点击