机器学习实战5-AdaBoost

1.  前戏

集成学习,通过构建并结合多个学习器来完成学习任务,主要分以下两个种类:
  1. 个体学习器间存在强依赖关系、必须串行生成的序列化方法。代表为boosting,如adaboost。
  2. 个体学习器间不存在强依赖关系、可同时生成的并行化方法。代表为bagging和随机森林(RF)。

2.  adaboost解释

本质上就是三个臭皮匠顶个诸葛亮,将有限个弱分类器组合成为一个强分类器,从而增强分类效果。弱分类器的构建是串行的,也就是说有了上一个分类器的错误率才会构建下一个分类器,直到强分类器能够达到要求。如果想要了解具体数学算法,可搜索加法模型,损失函数(使用的是指数损失函数),前向分步函数,可参阅李航《统计学习方法》,讲的较清楚。
 
算法流程:
  1. 给定初始样本数据权重(1/m),权重相等
  2. 放入基础弱学习器学习,得到一个弱分类器
  3. 计算该分类器错误率,根据错误率计算分类器权重alpha(注意此处权重为分类器权重)
  4. 根据分类器权重计算样本权重矩阵D(分类错误的权重增加,分类正确的权重减少,注意此处的权重为样本的权重)
  5. 将所有的弱分类器按权重alpha线性组合得到最终的强分类器
  6. 判断强分类器的错误率是否为零,或者迭代次数是否到达阈值,否则重复步骤2,3,4,5

3. 实例:基于单层决策树的弱分类器

 1 from numpy import *
 2 
 3 # 1.新建数据
 4 def loadSimpData():
 5     datMat=mat([[1,2.1],
 6                    [2,1.1],
 7                    [1.3,1],
 8                    [1,1],
 9                    [2,1]])
10     classLabels=[1.0,1.0,-1.0,-1.0,1.0]
11     return datMat,classLabels
12 
13 # 2. 通过阈值比较对数据进行分类
14 def stumpClassify(dataMatrix,dimen,threshVal,threshIneq):
15     retArray=ones((shape(dataMatrix)[0],1))
16     if threshIneq=='lt':
17         retArray[dataMatrix[:,dimen]<=threshVal]=-1.0
18     else:
19         retArray[dataMatrix[:,dimen]>threshVal]=-1.0
20     return retArray
21 
22 # 3. 单层决策树,是决策树的一个弱化版本
23 #    遍历stumpClassify()函数所有的可能输入值,并找到数据集上的最佳单层决策树
24 def buildStump(dataArr,classLabels,D):
25     dataMatrix=mat(dataArr)
26     labelMat=mat(classLabels).T
27     m,n=shape(dataMatrix)
28     numSteps=10.0;bestStump={};bestClassEst=mat(zeros((m,1)))
29     minError=inf # 初始最小错误为正无穷
30     # 数据集上的所有特征进行循环
31     for i in range(n):
32         rangeMin =dataMatrix[:,i].min()
33         rangeMax =dataMatrix[:,i].max()
34         stepSize=(rangeMax-rangeMin)/numSteps
35         # 在每个特征里(即每一列数),从最小值到最大值之间按照固定步长遍历,寻找到一个最小分类错误率
36         for j in range(-1,int(numSteps)+1):
37             # 在大于和小于之间切换不等式
38             for inequal in ['lt','gt']:
39                 threshVal=(rangeMin+float(j)*stepSize)
40                 predictedVals=stumpClassify(dataMatrix,i,threshVal,inequal) #按阈值分类
41                 errArr=mat(ones((m,1)))
42                 errArr[predictedVals==labelMat]=0 #分类错误为1
43                 weightedError=D.T*errArr
44                 # print("split: dim %d,thresh %.2f,thresh inequal: %s,the weighted error is %.3f"%\
45                 #       (i,threshVal,inequal,weightedError))
46                 if weightedError<minError:
47                     minError=weightedError
48                     bestClassEst=predictedVals.copy()
49                     bestStump['dim']=i
50                     bestStump['thresh']=threshVal
51                     bestStump['ineq']=inequal
52     return bestStump,minError,bestClassEst
53 
54 # 4. adaboost算法,返回各弱分类器
55 def adaBoostTrainDS(dataArr,classLabels,numIt=40):
56     weakClassArr=[]
57     m=shape(dataArr)[0]
58     D=mat(ones((m,1))/m)
59     aggClassEst=mat(zeros((m,1)))
60     for i in range(numIt):
61         bestStump,error,classEst=buildStump(datMat,classLabels,D) # 弱分类器,单层决策树
62         # print("D:",D.T)
63         alpha=float(0.5*log((1.0-error)/max(error,1e-16))) # 计算分类器权重alpha值,此处一个分类器就是一次单层决策树
64         bestStump['alpha']=alpha
65         weakClassArr.append(bestStump)
66         # print("classEst:",classEst.T)
67         # 计算expon, 正确分类的样本为exp(-alpha),错误分类的样本为为exp(alpha)
68         # D为权重矩阵,这里的权重是样本的权重,由alpha计算而来
69         expon=multiply(-1*alpha*mat(classLabels).T,classEst)
70         D=multiply(D,exp(expon))
71         D=D/D.sum()
72         aggClassEst+=alpha*classEst  # 记录每个数据点的类别估计累计值,也就是分类器加权求和
73         # print("aggclassest:",aggClassEst.T)
74         # 分类错误结果置1 sign取数字符号,正数为1,负数为-1,0为0
75         aggErrors=multiply(sign(aggClassEst)!=mat(classLabels).T,ones((m,1)))
76         errorRate=aggErrors.sum()/m
77         print("total error:",errorRate,"\n")
78         if errorRate==0.0:
79             break
80     return weakClassArr

 

posted @ 2019-05-23 09:42  滇红88号  阅读(207)  评论(0编辑  收藏  举报