1. 程式人生 > >Adaboost原理及簡單的Python實現

Adaboost原理及簡單的Python實現

原理

Adaboost原理方面網上早已汗牛充棟,李航的《統計學習方法》中寫的簡單易懂,這裡直接搬過來。
這裡寫圖片描述
這裡寫圖片描述
即每次訓練一個弱分類器,之後為每個弱分類器分錯的樣本增大權重,為每個分對的樣本減少權重,然後訓練新的分類器。最後對分類器進行加權平均。

實現

這裡直接採用李航書中的例子。
這裡寫圖片描述

 閾值弱分類器

實現閾值弱分類器時要注意,這裡的分類器除了含有一個閾值,還應有一方向。簡單來說就是下面二圖(這裡一開始困惑了我好久)
這裡寫圖片描述
這裡寫圖片描述
上面二圖分別為例題中第一、三次迭代訓練出的最佳分類器。很明顯,兩個分類器的方向不同。這裡很容易理解,因為若方向相同,則越大的數越傾向於正例,越小的數越傾向於負例,但資料集中顯然沒有這種先驗關係。

Adaboost所用的分類器還有一特點,即必須能夠根據權重來調整訓練目標。因此在演算法中要有所體現。最終實現如下:

class ThreshClassifier():
    def __init__(self):
        self.v = 0
        self.direction = 0
    def train(self, x, y, w):
        loss = 0
        min_loss = 1
        for v in np.arange(0.5,10,1):
            for direction in [0,1]:
                if
direction == 0: mis = (((x < v) - 0.5)*2 != y) else: mis = (((x > v) - 0.5)*2 != y) loss = sum(mis * w) if loss < min_loss: min_loss = loss self.v = v self.direction = direction return
min_loss def predict(self, x): if self.direction == 0: return ((x < self.v) - 0.5)*2 else: return ((x > self.v) - 0.5)*2

Adaboost實現

實現Adaboost只要按照書中的方法實現就好。程式碼如下:

class AdaBoost():
    def __init__(self, classifier = ThreshClassifier):
        self.classifier = classifier
        self.classifiers = []
        self.alphas = []
    def train(self, x, y):        
        n = x.shape[0]
        M = 3
        w_m = np.array([1 / n] * n)
        for m in range(M):
            classifier_m = self.classifier()
            e_m = classifier_m.train(x, y, w_m)
            print(e_m)
            alpha_m = 1 / 2 * np.log((1-e_m)/e_m)
            w_m = w_m * np.exp(-alpha_m*y*classifier_m.predict(x))
            z_m = np.sum(w_m)
            w_m = w_m / z_m
            print(w_m)
            self.classifiers.append(classifier_m)
            self.alphas.append(alpha_m)
    def predict(self, x):
        n = x.shape[0]
        results = np.zeros(n)
        for alpha, classifier in zip(self.alphas, self.classifiers):
            results += alpha * classifier.predict(x)
        return ((results > 0) - 0.5) * 2

x = [0,1,2,3,4,5,6,7,8,9]
y = [1,1,1,-1,-1,-1,1,1,1,-1]
x = np.array(x)
y = np.array(y)       
ab = AdaBoost()
ab.train(x, y)
ab.predict(x)

執行結果為

0.30000000000000004
[0.07142857 0.07142857 0.07142857 0.07142857 0.07142857 0.07142857
 0.16666667 0.16666667 0.16666667 0.07142857]
0.21428571428571427
[0.04545455 0.04545455 0.04545455 0.16666667 0.16666667 0.16666667
 0.10606061 0.10606061 0.10606061 0.04545455]
0.18181818181818185
[0.125      0.125      0.125      0.10185185 0.10185185 0.10185185
 0.06481481 0.06481481 0.06481481 0.125     ]
Out[133]:
array([ 1.,  1.,  1., -1., -1., -1.,  1.,  1.,  1., -1.])

對比書上給出的結果可知程式碼完全正確。