一、集成学习与Boosting

集成学习是指将多个弱学习器组合成一个强学习器,这个强学习器能取所有弱学习器之所长,达到相对的最佳性能的一种学习范式。

集成学习主要包括Boosting和Bagging两种学习框架。Boosting是一种将弱学习器提升为强学习器的算法,所以也叫提升算法。

以分类问题为例,给定一个训练数据集,训练弱分类器要比训练强分类器相对容易很多,从第一个弱分类器开始,Boosting通过训练多个弱分类器,并在训练过程中不断改变训练样本的概率分布,使得每次训练时算法都会更加关注上一个弱分类器的错误。通过组合多个这样的弱分类器,便可以获得一个接近相对完美的强分类器。boosting方法的核心理念在于博采众长,正所谓"三个臭皮匠,顶个诸葛亮",这也使得boosting方法要好于大多数单模型算法。

二、AdaBoost模型

AdaBoost基本原理

AdaBoost的全称为Adaptive Boosting,可以翻译为自适应提升算法。(提升方法是将弱学习算法提升为强学习算法的统计学习方法。)

AdaBoost是一种通过改变训练样本权重来学习多个弱分类器并线性组合成强学习器的Boosting算法。

Boosting要解决两个关键问题:

  • 一是在训练过程中如何改变训练样本的权重或者概率分布。
  • 二是如何将多个弱分类器组合成一个强分类器。

针对这两个问题,Adaboost是做法非常朴素,第一个就是提高前一轮被弱分类器分类错误的样本的权重、而降低分类正确的样本权重;第二则是对多个弱分类器进行线性组合,提高分类效果好的弱分类器权重,减小分类误差率大的弱分类器权重。

给定训练数据集\(D={(x_1,y_1),(x_2,y_2),⋯,(x_N,y_N)}\),其中\(x_i∈χ⊆R^n,y_i∈Y={−1,+1}\),AdaBoost训练算法如下。

  1. 初始化训练数据样本的权值分布,即为每个训练样本分配一个初始权值:$D_1=(w_{11},⋯,w_{1i},⋯w_{1N}), w_{1i}=1/N, i=1, 2,⋯,N $

  2. 对于\(t=1, 2,⋯,T\),分别执行以下步骤。

  • 对包含权值分布\(D_m\)的训练数据集进行训练并得到弱分类器\(G_t(x)\)。

  • 计算\(G_t(x)\)在当前加权训练集上的分类误差率\(ϵ_t\):

    \(ϵ_t=P(G_t(x_i)≠y_i)=∑_{i=1}^Nw_{ti}I(G_t(x_i)≠y_i)\)

  • 根据分类误差率\(ϵ_t\)计算当前弱分类器的权重系数\(α_t\):

    \(α_t=1/2 log{(1−ϵ_t)/ϵ_t}\)

  • 调整训练数据集的权值分布:

    \(D_{t+1}=(w_{t+1},1,⋯,w_{t+1},i,⋯w_{t+1},N)\)

    \(w_{t+1},i=w_ti/{Z_t} exp(−α_t y_i G_t(x_i))\)

    分类正确的权重下降,分类错误权重上升

    其中\(Z_t\)为归一化因子,\(Z_t=∑_{i=1}^N w_{ti}exp(−α_t y_i G_t(x_i))\)。

  1. 最后构建T个弱分类器的线性组合:

    \(f(x)=∑_{i=1}^T α_t G_t(x)\)

最终的AdaBoost强分类器可以写为:

\(G(x)=sign(f(x))=sign(∑_{i=1}^N α_t G_t(x))\)

在弱分类器权重系数计算过程中,当弱分类器的分类误差率\(ϵ_t≤1/2\)时,\(α_t≥0\),且\(α_t\)随着\(ϵ_t\)的减小而变大,这也正是弱分类器权重系数计算公式的设计思想,它能够使得分类误差率较低的分类器有较大的权重系数。AdaBoost训练样本权值分布可以写为:

\[w_{t+1, i}=\left\{\begin{array}{ll}
\frac{w_{t i}}{Z_{t}} e^{-\alpha_{t}}, & G_{t}\left(x_{i}\right)=y_{i} \\
\frac{w_{t i}}{Z_{t}} e^{\alpha_{t}}, & G_{t}\left(x_{i}\right) \neq y_{i}
\end{array}\right.\]

当样本被弱分类器正确分类时,对应样本的权重变小;当样本被弱分类器错误分类时,对应样本的权重变大。相比之外,错误分类样本的权重扩大了\(e^{2α_t}\)倍,这就使得在下一轮训练中,算法将更加关注这些误分类的样本。

视频讲解:

简博士

https://www.bilibili.com/video/BV18g41197rC

https://www.bilibili.com/video/BV1pF411F7CY/

前向分步算法

从机器学习三要素(模型、策略、算法)的角度来看,AdaBoost可以看作为以加性模型为模型、指数函数为损失函数和前向分步为算法的分类学习算法。

所谓加性模型(additive model),就是由多个基模型求和的形式构造起来的。加性模型可以表示为:

\(f(x)=∑_{t=1}^T α_t b(x;γ_t)\)

其中\(b(x;γ_t)\)为基模型,\(γ_t\)为基模型参数,\(α_t\)为基模型系数,可知f(x)是由T个基模型求和的加性模型。

给定训练数据集和损失函数的条件下,加性模型的目标函数为如下最小化损失函数:

\(\min _{\alpha_{t}, \gamma_{t}} \sum_{i=1}^{N} L\left(y_{i}, \sum_{t=1}^{T} \alpha_{t} b\left(x_{i} ; \gamma_{t}\right)\right)\)

针对上式这样一个较为复杂的优化问题,可以采用前向分步算法进行求解。其基本思路如下:针对加性模型的特点,从前往后每次只优化一个基模型的参数,每一步优化叠加之后便可逐步逼近目标函数。每一步优化的表达式如下式所示:

\(\min _{α,γ} ∑_{i=1}^N L(y_i,αb(x_i;γ))\)

给定训练数据集\(D={(x_1,y_1),(x_2,y_2),⋯,(x_N,y_N)}\),其中\(x_i∈χ⊆R^n,y_i∈Y=\{−1,+1\}\),前向分步算法求解过程如下。

初始化模型\(f_0(x)=0\)。

对于t=1, 2,⋯,T,分别执行以下操作。

以\(α_t\)和\(γ_t\)为优化参数,最小化目标损失函数:

$(α_t,γ_t)=argmin_{α,γ}∑_{i=1}^N L(y_i,f_{t−1}(x_i)+αb(x_i;γ)) $

更新加性模型:

\(f_t(x)=f_{t−1}(x)+α_tb(x;γ_t)\)

可得到最后的加性模型为:

\(f(x)=f_T(x)=∑_{t=1}^Tα_tb(x;γ_t)\)

从前向分步算法的角度来理解AdaBoost,可以将AdaBoost看作前向分步算法的特例,这时加性模型是以分类器为基模型、以指数函数为损失函数的最优化问题。假设经过t−1次前向分步迭代后已经得到\(f_{t−1}(x)\),第t次迭代可以得到第t个基模型的权重系数\(α_t\)、第t个基模型\(G_t(x)\)和t轮迭代后的加性模型\(f_t(x)\)。优化目标是使

\(f_t(x)\)在给定训练数据集D上的指数损失最小化,有:

\(\left(\alpha_{t}, G_{t}(x)\right)=\underset{\alpha, G}{\operatorname{argmin}} \sum_{i=1}^{N} \exp \left(-y_{i}\left(f_{t-1}\left(x_{i}\right)+\alpha G\left(x_{i}\right)\right)\right)\)

求解上式的最小化指数损失即可得到AdaBoost的优化参数。

三、AdaBoost算法实现

先定义一个基分类器

### 定义决策树桩类
### 作为Adaboost弱分类器
class DecisionStump():
def __init__(self):
# 基于划分阈值决定样本分类为1还是-1
self.label = 1
# 特征索引
self.feature_index = None
# 特征划分阈值
self.threshold = None
# 指示分类准确率的值
self.alpha = None

定义AdaBoost算法类

### 定义AdaBoost算法类
class Adaboost:
# 弱分类器个数
def __init__(self, n_estimators=5):
self.n_estimators = n_estimators # Adaboost拟合算法
def fit(self, X, y):
m, n = X.shape
# (1) 初始化权重分布为均匀分布 1/N
w = np.full(m, (1/m))
# 处初始化基分类器列表
self.estimators = []
# (2) for m in (1,2,...,M)
for _ in range(self.n_estimators):
# (2.a) 训练一个弱分类器:决策树桩
estimator = DecisionStump()
# 设定一个最小化误差
min_error = float('inf')
# 遍历数据集特征,根据最小分类误差率选择最优划分特征
for i in range(n):
# 获取特征值
values = np.expand_dims(X[:, i], axis=1)
# 特征取值去重
unique_values = np.unique(values)
# 尝试将每一个特征值作为分类阈值
for threshold in unique_values:
p = 1
# 初始化所有预测值为1
pred = np.ones(np.shape(y))
# 小于分类阈值的预测值为-1
pred[X[:, i] < threshold] = -1
# 2.b 计算误差率
error = sum(w[y != pred]) # 如果分类误差大于0.5,则进行正负预测翻转
# 例如 error = 0.6 => (1 - error) = 0.4
if error > 0.5:
error = 1 - error
p = -1 # 一旦获得最小误差则保存相关参数配置
if error < min_error:
estimator.label = p
estimator.threshold = threshold
estimator.feature_index = i
min_error = error # 2.c 计算基分类器的权重
estimator.alpha = 0.5 * np.log((1.0 - min_error) / (min_error + 1e-9))
# 初始化所有预测值为1
preds = np.ones(np.shape(y))
# 获取所有小于阈值的负类索引
negative_idx = (estimator.label * X[:, estimator.feature_index] < estimator.label * estimator.threshold)
# 将负类设为 '-1'
preds[negative_idx] = -1
# 2.d 更新样本权重
w *= np.exp(-estimator.alpha * y * preds)
w /= np.sum(w) # 保存该弱分类器
self.estimators.append(estimator) # 定义预测函数
def predict(self, X):
m = len(X)
y_pred = np.zeros((m, 1))
# 计算每个弱分类器的预测值
for estimator in self.estimators:
# 初始化所有预测值为1
predictions = np.ones(np.shape(y_pred))
# 获取所有小于阈值的负类索引
negative_idx = (estimator.label * X[:, estimator.feature_index] < estimator.label * estimator.threshold)
# 将负类设为 '-1'
predictions[negative_idx] = -1
# 2.e 对每个弱分类器的预测结果进行加权
y_pred += estimator.alpha * predictions # 返回最终预测结果
y_pred = np.sign(y_pred).flatten()
return y_pred

数据测试

from sklearn.model_selection import train_test_split
# 导入sklearn模拟二分类数据生成模块
from sklearn.datasets._samples_generator import make_blobs
# 生成模拟二分类数据集
X, y = make_blobs(n_samples=150, n_features=2, centers=2,
cluster_std=1.2, random_state=40)
# 将标签转换为1/-1
y_ = y.copy()
y_[y_==0] = -1
y_ = y_.astype(float)
# 训练/测试数据集划分
X_train, X_test, y_train, y_test = train_test_split(X, y_,
test_size=0.3, random_state=43)
# 设置颜色参数
colors = {0:'r', 1:'g'}
# 绘制二分类数据集的散点图
plt.scatter(X[:,0], X[:,1], marker='o', c=pd.Series(y).map(colors))
plt.show();

自定义Adaboost模型测试

# 导入sklearn准确率计算函数
from sklearn.metrics import accuracy_score
# 创建Adaboost模型实例
clf = Adaboost(n_estimators=5)
# 模型拟合
clf.fit(X_train, y_train)
# 模型预测
y_pred = clf.predict(X_test)
# 计算模型预测准确率
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy of AdaBoost by numpy:", accuracy)

Accuracy of AdaBoost by numpy: 0.9777777777777777

导入sklearn adaboost分类器测试

from sklearn.ensemble import AdaBoostClassifier
# 创建Adaboost模型实例
clf_ = AdaBoostClassifier(n_estimators=5, random_state=0)
# 模型拟合
clf_.fit(X_train, y_train)
# 模型预测
y_pred_ = clf_.predict(X_test)
# 计算模型预测准确率
accuracy = accuracy_score(y_test, y_pred_)
print("Accuracy of AdaBoost by sklearn:", accuracy)

Accuracy of AdaBoost by sklearn: 0.9777777777777777

监督学习集成模型——AdaBoost的更多相关文章

  1. 吴裕雄 python 机器学习——集成学习AdaBoost算法回归模型

    import numpy as np import matplotlib.pyplot as plt from sklearn import datasets,ensemble from sklear ...

  2. 吴裕雄 python 机器学习——集成学习AdaBoost算法分类模型

    import numpy as np import matplotlib.pyplot as plt from sklearn import datasets,ensemble from sklear ...

  3. Python机器学习(基础篇---监督学习(集成模型))

    集成模型 集成分类模型是综合考量多个分类器的预测结果,从而做出决策. 综合考量的方式大体分为两种: 1.利用相同的训练数据同时搭建多个独立的分类模型,然后通过投票的方式,以少数服从多数的原则作出最终的 ...

  4. DeepMind提出空间语言集成模型SLIM,有效编码自然语言的空间关系

    前不久,DeepMind 提出生成查询网络 GQN,具备从 2D 画面到 3D 空间的转换能力.近日.DeepMind 基于 GQN 提出一种新模型.可以捕捉空间关系的语义(如 behind.left ...

  5. 『Kaggle』分类任务_决策树&集成模型&DataFrame向量化操作

    决策树这节中涉及到了很多pandas中的新的函数用法等,所以我单拿出来详细的理解一下这些pandas处理过程,进一步理解pandas背后的数据处理的手段原理. 决策树程序 数据载入 pd.read_c ...

  6. 【集成模型】Bootstrap Aggregating(Bagging)

    0 - 思想 如下图所示,Bagging(Bootstrap Aggregating)的基本思想是,从训练数据集中有返回的抽象m次形成m个子数据集(bootstrapping),对于每一个子数据集训练 ...

  7. 吴裕雄 python 机器学习——半监督学习LabelSpreading模型

    import numpy as np import matplotlib.pyplot as plt from sklearn import metrics from sklearn import d ...

  8. 决策树与树集成模型(bootstrap, 决策树(信息熵,信息增益, 信息增益率, 基尼系数),回归树, Bagging, 随机森林, Boosting, Adaboost, GBDT, XGboost)

    1.bootstrap   在原始数据的范围内作有放回的再抽样M个, 样本容量仍为n,原始数据中每个观察单位每次被抽到的概率相等, 为1/n , 所得样本称为Bootstrap样本.于是可得到参数θ的 ...

  9. 集成学习-Adaboost

    Adaboost 中文名叫自适应提升算法,是一种boosting算法. boosting算法的基本思想 对于一个复杂任务来说,单个专家的决策过于片面,需要集合多个专家的决策得到最终的决策,通俗讲就是三 ...

随机推荐

  1. Code Forces 1367A Sorting Parts 题解

    (原题链接:CF传送门) 题目背景(我看不懂英文嘤嘤嘤) Sorting Parts You have an array a of length n. You can exactly once sel ...

  2. BitBlt()函数实现带数字百分比进度条控件、静态文本(STATIC)控件实现的位图进度条、自定义进度条控件实现七彩虹颜色带数字百分比

    Windows API BitBlt()函数实现带数字百分比进度条控件. 有两个例子:一用定时器实现,二用多线程实现. 带有详细注解. 此例是本人原创,绝对是网上稀缺资源(本源码用Windows AP ...

  3. FlinkSQL源码阅读-schema管理

    在Flink SQL中, 元数据的管理分为三层: catalog-> database-> table, 我们知道Flink SQL是依托calcite框架来进行SQL执行树生产,校验,优 ...

  4. 使用 content-visibility 优化渲染性能

    最近在业务中实际使用 content-visibility 进了一些渲染性能的优化. 这是一个比较新且有强大功能的属性.本文将带领大家深入理解一番. 何为 content-visibility? co ...

  5. 百度地图API 地图圈区域并计算坐标点是否在区域内

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. JS:typeof

    想要弄明白某一个变量中保存的数据到底是什么数据类型,我们可以使用到typeof操作符. typeof操作符:检测变量的数据类型. 看例子! var a = "abc"; var b ...

  7. 重学ES系列之字符串方面的处理

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. RPA应用场景-公积金贷款业务数据整合和报送

    场景概述 公积金贷款业务数据整合和报送 所涉系统名称 个贷系统.公积金管理系统 人工操作(时间/次) 0.5小时 所涉人工数量1000操作频率 每日 场景流程 1.机器人整理个人贷款信息.个人贷款账户 ...

  9. 前端下载图片的N种方法

    前几天一个简单的下载图片的需求折腾了我后端大佬好几天,最终还是需要前端来搞,开始说不行的笔者最后又行了,所以趁着这个机会来总结一下下载图片到底有多少种方法. 先起个服务 使用expressjs起个简单 ...

  10. CF333E Summer Earnings

    CF333E Summer Earnings 题目 https://codeforces.com/problemset/problem/333/E 题解 思路 知识点:枚举,图论,位运算. 题目要求从 ...