1. 集成学习概述

1.1. 定义

集成学习(Ensemble learning)便是将若干个弱分类器通过必定的战略组合之后产生一个强分类器。 弱分类器(Weak Classifier)指的便是那些分类精确率只比随机猜想略好一点的分类器,而强分类器( Strong Classifier)的分类精确率会高许多。这儿的”强”&”弱”是相对的。某些书中也会把弱分类器称 为“基分类器”。

机器学习算法: AdaBoost 详解

目前集成学习算法的流派主要有两种:

  • bagging
  • boosting

1.2. bagging

装袋(bagging)又称自主聚集(bootstrap aggregating),是一种依据均匀概率散布从数据会集重复 抽样(有放回的)的技能。每个新数据集和原始数据集的巨细持平。由于新数据会集的每个样本都是从 原始数据会集有放回的随机抽样出来的,所以新数据会集或许有重复的值,而原始数据会集的某些样本 或许根本就没出现在新数据会集。

bagging办法的流程,如下图所示:

机器学习算法: AdaBoost 详解

  • 有放回的随机抽样:

自主采样法(Bootstap sampling),也便是说关于m个样本的原始数据集,每次 随机选取一个样本放入采样集,然后把这个样本重新放回原数据会集,然后再进行下一个样本的随机抽 样,直到一个采样会集的数量到达m,这样一个采样集就构建好了,然后咱们能够重复这个进程,生成 n个这样的采样集。也便是说,终究形成的采样集,每个采样会集的样本或许是重复的,也或许原数据 会集的某些样本根本就没抽到,而且每个采样会集的样本散布或许都不相同。

依据有放回的随机抽样构造的n个采样集,咱们就能够对它们别离进行练习,得到n个弱分类器,然后根 据每个弱分类器回来的成果,咱们能够选用必定的组合战略得到咱们终究需要的强分类器。

bagging办法的代表算法是随机森林,精确的来说,随机森林是bagging的一个特化进阶版,所谓的特 化是因为随机森林的弱学习器都是决议计划树。所谓的进阶是随机森林在bagging的样本随机采样基础上, 又加上了特征的随机挑选,其基本思想没有脱离bagging的范畴。

1.3. boosting

boosting是一个迭代的进程,用来自适应地改变练习样本的散布,使得弱分类器聚集到那些很难分类的 样本上。它的做法是给每一个练习样本赋予一个权重,在每一轮练习结束时自动地调整权重。

boosting办法的流程,如下图所示:

机器学习算法: AdaBoost 详解

boosting办法的代表算法有Adaboost、GBDT、XGBoost算法

1.4. 结合战略

1.4.1. 均匀法

关于数值类的回归猜测问题,一般运用的结合战略是均匀法,也便是说,关于若干个弱学习器的输出进 行均匀得到终究的猜测输出。

假定咱们终究得到的n个弱分类器为

机器学习算法: AdaBoost 详解

最简略的均匀是算术均匀,也便是说终究猜测是

机器学习算法: AdaBoost 详解

假如每个弱分类器有一个权重w,则终究猜测是

机器学习算法: AdaBoost 详解

1.4.2. 投票法

关于分类问题的猜测,咱们一般运用的是投票法。假定咱们的猜测类别是

机器学习算法: AdaBoost 详解

关于恣意一个猜测样本x,咱们的n个弱学习器的猜测成果别离是

机器学习算法: AdaBoost 详解

最简略的投票法是相对多数投票法,也便是咱们常说的少数服从多数,也便是n个弱学习器的对样本x的 猜测成果中,数量最多的类别 为终究的分类类别。假如不止一个类别取得最高票,则随机挑选一个做 终究类别。

略微杂乱的投票法是绝对多数投票法,也便是咱们常说的要票过半数。在相对多数投票法的基础上,不 光要求取得最高票,还要求票过半数。否则会回绝猜测。

愈加杂乱的是加权投票法,和加权均匀法相同,每个弱学习器的分类票数要乘以一个权重,终究将各个 类别的加权票数求和,最大的值对应的类别为终究类别。

1.4.3. 学习法

前两种办法都是对弱学习器的成果做均匀或许投票,相对比较简略,可是或许学习差错较大,所以就有 了学习法这种办法,关于学习法,代表办法是stacking,当运用stacking的结合战略时, 咱们不是对弱 学习器的成果做简略的逻辑处理,而是再加上一层学习器,也便是说,咱们将练习集弱学习器的学习结 果作为输入,将练习集的输出作为输出,重新练习一个学习器来得到终究成果。

在这种情况下,咱们将弱学习器称为初级学习器,将用于结合的学习器称为次级学习器。关于测试集, 咱们首先用初级学习器猜测一次,得到次级学习器的输入样本,再用次级学习器猜测一次,得到终究的 猜测成果。

2. AdaBoost

Adaboost是adaptive boosting(自适应boosting)的缩写。算法步骤如下:

机器学习算法: AdaBoost 详解

2.1. 核算样本权重

赋予练习会集每个样本一个权重,构成权重向量D,将权重向量D初始化持平值。设定咱们有m个样本,每个样本的权重都持平,则权重为

2.2. 核算错误率

在练习集上练习出一个弱分类器,并核算分类器的错误率:

机器学习算法: AdaBoost 详解

2.3. 核算弱分离器权重

为当前分类器赋予权重值alpha,则alpha核算公式为:

机器学习算法: AdaBoost 详解

2.4. 调整权重值

依据上一次练习成果,调整权重值(上一次分对的权重下降,分错的权重添加

假如第i个样本被正确分类,则该样本权重更改为:

机器学习算法: AdaBoost 详解

假如第i个样本被分错,则该样本权重更改为:

机器学习算法: AdaBoost 详解

把上面两个公式汇整成一个:

机器学习算法: AdaBoost 详解

之后,在同一数据集上再一次练习弱分类器,然后循环上述进程,直到练习错误率为0,或许弱分类器 的数目到达指定值。

2.5. 成果

循环结束后,咱们能够得到咱们的强分类器的猜测成果:

机器学习算法: AdaBoost 详解

3. 依据单层决议计划树构建弱分类器

单层决议计划树(decision stump)也称决议计划树桩,是一种简略的决议计划树。咱们已经讲过决议计划树的相 关原理了,接下来咱们一起来构建一个单层决议计划树,它仅仅依据单个特征来做决议计划。由于这棵树只有一 次分裂进程,因此它实际上便是一个树桩。

3.1. 构建数据集

  • 咱们先构建一个简略数据集来确保咱们写出的函数能够正常运转。
import pandas as pd
import numpy as np
# 取得特征矩阵和标签矩阵
def get_Mat(path):
    dataSet = pd.read_table(path,header = None)
    xMat = np.mat(dataSet.iloc[:,:-1].values)
    yMat = np.mat(dataSet.iloc[:,-1].values).T
    return xMat,yMat
xMat,yMat = get_Mat('simpdata.txt')
  • 构建数据可视化函数,并运转检查数据散布
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['simhei']
%matplotlib inline
# 数据集可视化函数
def showPlot(xMat,yMat):
    x=np.array(xMat[:,0])
    y=np.array(xMat[:,1])
    label = np.array(yMat)
    plt.scatter(x,y,c=label)
    plt.title('单层决议计划树测试数据')
    plt.show()
showPlot(xMat,yMat)

机器学习算法: AdaBoost 详解

3.2. 构建单层决议计划树

咱们会树立两个函数来完成咱们的单层决议计划树:

第一个函数用来测试是否有某个值小于或许大于咱们正在测试的阈值。

"""
函数功用:单层决议计划树分类函数
参数阐明:
    xMat: 特征矩阵
    i: 第i列,也便是第几个特征
    Q: 阈值
    S: 标志
回来:
	re: 分类成果
"""
def Classify0(xMat,i,Q,S):
    re = np.ones((xMat.shape[0],1)) # 初始化re为1
    if S == 'lt':
    	re[xMat[:,i] <= Q] = -1 # 假如小于阈值,则赋值为-1
    else:
    	re[xMat[:,i] > Q] = -1 # 假如大于阈值,则赋值为-1
    return re

第二个函数略微杂乱一些,会在一个加权数据会集循环,并找到具有最低错误率的单层决议计划树

"""
函数功用:找到数据集上最佳的单层决议计划树
参数阐明:
    xMat:特征矩阵
    yMat:标签矩阵
    D:样本权重
回来:
    bestStump:最佳单层决议计划树信息
    minE:最小差错
    bestClas:最佳的分类成果
"""
def get_Stump(xMat,yMat,D):
    m,n = xMat.shape # m为样本个数,n为特征数
    Steps = 10 # 初始化一个步数
    bestStump = {} # 用字典方法来储存树桩信息
    bestClas = np.mat(np.zeros((m,1))) # 初始化分类成果为1
    minE = np.inf # 最小差错初始化为正无穷大
    for i in range(n): # 遍历所有特征
        Min = xMat[:,i].min() # 找到特征中最小值
        Max = xMat[:,i].max() # 找到特征中最大值
        stepSize = (Max - Min) / Steps # 核算步长
        for j in range(-1, int(Steps)+1):
            for S in ['lt', 'gt']: # 大于和小于的情况,均遍历。lt:less than,gt:greater than
                Q = (Min + j * stepSize) # 核算阈值
                re = Classify0(xMat, i, Q, S) # 核算分类成果
                err = np.mat(np.ones((m,1))) # 初始化差错矩阵
                err[re == yMat] = 0 # 分类正确的,赋值为0
                eca = D.T * err # 核算差错
                # print(f'切分特征: {i}, 阈值:{np.round(Q,2)}, 标志:{S}, 权重差错:{np.round(eca,3)}')
                if eca < minE: # 找到差错最小的分类方法
                minE = eca
                bestClas = re.copy()
                bestStump['特征列'] = i
                bestStump['阈值'] = Q
                bestStump['标志'] = S
    return bestStump,minE,bestClas

测试函数并运转检查成果:

m = xMat.shape[0]
D = np.mat(np.ones((m, 1)) / m) # 初始化样本权重(每个样本权重持平)
bestStump,minE,bestClas= get_Stump(xMat,yMat,D)

4. AdaBoost代码

用python代码来完成完整版AdaBoost算法

"""
函数功用:依据单层决议计划树的AdaBoost练习进程
参数阐明:
    xMat:特征矩阵
    yMat:标签矩阵
    maxC:最大迭代次数
回来:
    weakClass:弱分类器信息
    aggClass:类别估计值(其实便是更改了标签的估计值)
"""
def Ada_train(xMat, yMat, maxC = 40):
    weakClass = []
    m = xMat.shape[0]
    D = np.mat(np.ones((m, 1)) / m) # 初始化权重
    aggClass = np.mat(np.zeros((m,1)))
    for i in range(maxC):
        Stump, error, bestClas = get_Stump(xMat, yMat,D) # 构建单层决议计划树
        # print(f"D:{D.T}")
        alpha=float(0.5 * np.log((1 - error) / max(error, 1e-16))) # 核算弱分类器权重alpha
        Stump['alpha'] = np.round(alpha,2) # 存储弱学习算法权重,保留两位小数
        weakClass.append(Stump) # 存储单层决议计划树
        # print("bestClas: ", bestClas.T)
        expon = np.multiply(-1 * alpha *yMat, bestClas) # 核算e的指数项
        D = np.multiply(D, np.exp(expon))
        D = D / D.sum() # 依据样本权重公式,更新样本权重
        aggClass += alpha * bestClas #更新累计类别估计值
        # print(f"aggClass: {aggClass.T}" )
        aggErr = np.multiply(np.sign(aggClass) != yMat, np.ones((m,1)))# 核算差错
        errRate = aggErr.sum() / m
        # print(f"分类错误率: {errRate}")
        if errRate == 0: break # 差错为0,退出循环
    return weakClass, aggClass
  • 运转函数,检查成果:
weakClass, aggClass =Ada_train(xMat, yMat, maxC = 40)
weakClass
aggClass

5. 依据AdaBoost的分类

这儿咱们运用弱分类器的加权求和来核算终究的成果。

"""
函数功用:AdaBoost分类函数
参数阐明:
    data: 待分类样例
    classifys:练习好的分类器
回来:
	分类成果
"""
def AdaClassify(data,weakClass):
    dataMat = np.mat(data)
    m = dataMat.shape[0]
    aggClass = np.mat(np.zeros((m,1)))
    for i in range(len(weakClass)): # 遍历所有分类器,进行分类
        classEst = Classify0(dataMat,
        weakClass[i]['特征列'],
        weakClass[i]['阈值'],
        weakClass[i]['标志'])
        aggClass += weakClass[i]['alpha'] * classEst
        # print(aggClass)
    return np.sign(aggClass)
  • 成果
AdaClassify([0,0],weakClass)

本文由mdnice多渠道发布