Adaboost原理及简单的Python实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013859301/article/details/79483126

原理

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.])

对比书上给出的结果可知代码完全正确。

猜你喜欢

转载自blog.csdn.net/u013859301/article/details/79483126
今日推荐