ADABOOSt

来源:互联网 发布:淘宝杂货铺店名 编辑:程序博客网 时间:2024/05/19 19:41

  1. 导入需要进行训练的数据集。这个数据集一共有5个样本,每个样本都有两个。他们的类别都写在标签矩阵之中。由于这次分类使用的分类函数是符号函数,
  2. 只能输出-1和1两个结果,因此,和sigmoid函数的分类结果不同。
  3. def loadSimDat():  
  4.     dataMat = matrix([[12.1],  
  5.                       [2.01.1],  
  6.                       [1.31.0],  
  7.                       [1.01.0],  
  8.                       [2.01.0]])  
  9.     classLabels = [1.01.0, -1.0, -1.01.0]  
  10.     return dataMat, classLabels  
  11.   

  1. 根据输入的样本,选择样本的第dimen个特征作为分类的特征,选择threshVal作为该特征的阈值,并由threshIneq是否为Lt来确定这个样本是属于-1还是1
  2. 这个函数直接根据给定特征的阈值来对样本进行分类。
  3. def stumpClassify(dataMatrix,dimen,threshVal,threshIneq):#just classify the data  
  4.     retArray = ones((shape(dataMatrix)[0],1))  
  5.     if threshIneq == 'lt':  
  6.         retArray[dataMatrix[:,dimen] <= threshVal] = -1.0  
  7.     else:  
  8.         retArray[dataMatrix[:,dimen] > threshVal] = -1.0  
  9.     return retArray  //返回一个矩阵,里面是所有样本的分类结果
  10.   

  1. 这个函数实现:对于一个给定的样本初始权值D,返回错误率最低的分类器极其相应的各个特点,以及这个最佳分类器分类的结果。这个函数只返回一个分类器
  2. def buildStump(dataArr, classLabels, D):  
  3.     dataMatrix = mat(dataArr); labelMat = mat(classLabels).T  //样本集合和样本的标签
  4.     m,n = shape(dataMatrix)  
  5.     numSteps = 10.0; bestStump = {}; bestClassEst = mat(zeros((m,1)))  
  6.     minError = inf  //无穷大
  7.     for i in range(n):  //对所有 的特征进行遍历
  8.         rangeMin = dataMatrix[:,i].min(); rangeMax = dataMatrix[:,i].max();  //选出某个特征中的最大值和最小值
  9.         stepSize = (rangeMax - rangeMin)/numSteps  //设置阈值变化的步长
  10.         for j in range(-1, int(numSteps)+1):  //设置阈值增加的次数;对阈值进行等间隔遍历
  11.             for inequal in ['lt','gt']:  //设置分界值;对分界值进行遍历
  12.                 threshVal = (rangeMin + float(j)*stepSize)  //设置阈值
  13.                 predictedVals = stumpClassify(dataMatrix, i, threshVal, inequal)  //对于给定的矩阵、给定的特征、给定的阈值、给定的分界值,得出一个分类的结果
  14.                 errArr = mat(ones((m,1)))  
  15.                 errArr[predictedVals == labelMat] = 0  //将预测分类的结果和真实的类别结果进行比较,输出分类错误的结果
  16.                 weightedError = D.T * errArr      //计算误差率,根据定义,误差率是分类错误的样本的权值之和
  17.                 #print "split: dim %d, thresh %.2f, thresh inequal: %s, the weighted error is %.3f" %(i, threshVal, inequal, weightedError)  
  18.                 if weightedError < minError:  
  19.                     minError = weightedError  
  20.                     bestClassEst = predictedVals.copy()  
  21.                     bestStump['dim'] = i  
  22.                     bestStump['thresh'] = threshVal  
  23.                     bestStump['ineq'] = inequal  
  24.     return bestStump, minError, bestClassEst //对所有的特征、阈值、分界值进行遍历之后,就能够输出误差率最小的那个分类的方法。即相应的特征、阈值和分界值,以及这个最佳分类器的分类结果


  1. 训练一个完整的adaboost分类器
  2. def adaBoostTrainDS(dataArr, classLabels, numIt = 40):  //输入样本数据,以及样本真实的分类标签
  3.     weakClassArr = []  
  4.     m = shape(dataArr)[0]  //样本的个数
  5.     D = mat(ones((m,1))/m)  //初始化样本的权值,给每个样本都赋予相同的权值
  6.     aggClassEst = mat(zeros((m,1)))  //
  7.     for i in range(numIt):  //设置循环的次数,也即预先设定创建40个分类器
  8.         bestStump, error, classEst = buildStump(dataArr, classLabels, D)  //对于给定的样本和初始样本权值,返回最佳的分类器特征,分类结果和错误率
  9.        # print "D:", D.T  
  10.         alpha = float(0.5 * log((1.0 - error)/max(error, 1e-16)))  //由这个分类器的错误率计算这个分类器的权值
  11.         bestStump['alpha'] = alpha  
  12.         weakClassArr.append(bestStump)  //保存这个分类器的dim/thresh/ineq/alpha等四个特点
  13.         #print "classEst:", classEst.T  
  14.         expon = multiply(-1 * alpha * mat(classLabels).T, classEst)   
  15.         D = multiply(D, exp(expon))  
  16.         D = D/D.sum()            //上面三个式子是根据这个分类器的分类结果和分类器权重,来更新用于下一轮迭代的样本权值D。上面三个式子的理论依据如下
  17.         aggClassEst += alpha * classEst    #累加变成强分类器  ,将分类器的分类结果同分类器的权值线性叠加,形成强分类器。
  18.         aggErrors = multiply(sign(aggClassEst) != mat(classLabels).T, ones((m,1)))  //选出强分类器分类错误的样本
  19.         errorRate = aggErrors.sum()/m  //计算强分类器的错分率
  20.         print "total error: ", errorRate, "\n"  
  21.         if errorRate == 0.0break  
  22.     return weakClassArr, aggClassEst  //返回强分类器每个分类器的特征,以及强分类器的输出结果

样本权值更新函数如下:


强分类器累加函数:


由符号函数确定最终的分类器



  1. 调用完整的adaboost分类器对测试样本进行测试
  2. def adaClassify(datToClass, classifierArr):  //输入测试样本和上面训练出来的完整的adaboost分类器
  3.     dataMatrix = mat(datToClass)  
  4.     m = shape(dataMatrix)[0]  //测试样本的个数
  5.     aggClassEst = mat(zeros((m,1)))  //初始化强分类器的累加值为0
  6.     for i in range(len(classifierArr)):  //按顺序调用adaboost分类器中的每一个分类器,顺序很重要,因为训练器的顺序是由每个样本的权值决定的
  7.         classEst = stumpClassify(dataMatrix, classifierArr[i]['dim'], classifierArr[i]['thresh'], classifierArr[i]['ineq'])  //使用这个分类器给样本进行分类,并输出分类结果
  8.         aggClassEst += classifierArr[i]['alpha']*classEst  //将每个分类器的分类结果和分类器的权值线性相加,得到逐渐强分类器的分类结果
  9.         print aggClassEst  
  10.     return sign(aggClassEst)  //使用符号函数,输出真正最终的分类结果

adaboost分类器有个很明显的特点,它可以实现在训练样本中无错误地输出;但是在测试样本中,却只能将错误率稳定在一个值附近。

0 0
原创粉丝点击