前言

前面的文章中介绍了决策树以及其它一些算法,但是,会发现,有时候使用使用这些算法并不能达到特别好的效果。于是乎就有了集成学习(Ensemble Learning),通过构建多个学习器一起结合来完成具体的学习任务。这篇文章将介绍集成学习,以及其中的一种算法 AdaBoost。

集成学习

首先先来介绍下什么是集成学习:

  • 构建多个学习器一起结合来完成具体的学习任务,常可获得比单一学习器显著优越的泛化性能,对“弱学习器” 尤为明显(三个臭皮匠,顶个诸葛亮)
  • 也称为Multi-Classifier System, Committee-Based Learning
  • 学习器可以是同类型的,也可以是不同类型

这么一看,就感觉集成学习与常说的模型融合很像,甚至可以理解为就是模型融合。

那么,常用的集成学习方法有哪些呢?

  1. Boosting,将各种弱分类器串联起来的集成学习方式,每一个分类器的训练都依赖于前一个分类器的结果,代表:AdaBoost,Gradient Boosting Machine
  2. Bagging,Bootstrap Aggregating 的缩写。这种方法采用的是随机有放回的选择训练数据然后构造分类器,最后进行组合,代表:Random Forest
  3. Voting/Averaging,在不改变模型的情况下,直接对各个不同的模型预测的结果进行投票或者平均
  4. Binning,最近看到的一种方法,还没细看,参考论文
  5. Stacking
  6. Blending

后面几种方法这里暂时不做介绍,后面会单独写博客来介绍这些方法

AdaBoost

算法思想

这里将介绍一个基于 Boosting 方法的一个学习算法 AdaBoost,于1995年由 Freund 和 Schapire 提出。其主要思想为:

  1. 先训练出一个基学习器
  2. 根据该学习器的表现对训练样本权重进行调整,使得现有基学习器做错的样本在后续学习器的训练中受到更多的关注
  3. 基于调整后的权重来训练下一个基学习器
  4. 重复 2、3 直至学习器数目达到事先指定的值 T
  5. 最终将这 T 个学习器进行加权结合

\[H(x)=\operatorname{sign}\left(\sum_{t=1}^{T} \alpha_{t} h_{t}(x)\right)
\]

具体算法

设训练数据集

\[\{x^{(i)}, y^{(i)}\}_{i=1}^{m},x^{(i)} \in \mathbb{R}^n, y \in \{-1, +1\}
\]

初始化训练数据的权值分布

\[\mathcal{D}_{1}\left(x^{(i)}\right)=\frac{1}{m}
\]

for t in range(T):

​ 假设训练得到分类器 \(h_t(x)\) ,则可计算 \(h_t(x)\) 在当前训练集上的分类误差:

\[\epsilon_{t}=P_{x \sim \mathcal{D}_{t}}\left[h_{t}(x) \neq y\right]=\sum_{y^{(i)} \neq h_{t}\left(x^{(i)}\right)} \mathcal{D}_{t}\left(x^{(i)}\right)
\]

​ 若 \(\epsilon_{t} > 0.5\), break; 否则计算分类器权重

\[\alpha_{t}=\frac{1}{2} \log \frac{1-\epsilon_{t}}{\epsilon_{t}}
\]

​ 然后更新样本权重

\[\mathcal{D}_{t+1}\left(x^{(i)}\right)=\frac{1}{Z_{t}} \mathcal{D}_{t}\left(x^{(i)}\right) \exp \left[-\alpha_{t} y^{(i)} h_{t}\left(x^{(i)}\right)\right]
\]

​ 其中 \(Z_t\) 为归一化因子

\[Z_{t}=\sum_{i} \mathcal{D}_{t}\left(x^{(i)}\right) \exp \left[-\alpha_{t} y^{(i)} h_{t}\left(x^{(i)}\right)\right]
\]

构建基本分类器的线性组合

\[f(x)=\sum_{t=1}^{T} \alpha_{t} h_{t}(x)
\]

得到最终分类器

\[H(x)=\operatorname{sign}\left(\sum_{t=1}^{T} \alpha_{t} h_{t}(x)\right)
\]

这里我们可以看到 \(\alpha_t\) 是大于 $\frac{1}{2} $ 的,如果误分类了,那么 \(-\alpha_{t} y^{(i)} h_{t}\left(x^{(i)}\right)\) 为大于 0 的数,那么样本的权重就会被放大,反之,则会被缩小。并且, \(\epsilon_t\) 越大,\(\alpha_t\) 就越小,即在最终构建强分类器的时候,误差率越小的弱分类器预测结果所占比重越高。

算法推导

思考两个个问题, \(\alpha_t\) 的公式是怎么来的?以及权重更新公式是怎么来的?下面通过公式推导来讲解

假设已经经过 \(t-1\) 轮迭代,得到\(f_{t-1}(x)\),根据前向分布加法算法

\[f_t(x) = f_{t-1}(x) + \alpha_{t}h_t(x)
\]

目标是损失函数最小,即

\[\min{Loss} = \min\sum_{i=1}^{N}exp[-y_i(f_{t-1}(x_i)+\alpha_th_t)]
\]

所以,有

\[\begin{eqnarray}(\alpha_t,h_t(x)) & = & \arg {\min_{\alpha,h}\sum_{i=1}^{N}exp[-y_i(f_{t-1}(x_i)+\alpha_th_t()x_i)]} \\ & = & \arg {\min_{\alpha,h}\sum_{i=1}^{N}w_{t,i}exp[-y_i(\alpha_th_t(x_i))]} \end{eqnarray}
\]

\[w_{t,i} = \exp[-y_if_{t-1}(x_i)]
\]

我们先来化简损失函数

\[\begin{eqnarray}Loss & = &\sum_{y_i=h_t(x_i)}w_{t,i}exp(-\alpha_t)+\sum_{y_i \ne h_t(x_i)}w_{t,i}exp(\alpha_t)
\\ & = & \sum_{i=1}^{N}w_{t,i}(\frac{\sum_{y_i=h_t(x_i)}w_{t,i}}{\sum_{i=1}^{N}w_{t,i}}exp(-\alpha_t)+\frac{\sum_{y_i \ne h_t(x_i)}w_{t,i}}{\sum_{i=1}^{N}w_{t,i}}exp(-\alpha_t))
\end{eqnarray}
\]

仔细以看,后面那项 \(\frac{\sum_{y_i \ne h_t(x_i)}w_{t,i}}{\sum_{i=1}^{N}w_{t,i}}\) 就是分类误差率 \(\epsilon_{t}\),所以

\[Loss = \sum_{i=1}^{N}w_{t,i}[(1-\epsilon_t)exp(-\alpha_t)+\epsilon_texp(\alpha_t)]
\]

对 \(\alpha_t\) 求偏导

\[\begin{eqnarray}
\frac{\partial Loss}{\partial \alpha_t} & = & \sum_{i=1}^{N}w_{t,i}[-(1-\epsilon_t)exp(-\alpha_t)+\epsilon_texp(\alpha_t)]
\end{eqnarray}
\]

令 \(\frac{\partial Loss}{\partial \alpha_t} = 0\) ,则

\[-(1-\epsilon_t)exp(-\alpha_t)+\epsilon_texp(\alpha_t) = 0
\]

推得

\[\alpha_{t}=\frac{1}{2} \log \frac{1-\epsilon_{t}}{\epsilon_{t}}
\]

另,由前向分布加法算法

\[\begin{eqnarray}
w_{t,i} & = & \exp[-y_if_{t-1}(x_i)] \\
& = & \exp[-y_i(f_{t-2}(x_i)+\alpha_{t-1}h_{t-1}(x_i))] \\
& = & w_{t-1,i}\exp[\alpha_{t-1}h_{t-1}(x_i)]
\end{eqnarray}
\]

再加上规范化因子即为算法中的更新公式。(公式敲的要累死了~~~)

代码实现

这里为了方便起见,我使用了 sklearn 里面的决策树,之前使用的时候一直没发现 sklearn 里的决策树可以带权重训练 orz。。。决策树带权训练的代码我后面再研究研究

from sklearn.tree import DecisionTreeClassifier
def adaboost(X, y, M, max_depth=None):
"""
adaboost函数,使用Decision Tree作为弱分类器
参数:
X: 训练样本
y: 样本标签, y = {-1, +1}
M: 使用 M 个弱分类器
max_depth: 基学习器决策树的最大深度
返回:
F: 生成的模型
"""
num_X, num_feature = X.shape # 初始化训练数据的权值分布
D = np.ones(num_X) / num_X G = []
alpha = [] for m in range(M):
# 使用具有权值分布 D 的训练数据集学习,得到基本分类器
# 使用 DecisionTreeClassifier,设置树深度为 max_depth
G_m = DecisionTreeClassifier(max_depth=max_depth)
# 开始训练
G_m.fit(X, y, D)
# 计算G_m在训练数据集上的分类误差率
y_pred = G_m.predict(X)
e_m = np.sum(D[y != y_pred]) if e_m == 0:
break if e_m == 1:
raise ValueError("e_m = {}".format(e_m)) # 计算 G_m 的系数
alpha_m = np.log((1 - e_m) / e_m) / 2
# print(alpha_m)
# 更新训练数据集的权值分布
D = D * np.exp(-alpha_m * y * y_pred)
D = D / np.sum(D)
# 保存 G_m 和其系数
G.append(G_m)
alpha.append(alpha_m) # 构建基本分类器的线性组合
def F(X):
num_G = len(G)
score = 0
for i in range(num_G):
score += alpha[i] * G[i].predict(X)
return np.sign(score) return F

小节

上面介绍了集成学习的一些知识点以及 AdaBoost 的基本原理及实现,下一篇将介绍集成学习中基于 Bagging 的随机森林(Random Forest)。

谈谈模型融合之一 —— 集成学习与 AdaBoost的更多相关文章

  1. 集成学习值Adaboost算法原理和代码小结(转载)

    在集成学习原理小结中,我们讲到了集成学习按照个体学习器之间是否存在依赖关系可以分为两类: 第一个是个体学习器之间存在强依赖关系: 另一类是个体学习器之间不存在强依赖关系. 前者的代表算法就是提升(bo ...

  2. 集成学习之AdaBoost

    AdaBoost 当做出重要决定时,大家可能会考虑吸取多个专家而不只是一个人的意见,机器学习也是如此,这就是集成学习的基本思想.使用集成方法时有多种形式:可以是不同算法的集成,也可以是同一算法在不同设 ...

  3. 机器学习回顾篇(13):集成学习之AdaBoost

    .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...

  4. 集成学习之Adaboost算法原理小结

    在集成学习原理小结中,我们讲到了集成学习按照个体学习器之间是否存在依赖关系可以分为两类,第一个是个体学习器之间存在强依赖关系,另一类是个体学习器之间不存在强依赖关系.前者的代表算法就是是boostin ...

  5. 集成学习之Adaboost算法原理

    在boosting系列算法中,Adaboost是最著名的算法之一.Adaboost既可以用作分类,也可以用作回归. 1. boosting算法基本原理 集成学习原理中,boosting系列算法的思想:

  6. 集成学习算法——adaboost

    adaboost是boosting类集成学习方法中的一种算法,全称是adaptive boost,表示其是一种具有自适应性的算法,这个自适应性体现在何处,下面来详细说明. 1.adaboost算法原理 ...

  7. 谈谈模型融合之三 —— GBDT

    前言 本来应该是年后就要写的一篇博客,因为考完试后忙了一段时间课设和实验,然后回家后又在摸鱼,就一直没开动.趁着这段时间只能呆在家里来把这些博客补上.在之前的文章中介绍了 Random Forest ...

  8. 机器学习—集成学习(Adaboost)

    一.原理部分: 二.sklearn实现: from sklearn.ensemble import AdaBoostClassifier from sklearn.datasets import lo ...

  9. 决策树(中)-集成学习、RF、AdaBoost、Boost Tree、GBDT

    参考资料(要是对于本文的理解不够透彻,必须将以下博客认知阅读): 1. https://zhuanlan.zhihu.com/p/86263786 2.https://blog.csdn.net/li ...

随机推荐

  1. SaaS加速器II 能力中心:互利互补 共享商业红利

    摘要: 通过丰富的阿里集团和三方的业务能力API,缩短业务从0-1构建的周期和降低成本,我们希望能够把阿里巴巴在电商.金融.物流.高德以及其他领域沉淀出来商业最佳实践.商业能力,通过阿里云的渠道输出, ...

  2. SQL语法之DDL和DML

    SQL语法之DDL和DML        DDL数据库定义语言 create 创建 alter 修改 drop 删除 drop和delete的区别 truncate DML 数据操作语言 insert ...

  3. dnspython

    dnspython 一个Python实现的一个DNS工具包,利用其查询功能来实现dns的服务监控及解析结果的校验. 安装 pip install dnspython 解析域名为IP from dns ...

  4. MyBatis动态批量插入、更新Mysql数据库的通用实现方案

    一.业务背景 由于需要从A数据库提取大量数据同步到B系统,采用了tomikos+jta进行分布式事务管理,先将系统数据源切换到数据提供方,将需要同步的数据查询出来,然后再将系统数据源切换到数据接收方, ...

  5. 2019-6-23-WPF-获得当前输入法语言区域

    title author date CreateTime categories WPF 获得当前输入法语言区域 lindexi 2019-06-23 11:51:21 +0800 2018-10-12 ...

  6. 【牛腩视频】之SQL触发器 标签: 数据库 2015-05-23 09:44 1339人阅读 评论(40) 收藏

    之前在学习机房管理系统.net版的时候,已经写过了关于数据库的操作,但是现在开始学习牛腩,才发现之前自己理解的太浅显,很多东西看似好像会了,不去实际操作一下,不把代码从头到尾敲出来,到头来还是不会,所 ...

  7. HZOJ Drink

    神仙题,打了个whs式暴力卡常卡A了(我没脸),正解还是要打的,然而作者的题解看不懂…… Drink: 看惯了罗马音的小朋友们都会知道r发l的音,题目名:D Link. 每次修改都会改变O( N ^  ...

  8. 行为面试法(STAR)

    从过去的行为预测未来,是一种提问技巧. 情景 : Situation 当时怎么了 当时你所在团队主要销售任务是什么目标 : Task 你要干什么 当时你的销售业绩是多少行动 : Action 你都干了 ...

  9. WebSocket 实时更新mysql数据到页面

    使用websocket的初衷是,要实时更新mysql中的报警信息到web页面显示 没怎么碰过web,代码写的是真烂,不过也算是功能实现了,放在这里也是鞭策自己,web也要多下些功夫 准备 引入依赖 & ...

  10. 检查进程启动情况,开始时间、启动时间、启动进程数、进程数是否正确、PID

    #!/bin/sh bin=$(cd ``;pwd) cd ${bin} ### 定义检查函数 chk(){ programName=$ correctNum=$ programSubName=$ # ...