其他分享
首页 > 其他分享> > 手撸AdaBoost

手撸AdaBoost

作者:互联网

AdaBoost代码实践

数学定义

决策树以及AdaBoost

代码实现

数据

序号12345678910
x0123456789
y111-1-1-1111-1
import numpy as np
import pandas as pd
pd.set_option("display.max_columns", 20)
pd.set_option("display.max_rows", 20)
pd.set_option("display.width", 2000)
pd.set_option("display.max_colwidth", 2000)


class G:
    """
    :param which_type, 0表示小于, 1表示大于
    """

    def __init__(self, threshold, which_type="<="):
        self.threshold = threshold
        self.which_type = which_type

    def __call__(self, x):
        if self.which_type == "<=":
            a = (x <= self.threshold) * 1
        elif self.which_type == ">=":
            a = (x >= self.threshold) * 1
        else:
            raise TypeError("类型错误, 必须是<= 或 >=")
        b = (a - 1) + a
        return b


class AdaBoostClassifier:
    def __init__(self, begin_w, x, y, m, threshold_candidate):
        self.m = m
        self.threshold_candidate = threshold_candidate
        self.D_list = []
        self.F_list = []
        self.begin_w = begin_w
        self.D_list.append(begin_w)
        self.x = x
        self.y = y

    def get_threshod_err(self, w):
        all = []
        for i in self.threshold_candidate:
            g_i_0 = G(i, "<=")
            g_i_1 = G(i, ">=")
            e_0 = np.sum((g_i_0(self.x) != self.y) * w)
            e_1 = np.sum((g_i_1(self.x) != self.y) * w)
            all.append((f"{i}_<=", e_0, g_i_0))
            all.append((f"{i}_>=", e_1, g_i_1))
        all = sorted(all, key=lambda x: x[1])
        return all[0]

    def get_alpha(self, e):
        return 0.5 * np.log((1 - e) / e)

    def get_next_weight(self, w, alpha, x, y, G_m):
        tmp = np.exp(-alpha * y * G_m(x)) * w
        return tmp / np.sum(tmp)

    def one_step(self, w):
        threshold_num, e, Gm = self.get_threshod_err(w)
        alpha = self.get_alpha(e)
        self.F_list.append((alpha, Gm, e))
        return self.get_next_weight(w, alpha, self.x, self.y, Gm)

    def fit(self):
        for i in range(self.m):
            w = self.one_step(self.D_list[i])
            self.D_list.append(w)
        return self.summary()

    def summary(self):
        df = pd.DataFrame({"w": [np.around(wi, 5) for wi in self.D_list[: -1]],
                           "alpha": [g[0] for g in self.F_list],
                           "threshold": [g[1].threshold for g in self.F_list],
                           "type": [g[1].which_type for g in self.F_list],
                           "err": [g[2] for g in self.F_list]})
        return df

    def predict(self, x):
        out = np.zeros_like(x, dtype=np.float32)
        for alpha, Gm, _ in self.F_list:
            out += alpha * Gm(x)
        # print(out)
        return 2 * (out > 0) - 1


def main():
    # x 值
    x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=np.int32)
    # y 值
    y = np.array([1, 1, 1, -1, -1, -1, 1, 1, 1, -1], dtype='i4')
    # 初始权重
    D1 = np.ones(10) * 0.1
    # 次数M
    m = 4
    # 阈值搜索空间
    threshold_candidate = np.array(range(1, 21, 2)) * 0.5
    # AdaBoost
    model = AdaBoostClassifier(D1, x, y, m, threshold_candidate)
    # 训练
    model.fit()
    # 查看训练结果
    print(model.summary())
    # 对x进行预测
    predict = model.predict(x)
    print(predict)
    # 将真实结果与预测结果对比
    print(predict == y)


if __name__ == '__main__':
    main()

                                                                                            w     alpha  threshold type       err
0                                          [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]  0.423649        2.5   <=  0.300000
1  [0.07143, 0.07143, 0.07143, 0.07143, 0.07143, 0.07143, 0.16667, 0.16667, 0.16667, 0.07143]  0.649641        8.5   <=  0.214286
2  [0.04545, 0.04545, 0.04545, 0.16667, 0.16667, 0.16667, 0.10606, 0.10606, 0.10606, 0.04545]  0.752039        5.5   >=  0.181818
3          [0.125, 0.125, 0.125, 0.10185, 0.10185, 0.10185, 0.06481, 0.06481, 0.06481, 0.125]  0.710693        2.5   <=  0.194444
[ 1  1  1 -1 -1 -1  1  1  1 -1]
[ True  True  True  True  True  True  True  True  True  True]

标签:0.1,self,list,threshold,AdaBoost,np,alpha
来源: https://blog.csdn.net/dahaiya/article/details/123542018