機器學習實戰(5) AdaBoost元算法 基於python3

AdaBoost 元算法

我們可以將前面介紹的不同的分類器組合起來,這種組合結果被稱爲集成方法或者元方法。

bagging:基於數據隨機重抽樣的分類器構建方法

通過對一個數據集多次抽樣數據集個數的樣本,可能會出現一個樣本多次抽到,獲得S個數據集,將某個算法分別作用於每個數據集就得到了S個分類器,然後對多個分類器的結果採用多數投票原則。

boosting

boosting是通過集中關注被已有分類器錯分的那些數據來獲得新的分類器。boosting分類的結果是基於所有分類器的加權求和結果,而bagging的分類器權重是相等的。

訓練算法:基於錯誤提升分類器的性能

AdaBoost算法:訓練集的每個樣本會初始化一個相等的權重,構成向量D,首先訓練一個弱分類器計算分類器的錯誤率,然後在同一數據集上再次訓練弱分類器,第二次訓練將會重新調整每個樣本的權重,第一次訓練分對的樣本權重將會降低,分錯的樣本的權重將會提高。
爲了從所有弱分類器中得到最終的分類結果,AdaBoost爲每個分類器都基於錯誤率分配了一個權重值alpha。
ϵ = \epsilon = \frac{未正確分類的樣本數}{總樣本數}
α = 1 2 l o g ( 1 ϵ ϵ ) \alpha=\frac{1}{2}log(\frac{1-\epsilon}{\epsilon})

正確率、召回率及ROC曲線

關於正確率、召回率及ROC曲線的理論知識這裏不多介紹,咱們來看下代碼,我發現機器學習實戰這本書難點竟然都在畫圖上,作者畫圖的代碼有時候看來太詭異?
代碼主要分爲兩部分,索引列表的構造和畫圖,輸入爲預測的概率值數組和樣本真正的類別標籤,
1.通過argsort()函數輸出概率分佈的由小到大的index列表。
2.然後開始畫圖,這裏採用的兩點畫圖法,即確定一個點然後與上一個點左連接。首先確認初始點(1.0,1.0),爲什麼是該點,因爲我們假設把預測概率值最小的點以及大於最小值的點都預測爲類別1,這樣的話我們的正確率明顯是100%,因爲我們把所有的值都預測爲類別1了,而召回率也爲100%,召回率指的是所有的負向樣本中我們預測爲正向樣本的概率,所以也爲100%。
3.然後我們開始for循環,第一個點,繼續假設:該點以及大於該點概率都爲類別1,小於該點概率的爲類別2。然後我們檢驗該點的樣本真實值,如果爲1,我們該如何對正確率和召回率做變化呢?答案是正確率應該減掉一個ystep,而召回率不變。爲什麼變化的是正確率呢?這裏我們需要反向來看,當我們加上這第一個點之後,正確率應該增加,而召回率是不變的,那麼反向來看,正確率就應該減少,召回率依然是不變的。
至於AUC的計算就不難了,當縱向移動時,面積是不變的,橫向移動時我們計算橫向移動的y值,因爲橫向移動的xstep是固定的,最後只需要將加和的y值乘固定的xstep即可。後續我再把AdaBoost的代碼貼上來。

import matplotlib.pyplot as plt
def plotroc(pred,label):
    cur = (1.0,1.0)
    ysum = 0.0
    num = np.sum(label==1.0) #TP+FN
    ystep = 1/float(num) #TP/(TP+FN)
    xstep = 1/float(len(label)-num) #FP/(FP+TN)
    sortindicies = np.squeeze(pred).argsort()
    #print(sortindicies)
    plt.figure()
    #figure().clf()
    plt.subplot(111)
    for index in sortindicies.tolist():
        #print(index)
        if label[index] ==1.0:
            delX = 0
            delY = ystep
        else:
            delX = xstep
            delY = 0
            ysum +=cur[1]
        plt.plot([cur[0],cur[0]-delX],[cur[1],cur[1]-delY],c='b')#draw line from (cur[0],cur[1]) to (cur[0]-delX,cur[1]-delY)
        cur =(cur[0]-delX,cur[1]-delY)
    plt.plot([0,1],[0,1],'b--')
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.title('ROC')

結果圖: