简单易学的机器学习算法——AdaBoost 简单易学的机器学习算法——AdaBoost

简单易学的机器学习算法——AdaBoost

一、集成方法(Ensemble Method)

    集成方法主要包括BaggingBoosting两种方法,随机森林算法是基于Bagging思想的机器学习算法,Bagging方法中,主要通过对训练数据集进行随机采样,以重新组合成不同的数据集,利用弱学习算法对不同的新数据集进行学习,得到一系列的预测结果,对这些预测结果做平均或者投票做出最终的预测。AdaBoost算法和GBDT(Gradient Boost Decision Tree,梯度提升决策树)算法是基于Boosting思想的机器学习算法。在Boosting思想中是通过对样本进行不同的赋值,对错误学习的样本的权重设置的较大,这样,在后续的学习中集中处理难学的样本,最终得到一系列的预测结果,每个预测结果有一个权重,较大的权重表示该预测效果较好,详细的思想可见博文“简单易学的机器学习算法——集成方法(Ensemble Method)”。

二、AdaBoost算法思想

    AdaBoost算法是基于Boosting思想的机器学习算法,其中AdaBoostAdaptive Boosting的缩写,AdaBoost是一种迭代型的算法,其核心思想是针对同一个训练集训练不同的学习算法,即弱学习算法,然后将这些弱学习算法集合起来,构造一个更强的最终学习算法。
    为了构造出一个强的学习算法,首先需要选定一个弱学习算法,并利用同一个训练集不断训练弱学习算法,以提升弱学习算法的性能。在AdaBoost算法中,有两个权重,第一个数训练集中每个样本有一个权重,称为样本权重,用向量表示;另一个是每一个弱学习算法具有一个权重,用向量表示。假设有个样本的训练集,初始时,设定每个样本的权重是相等的,即,利用第一个弱学习算法对其进行学习,学习完成后进行错误率的统计:



其中,表示被错误分类的样本数目,表示所有样本的数目。这样便可以利用错误率计算弱学习算法的权重



    在第一次学习完成后,需要重新调整样本的权重,以使得在第一分类中被错分的样本的权重,使得在接下来的学习中可以重点对其进行学习:



其中,表示对第个样本训练正确,表示对第个样本训练错误。是一个归一化因子:



这样进行第二次的学习,当学习轮后,得到了个弱学习算法及其权重。对新的分类数据,分别计算个弱分类器的输出,最终的AdaBoost算法的输出结果为:



其中,是符号函数。具体过程可见下图所示:

(图片来自参考文件1)

三、AdaBoost算法流程

    上述为AdaBoost的基本原理,下面给出AdaBoost算法的流程:

(来自参考文献2)

四、实际的例子
    AdaBoost 算法是一种具有很高精度的分类器,其实 AdaBoost 算法提供的是一种框架,在这种框架下,我们可以使用不同的弱分类器,通过 AdaBoost 框架构建出强分类器。下面我们使用单层决策树构建一个分类器处理如下的分类问题:

决策树算法主要有 ID3 C4.5 CART ,其中 ID3 C4.5 主要用于分类, CART 可以解决回归问题。 ID3 算法可见博文“简单易学的机器学习算法——决策树之ID3算法”, CART 算法可见博文“简单易学的机器学习算法——CART之回归树”。对于单层决策树是无法求解上面这样的问题的。

Python 代码
[python]  view plain  copy
  1. #coding:UTF-8  
  2. ''''' 
  3. Created on 2015年6月15日 
  4.  
  5. @author: zhaozhiyong 
  6.  
  7. '''  
  8.   
  9. from numpy import *  
  10.   
  11. def loadSimpleData():  
  12.     datMat = mat([[1.2.1],  
  13.                   [2.1.1],  
  14.                   [1.31.],  
  15.                   [1.1.],  
  16.                   [2.1.]])  
  17.     classLabels = mat([1.01.0, -1.0, -1.01.0])  
  18.     return datMat, classLabels  
  19.   
  20. def singleStumpClassipy(dataMat, dim, threshold, thresholdIneq):  
  21.     classMat = ones((shape(dataMat)[0], 1))  
  22.     #根据thresholdIneq划分出不同的类,在'-1'和'1'之间切换  
  23.     if thresholdIneq == 'left':#在threshold左侧的为'-1'  
  24.         classMat[dataMat[:, dim] <= threshold] = -1.0  
  25.     else:  
  26.         classMat[dataMat[:, dim] > threshold] = -1.0  
  27.       
  28.     return classMat  
  29.   
  30. def singleStump(dataArr, classLabels, D):  
  31.     dataMat = mat(dataArr)  
  32.     labelMat = mat(classLabels).T  
  33.     m, n = shape(dataMat)  
  34.     numSteps = 10.0  
  35.     bestStump = {}  
  36.     bestClasEst = zeros((m, 1))  
  37.     minError = inf  
  38.     for i in xrange(n):#对每一个特征  
  39.         #取第i列特征的最小值和最大值,以确定步长  
  40.         rangeMin = dataMat[:, i].min()  
  41.         rangeMax = dataMat[:, i].max()  
  42.         stepSize = (rangeMax - rangeMin) / numSteps  
  43.         for j in xrange(-1, int(numSteps) + 1):  
  44.             #不确定是哪个属于类'-1',哪个属于类'1',分两种情况  
  45.             for inequal in ['left''right']:  
  46.                 threshold = rangeMin + j * stepSize#得到每个划分的阈值  
  47.                 predictionClass = singleStumpClassipy(dataMat, i, threshold, inequal)  
  48.                 errorMat = ones((m, 1))  
  49.                 errorMat[predictionClass == labelMat] = 0  
  50.                 weightedError = D.T * errorMat#D是每个样本的权重  
  51.                 if weightedError < minError:  
  52.                     minError = weightedError  
  53.                     bestClasEst = predictionClass.copy()  
  54.                     bestStump['dim'] = i  
  55.                     bestStump['threshold'] = threshold  
  56.                     bestStump['inequal'] = inequal  
  57.       
  58.     return bestStump, minError, bestClasEst  
  59.   
  60. def adaBoostTrain(dataArr, classLabels, G):  
  61.     weakClassArr = []  
  62.     m = shape(dataArr)[0]#样本个数  
  63.     #初始化D,即每个样本的权重  
  64.     D = mat(ones((m, 1)) / m)  
  65.     aggClasEst = mat(zeros((m, 1)))  
  66.       
  67.     for i in xrange(G):#G表示的是迭代次数  
  68.         bestStump, minError, bestClasEst = singleStump(dataArr, classLabels, D)  
  69.         print 'D:', D.T  
  70.         #计算分类器的权重  
  71.         alpha = float(0.5 * log((1.0 - minError) / max(minError, 1e-16)))  
  72.         bestStump['alpha'] = alpha  
  73.         weakClassArr.append(bestStump)  
  74.         print 'bestClasEst:', bestClasEst.T  
  75.           
  76.         #重新计算每个样本的权重D  
  77.         expon = multiply(-1 * alpha * mat(classLabels).T, bestClasEst)  
  78.         D = multiply(D, exp(expon))  
  79.         D = D / D.sum()  
  80.           
  81.         aggClasEst += alpha * bestClasEst  
  82.         print 'aggClasEst:', aggClasEst  
  83.         aggErrors = multiply(sign(aggClasEst) != mat(classLabels).T, ones((m, 1)))  
  84.         errorRate = aggErrors.sum() / m  
  85.         print 'total error:', errorRate  
  86.         if errorRate == 0.0:  
  87.             break  
  88.     return weakClassArr  
  89.   
  90. def adaBoostClassify(testData, weakClassify):  
  91.     dataMat = mat(testData)  
  92.     m = shape(dataMat)[0]  
  93.     aggClassEst = mat(zeros((m, 1)))  
  94.     for i in xrange(len(weakClassify)):#weakClassify是一个列表  
  95.         classEst = singleStumpClassipy(dataMat, weakClassify[i]['dim'], weakClassify[i]['threshold'], weakClassify[i]['inequal'])  
  96.         aggClassEst += weakClassify[i]['alpha'] * classEst  
  97.         print aggClassEst  
  98.     return sign(aggClassEst)  
  99.               
  100. if __name__ == '__main__':  
  101.     datMat, classLabels = loadSimpleData()  
  102.     weakClassArr = adaBoostTrain(datMat, classLabels, 30)  
  103.     print "weakClassArr:", weakClassArr  
  104.     #test  
  105.     result = adaBoostClassify([11], weakClassArr)  
  106.     print result  

最终的决策树序列:
weakClassArr: [{'threshold': 1.3, 'dim': 0, 'inequal': 'left', 'alpha': 0.6931471805599453}, {'threshold': 1.0, 'dim': 1, 'inequal': 'left', 'alpha': 0.9729550745276565}, {'threshold': 0.90000000000000002, 'dim': 0, 'inequal': 'left', 'alpha': 0.8958797346140273}]





参考
1、机器学习实战
2、A Short Introduction to Boosting

猜你喜欢

转载自blog.csdn.net/m0_37692953/article/details/80420268
今日推荐