机器学习实战第七章--集成方法 ensemble method

机器学习实战第七章–集成方法 ensemble method

集成方法:

ensemble method(元算法: meta algorithm) 概述
概念:是对其他算法进行组合的一种形式

提升方法是将弱学习算法提升为强学习算法的统计学习方法。在分类学习中,提升方法通过反复修改训练数据的权值分布,构建一系列基本分类器(弱分类器),并将这些基本分类器线性组合,构成一个强分类器。代表性的提升方法是AdaBoost算法。

AdaBoost模型是弱分类器的线性组合:

f ( x ) = ∑ m = 1 M α m G m ( x ) f(x)=\sum_{m=1}^{M} \alpha_{m} G_{m}(x) f(x)=m=1MαmGm(x)

随机森林 开发流程

收集数据:任何方法
准备数据:转换样本集
分析数据:任何方法
训练算法:通过数据随机化和特征随机化,进行多实例的分类评估
测试算法:计算错误率
使用算法:输入样本数据,然后运行 随机森林 算法判断输入数据分类属于哪个分类,最后对计算出的分类执行后续处理

随机森林 算法特点

优点:几乎不需要输入准备、可实现隐式特征选择、训练速度非常快、其他模型很难超越、很难建立一个糟糕的随机森林模型、大量优秀、免费以及开源的实现。
缺点:劣势在于模型大小、是个很难去解释的黑盒子。
适用数据范围:数值型和标称型

AdaBoost 开发流程


收集数据:可以使用任意方法
准备数据:依赖于所使用的弱分类器类型,本章使用的是单层决策树,这种分类器可以处理任何数据类型。
    当然也可以使用任意分类器作为弱分类器,第2章到第6章中的任一分类器都可以充当弱分类器。
    作为弱分类器,简单分类器的效果更好。
分析数据:可以使用任意方法。
训练算法:AdaBoost 的大部分时间都用在训练上,分类器将多次在同一数据集上训练弱分类器。
测试算法:计算分类的错误率。
使用算法:通SVM一样,AdaBoost 预测两个类别中的一个。如果想把它应用到多个类别的场景,那么就要像多类 SVM 中的做法一样对 AdaBoost 进行修改。

AdaBoost 算法特点

* 优点:泛化(由具体的、个别的扩大为一般的)错误率低,易编码,可以应用在大部分分类器上,无参数调节。
* 缺点:对离群点敏感。
* 适用数据类型:数值型和标称型数据。
from numpy import *

def loadSimpData():
   datMat = 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 datMat,classLabels

def loadDataSet(fileName):      #general function to parse tab -delimited floats
   numFeat = len(open(fileName).readline().split('\t')) #get number of fields 
   dataMat = []; labelMat = []
   fr = open(fileName)
   for line in fr.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):#just classify the data
   retArray = ones((shape(dataMatrix)[0],1))
   if threshIneq == 'lt':
       retArray[dataMatrix[:,dimen] <= threshVal] = -1.0
   else:
       retArray[dataMatrix[:,dimen] > threshVal] = -1.0
   return retArray
   

def buildStump(dataArr,classLabels,D):
   dataMatrix = mat(dataArr); labelMat = mat(classLabels).T
   m,n = shape(dataMatrix)
   numSteps = 10.0; bestStump = {}; bestClasEst = mat(zeros((m,1)))
   minError = inf #init error sum, to +infinity
   for i in range(n):#loop over all dimensions
       rangeMin = dataMatrix[:,i].min(); rangeMax = dataMatrix[:,i].max();
       stepSize = (rangeMax-rangeMin)/numSteps
       for j in range(-1,int(numSteps)+1):#loop over all range in current dimension
           for inequal in ['lt', 'gt']: #go over less than and greater than
               threshVal = (rangeMin + float(j) * stepSize)
               predictedVals = stumpClassify(dataMatrix,i,threshVal,inequal)#call stump classify with i, j, lessThan
               errArr = mat(ones((m,1)))
               errArr[predictedVals == labelMat] = 0
               weightedError = D.T*errArr  #calc total error multiplied by D
               print("split: dim %d, thresh %.2f, thresh ineqal: %s, the weighted error is %.3f" % (i, threshVal, inequal, weightedError))
               if weightedError < minError:
                   minError = weightedError
                   bestClasEst = predictedVals.copy()
                   bestStump['dim'] = i
                   bestStump['thresh'] = threshVal
                   bestStump['ineq'] = inequal
   return bestStump,minError,bestClasEst


def adaBoostTrainDS(dataArr,classLabels,numIt=40):
   weakClassArr = []
   m = shape(dataArr)[0]
   D = mat(ones((m,1))/m)   #init D to all equal
   aggClassEst = mat(zeros((m,1)))
   for i in range(numIt):
       bestStump,error,classEst = buildStump(dataArr,classLabels,D)#build Stump
       print("D:",D.T)
       alpha = float(0.5*log((1.0-error)/max(error,1e-16)))#calc alpha, throw in max(error,eps) to account for error=0
       bestStump['alpha'] = alpha  
       weakClassArr.append(bestStump)                  #store Stump Params in Array
       print("classEst: ",classEst.T)
       expon = multiply(-1*alpha*mat(classLabels).T,classEst) #exponent for D calc, getting messy
       D = multiply(D,exp(expon))                              #Calc New D for next iteration
       D = D/D.sum()
       #calc training error of all classifiers, if this is 0 quit for loop early (use break)
       aggClassEst += alpha*classEst
       print("aggClassEst: ",aggClassEst.T)
       aggErrors = multiply(sign(aggClassEst) != mat(classLabels).T,ones((m,1)))
       errorRate = aggErrors.sum()/m
       print("total error: ",errorRate)
       if errorRate == 0.0: break
   return weakClassArr

def adaClassify(datToClass,classifierArr):
   dataMatrix = mat(datToClass)#do stuff similar to last aggClassEst in adaBoostTrainDS
   m = shape(dataMatrix)[0]
   aggClassEst = mat(zeros((m,1)))
   for i in range(len(classifierArr)):
       classEst = stumpClassify(dataMatrix, classifierArr[i]['dim'],\
                                classifierArr[i]['thresh'],\
                                classifierArr[i]['ineq'])#call stump classify
       aggClassEst += classifierArr[i]['alpha']*classEst
       print(aggClassEst)
   return sign(aggClassEst)

def plotROC(predStrengths, classLabels):
   import matplotlib.pyplot as plt
   cur = (1.0,1.0) #cursor
   ySum = 0.0 #variable to calculate AUC
   numPosClas = sum(array(classLabels)==1.0)
   yStep = 1/float(numPosClas); xStep = 1/float(len(classLabels)-numPosClas)
   sortedIndicies = predStrengths.argsort()#get sorted index, it's reverse
   fig = plt.figure()
   fig.clf()
   ax = plt.subplot(111)
   #loop through all the values, drawing a line segment at each point
   for index in sortedIndicies.tolist()[0]:
       if classLabels[index] == 1.0:
           delX = 0; delY = yStep;
       else:
           delX = xStep; delY = 0;
           ySum += cur[1]
       #draw line from cur to (cur[0]-delX,cur[1]-delY)
       ax.plot([cur[0],cur[0]-delX],[cur[1],cur[1]-delY], c='b')
       cur = (cur[0]-delX,cur[1]-delY)
   ax.plot([0,1],[0,1],'b--')
   plt.xlabel('False positive rate'); plt.ylabel('True positive rate')
   plt.title('ROC curve for AdaBoost horse colic detection system')
   ax.axis([0,1,0,1])
   plt.show()
   print("the Area Under the Curve is: ",ySum*xStep)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值