【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

相關文章
相關標籤/搜索