【Supervised Learning】 集成学习Ensemble Learning & Boosting 算法(python实现)

零、 Introduction

1.learn over a subset of datahtml

  • choose the subset uniformally randomly (均匀随机地选择子集)
  • apply some learning algorithm
  • 解决第一个问题 :Boosting 算法
    • 再也不随机选择样本,而是选择the samples we are not good at?
    • 寻找算法解决咱们当下不知道如何解决的问题——学习的意义
    • baic idea behind boosting : focus on the “hardest” examples
    • 2.how do you combine all of those rules of thumbs by saying?
      (如何合并凭经验获得的全部规则)
  • weighted Mean
  • Bagging 算法python

  • Keyword算法

  • emsembles are good
  • bagging is good
  • combing simple -> complex
  • boosting is really good
  • weak learner
  • errorspring

1、集成方法(Ensemble Method)

集成方法主要包括Bagging和Boosting两种方法。网络

  • Bagging方法

随机森林算法是基于Bagging思想的机器学习算法,在Bagging方法中,主要经过对训练数据集进行随机采样,以从新组合成不一样的数据集,利用弱学习算法对不一样的新数据集进行学习,获得一系列的预测结果,对这些预测结果作平均或者投票作出最终的预测。架构

  • AdaBoost算法

AdaBoost算法和GBDT(Gradient Boost Decision Tree,梯度提高决策树)算法是基于Boosting思想的机器学习算法。在Boosting思想中是经过对样本进行不一样的赋值,对错误学习的样本的权重设置的较大,这样,在后续的学习中集中处理难学的样本,最终获得一系列的预测结果,每一个预测结果有一个权重,较大的权重表示该预测效果较好。app

2、AdaBoost算法思想

  • “hardest examples”
  • “weighted mean ”

AdaBoost算法是基于Boosting思想的机器学习算法,其中AdaBoost是Adaptive Boosting的缩写,AdaBoost是一种迭代型的算法,其核心思想是针对同一个训练集训练不一样的学习算法,即弱学习算法,而后将这些弱学习算法集合起来,构造一个更强的最终学习算法。框架

为了构造出一个强的学习算法,首先须要选定一个弱学习算法,并利用同一个训练集不断训练弱学习算法,以提高弱学习算法的性能。在AdaBoost算法中,有两个权重,第一个数训练集中每一个样本有一个权重,称为样本权重,用向量\(D\)表示;另外一个是每个弱学习算法具备一个权重,用向量\(\alpha\)表示。假设有\(N\)个样本的训练集
\(\{(X_1,y_1),(X_2,y_2),\cdots,(X_n,y_n)\} \),初始时,设定每一个样本的权重是相等的,即\(\frac{1}{n}\),利用第一个弱学习算法\(h_1\)对其进行学习,学习完成后进行错误率\(\varepsilon\)的统计:dom

\[ \varepsilon = \frac{ error}{ all}\]机器学习

其中,\(error\)表示被错误分类的样本数目,\(all\)表示全部样本的数目。这样即可以利用错误率\(\varepsilon\)计算弱学习算法的权重\(\alpha _1\):

\[ \alpha_1 = \frac{1} {2} ln (\frac{1-\varepsilon}{\varepsilon})\]

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

其中,表示\(h_t(x_i) = y_i\)对第\(i\)个样本训练正确,\(h_t(x_i) \neq y_i\)表示对第\(i\)个样本训练错误。是一个\(Z_t\)归一化因子:\(Z_t = sum (D)\)

这样进行第二次的学习,当学习t轮后,获得了t个弱学习算法\({ h_1,\cdots,h_t}\)及其权重\({ \alpha_1,\cdots,\alpha_t}\)。对新的分类数据,分别计算t个弱分类器的输出\({ h_1(X),\cdots,h_t(X)}\),最终的AdaBoost算法的输出结果为:

\(H(X) = sign (\sum_{i=1}^t \alpha_i h_i( X ) )\)

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


3、AdaBoost算法流程

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

Boost 算法伪代码

  • Given training \({(x_i,y_i)} \) ,\(y_i \in {-1,+1}\)

  • For t = 1 to T
    • construct distribution \(D_t\)
    • find weak classifier \(h_t(x)\)

    with small error
    \( \epsilon_t = P_{D_{\scriptsize t}} [h_t(x_i) \neq y_i]\)

  • Output \( H_{final} \)


4、Adaboost之python实现

AdaBoost算法是一种具备很高精度的分类器,其实AdaBoost算法提供的是一种框架,在这种框架下,咱们可使用不一样的弱分类器,经过AdaBoost框架构建出强分类器。下面咱们使用单层决策树构建一个分类器处理以下的分类问题:

决策树算法主要有ID3,C4.5和CART,其中ID3和C4.5主要用于分类,CART能够解决回归问题。

#coding:UTF-8  
''''' 
Created on 2017年2月22日 
 
@author: P50
 
'''  
  
from numpy import *  
  
def loadSimpleData():  
    datMat = mat([[1., 2.1],  
                  [2., 1.1],  
                  [1.3, 1.],  
                  [1., 1.],  
                  [2., 1.]])  
    classLabels = mat([1.0, 1.0, -1.0, -1.0, 1.0])  
    return datMat, classLabels  
  
def singleStumpClassipy(dataMat, dim, threshold, thresholdIneq):  
    classMat = ones((shape(dataMat)[0], 1))  
    #根据thresholdIneq划分出不一样的类,在'-1'和'1'之间切换  
    if thresholdIneq == 'left':#在threshold左侧的为'-1'  
        classMat[dataMat[:, dim] <= threshold] = -1.0  
    else:  
        classMat[dataMat[:, dim] > threshold] = -1.0  
      
    return classMat  
  
def singleStump(dataArr, classLabels, D):  
    dataMat = mat(dataArr)  
    labelMat = mat(classLabels).T  
    m, n = shape(dataMat)  
    numSteps = 10.0  
    bestStump = {}  
    bestClasEst = zeros((m, 1))  
    minError = inf  
    for i in xrange(n):#对每个特征  
        #取第i列特征的最小值和最大值,以肯定步长  
        rangeMin = dataMat[:, i].min()  
        rangeMax = dataMat[:, i].max()  
        stepSize = (rangeMax - rangeMin) / numSteps  
        for j in xrange(-1, int(numSteps) + 1):  
            #不肯定是哪一个属于类'-1',哪一个属于类'1',分两种状况  
            for inequal in ['left', 'right']:  
                threshold = rangeMin + j * stepSize#获得每一个划分的阈值  
                predictionClass = singleStumpClassipy(dataMat, i, threshold, inequal)  
                errorMat = ones((m, 1))  
                errorMat[predictionClass == labelMat] = 0  
                weightedError = D.T * errorMat#D是每一个样本的权重  
                if weightedError < minError:  
                    minError = weightedError  
                    bestClasEst = predictionClass.copy()  
                    bestStump['dim'] = i  
                    bestStump['threshold'] = threshold  
                    bestStump['inequal'] = inequal  
      
    return bestStump, minError, bestClasEst  
  
def adaBoostTrain(dataArr, classLabels, G):  
    weakClassArr = []  
    m = shape(dataArr)[0]#样本个数 ,row 


    ### Numpy 之 Shape  ###

# 创建一个4×2的矩阵c
# >>> c = array([[1,1],[1,2],[1,3],[1,4]])  
# >>> c.shape  
# (4, 2)  
# >>> c.shape[0]  
# 4  
# >>> c.shape[1]  
# 2  
    ###  ###
    #初始化D,即每一个样本的权重均为1/n

    D = mat(ones((n, 1)) / m)    
    ### 
    # ones(3,3) 能够用来构造(3,3)全一矩阵
    aggClasEst = mat(zeros((m, 1)))  
      
    for i in xrange(G):#G表示的是迭代次数  
        bestStump, minError, bestClasEst = singleStump(dataArr, classLabels, D)  
        print 'D:', D.T  
        #计算分类器的权重  
        alpha = float(0.5 * log((1.0 - minError) / max(minError, 1e-16)))  
        bestStump['alpha'] = alpha  
        weakClassArr.append(bestStump)  
        print 'bestClasEst:', bestClasEst.T  
          
        #从新计算每一个样本的权重D  
        expon = multiply(-1 * alpha * mat(classLabels).T, bestClasEst)  
        D = multiply(D, exp(expon))  
        D = D / D.sum()  
          
        aggClasEst += alpha * bestClasEst  
        print 'aggClasEst:', aggClasEst  
        aggErrors = multiply(sign(aggClasEst) != mat(classLabels).T, ones((m, 1)))  
        errorRate = aggErrors.sum() / m  
        print 'total error:', errorRate  
        if errorRate == 0.0:  
            break  
    return weakClassArr  
  
def adaBoostClassify(testData, weakClassify):  
    dataMat = mat(testData)  
    m = shape(dataMat)[0]  
    aggClassEst = mat(zeros((m, 1)))  
    for i in xrange(len(weakClassify)):#weakClassify是一个列表  
        classEst = singleStumpClassipy(dataMat, weakClassify[i]['dim'], weakClassify[i]['threshold'], weakClassify[i]['inequal'])  
        aggClassEst += weakClassify[i]['alpha'] * classEst  
        print aggClassEst  
    return sign(aggClassEst)  
              
if __name__ == '__main__':  
    datMat, classLabels = loadSimpleData()  
    weakClassArr = adaBoostTrain(datMat, classLabels, 30)  
    print "weakClassArr:", weakClassArr  
    #test  
    result = adaBoostClassify([1, 1], weakClassArr)  
    print result

OUTPUT:

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}]

[[-0.69314718]]

[[-1.66610226]]

[[-0.77022252]]

[[-1.]]

5、思考

5.1 回答Introduction中的问题

(i)每一次训练如何选择不一样分布?
     答:给先前学习规则分类错误的样本更高的权重,正确分类样本权重下降,
     使弱学习器可以更集中解决这些“困难”的样本。
     简单的来讲,分类正确的样本咱们能够不用再分了,错误分类的才是主要敌人。
 (ii)如何将产生的众多弱规则整合成一个规则?
     答:按照它们的预测结果经过‘投票法’产生,少数服从多数。

5.2 为何 Boosting 算法 的效果 这么好?

分布:让上一次被错误分类的样本 愈来愈重要 (增长权重)

偏差不会上升——每次迭代一定比随机猜想更好(即每次错误率必小于随机几率0.5)

逆向推理:什么状况下效果很差

还有大量样本分类错误

5.3 Boosting & 过拟合

boosting 每每不会过拟合,但这种状况仍然有可能会发生

回顾 SVM

solution : try to focus on maximum margin classfiers
(集中在最大边缘分类器上)

large margins tend to minimize over fitting

Boosting

+error
+confidence (置信度):
general definition:how strongly you believe in a particular answer that you given.

in the boosting case: h_final

boosting 每每不会过拟合,但这种状况仍然有可能会发生

  • possible overfitting case:
    1.□ 进行 Boosting 的弱学习方法是含有屡次网络和多个节点的神经网络

若boosting调用 ANN算法时发生过拟合 且返回值没有偏差,all the examples will have equal weight.

when you go through the loop again,you will just call the same learner,which will use the same neural network,and will return the same neural network.

每次调用学习器时,你都会获得零训练偏差。但所得的神经网络也是相同的。就此陷入恶性循环。

小结:若是你的基础学习器自己产生了过拟合,那么Boosting很难克服这一点。

  1. the case of pink noise

pink noise just means uniform noise.

P.S. white noise is Gaussian noise
pink noise is uniform noise.

*不是过拟合的缘由:

□ Boosting 训练的时间过长(极限思想,趋向于分离样本)

5.4 加权组合 回到最初的起点

经过简单组合 得到更复琐事物


参考连接:

http://blog.csdn.net/gamer_gyt/article/details/51372309

http://discussions.youdaxue.com/t/boosting/45579

http://blog.csdn.net/google19890102/article/details/46507387

https://www.cnblogs.com/csyuan/p/6537255.html

http://blog.sina.com.cn/s/blog_13ec1876a0102xboj.html

http://blog.csdn.net/google19890102/article/details/46376603

参考论文

1.Introduction to Boosting By Udacity
2.The Boosting Approach to Machine Learning By AT&T Labs Research Shannon Laborator

相关文章
相关标签/搜索