【集成学习】Boosting算法详解

文章目录

  • 1. 集成学习概述
  • 2. Boosting算法详解
  • 3. Gradient Boosting算法详解
    • 3.1 基本思想
    • 3.2 公式推导
  • 4. Python实现

1. 集成学习概述

集成学习(Ensemble Learning)是一种通过结合多个模型的预测结果来提高整体预测性能的技术。相比于单个模型,集成学习通过多个基学习器的“集体智慧”来增强模型的泛化能力,通常能够提高模型的稳定性和准确性。

常见的集成学习框架有:

  • Bagging:通过并行训练多个模型并对其结果进行平均或投票来减少方差
  • Boosting:通过按顺序训练多个模型,每个模型都试图纠正前一个模型的错误,从而减少偏差
  • Stacking:通过训练多个不同类型的基学习器,并将它们的输出作为特征输入到一个高层模型中,从而提升预测性能

每种方法都有其独特的优势和适用场景。在本文中,我们将重点介绍 Boosting 算法,它主要聚焦于通过提高模型的准确度来减少偏差。

2. Boosting算法详解

Boosting 是一种迭代加权的集成学习方法,旨在通过多个弱学习器(通常是偏差较大的模型)的组合,构建一个具有较低偏差和较高准确度的强学习器。与 Bagging 不同,Boosting 关注的是减小模型的 偏差,而非仅仅减少方差。

Boosting 算法通过逐步构建和改进模型,使得每个新模型都能够专注于纠正前一个模型的错误。这种方式使得模型的 预测能力 不断得到提高。Boosting 的核心思想是 顺序训练。每个新的模型都在前一个模型的基础上进行训练,重点关注那些被前一个模型错误分类的样本。通过这种方式,Boosting 可以有效地减少偏差,进而提升模型的精度。

3. Gradient Boosting算法详解

3.1 基本思想

Gradient Boosting 是 Boosting 的一种实现方法,它通过梯度下降的方式,逐步减少模型的偏差。在每一轮迭代中,Gradient Boosting 都会根据上一轮模型的预测误差(残差)训练一个新的弱学习器,最终的预测结果是所有模型预测结果的加权和。

举个简单的例子,假设一个样本真实值为10,若第一个学习器拟合结果为7,则残差为 10-7=3, 残差3作为下一个学习器的拟合目标。若第二个学习器拟合结果为2,则这两个弱学习器组合而成的Boosting模型对于样本的预测为7+2 = 9,以此类推可以继续增加弱学习器以提高性能。

Gradient Boosting还可以将其理解为函数空间上的梯度下降。我们比较熟悉的梯度下降是在参数空间上的梯度下降(例如训练神经网络,每轮迭代中计算当前损失关于参数的梯度,对参数进行更新)。而在Gradient Boosting中,每轮迭代生成一个弱学习器,这个弱学习器拟合损失函数关于之前累积模型的梯度,然后将这个弱学习器加入累积模型中,逐渐降低累积模型的损失。即 参数空间的梯度下降利用梯度信息调整参数降低损失,函数空间的梯度下降利用梯度拟合一个新的函数降低损失。

3.2 公式推导

假设有训练样本 { x i , y i } , i = 1... n \{x_i,y_i\}, i=1...n {xi,yi},i=1...n,在第 m − 1 m-1 m1 轮获得的累积模型为 F m − 1 ( x ) F_{m-1}(x) Fm1(x),则第 m m m 轮的弱学习器 h ( x ) h(x) h(x) 可以通过下式得到

F m ( x ) = F m − 1 ( x ) + arg ⁡ min ⁡ h ∈ H Loss ( y i , F m − 1 ( x i ) + h ( x i ) ) F_m(x) = F_{m-1}(x) + \arg \min_{h \in H} \, \text{Loss}(y_i, F_{m-1}(x_i) + h(x_i)) Fm(x)=Fm1(x)+arghHminLoss(yi,Fm1(xi)+h(xi))

其中上式等号右边第二项的意思是:在函数空间 H H H 中找到一个弱学习器 h ( x ) h(x) h(x),使得加入这个弱学习器之后的累积模型的 l o s s loss loss 最小。那么应该如何找这个 h ( x ) h(x) h(x) 呢?在第 m − 1 m-1 m1 轮结束后,我们可以计算得到损失 L o s s ( y , F m − 1 ( x ) ) Loss(y,F_{m-1}(x)) Loss(y,Fm1(x)),如果我们希望加入第 m m m 轮的弱学习器后模型的 l o s s loss loss 最小,根据最速下降法新加入的模型损失函数沿着负梯度的方向移动,即如果第 m 轮弱学习器拟合函数关于累积模型 F m − 1 ( x ) F_{m-1}(x) Fm1(x) 的负梯度,则加上该弱学习器之后累积模型的 l o s s loss loss 会最小。

因此可以得知第 m 轮弱学习器训练的目标是损失函数的负梯度,即:

g m = − ∂ Loss ( y , F m − 1 ( x ) ) ∂ F m − 1 ( x ) g_m = - \frac{\partial \, \text{Loss}(y, F_{m-1}(x))}{\partial F_{m-1}(x)} gm=Fm1(x)Loss(y,Fm1(x))

如果 Gradient Boosting中采用平方损失函数 L o s s = ( y − F m − 1 ( x ) ) 2 Loss=(y-F_{m-1}(x))^2 Loss=(yFm1(x))2,损失函数负梯度计算出来刚好是残差 y − F m − 1 ( x ) y-F_{m-1}(x) yFm1(x),因此也会说Gradient Boosting每一个弱学习器是在拟合之前累积模型的残差。这样的说法不具有一般性,如果使用其他损失函数或者在损失函数中加入正则项,那么负梯度就不再刚好是残差。

由此可得完整的 Gradient Boosting 算法流程:
在这里插入图片描述
以上 Gradient Boosting 的算法流程具有一般性,根据其中的损失函数和弱学习器的不同可以演变出多种不同的算法。如果损失函数换成平方损失,则算法变成 L2Boosting;如果将损失函数换成 log-loss,则算法成为 BinomialBoost;如果是指数损失,则算法演变成 AdaBoost;还可以采用 Huber loss 等更加 robust 的损失函数。弱学习器如果使用决策树,则算法成为 GBDT(Gradient Boosting Decision Tree),使用决策树作为弱学习器的 GBDT 使用较为普遍。

4. Python实现

python伪代码实现 GradientBoosting :

class GradientBoosting:def __init__(self, base_learner, n_learner, learning_rate):self.learners = [clone(base_learner) for _ in range(n_learner)]self.lr = learning_ratedef fit(self, X, y):residual = y.copy()for learner in self.learners:learner.fit(X, residual)residual -= self.lr * learner.predict(X)def predict(self, X):preds = [learner.predict(X)  for learner in self.learners]return np.array(preds).sum(axis=0) * self.lr

加入学习率 (learning_rate 或 lr) 的目的是为了控制每个基学习器(或弱学习器)对最终模型的贡献度,从而达到更好的训练效果和避免过拟合。 具体来说,学习率的作用可以总结为以下几点(From ChatGPT):

1.防止过拟合

在 Gradient Boosting 中,训练过程是逐步的,每一轮都会基于前一轮的残差训练一个新的基学习器,并将其结果加到已有模型中。假设没有学习率的话,每个基学习器的预测值将完全被加到累积模型中,可能会使模型快速过拟合训练数据。

学习率 lr 的引入通过调整每个基学习器的权重,从而控制模型每次更新的幅度。如果学习率过大,可能会使模型在训练集上快速拟合,导致过拟合;而如果学习率过小,模型训练速度会变得非常慢,可能需要更多的基学习器来达到同样的效果。因此,合理的学习率可以在训练过程中平衡模型的收敛速度和防止过拟合。

2. 控制每个基学习器的贡献度

Gradient Boosting 的训练是一个渐进的过程,每个基学习器都会根据前一轮的残差来进行拟合。没有学习率的情况下,每个新基学习器的贡献将会很大,这可能导致模型在早期就对训练数据过于敏感,无法很好地泛化。

学习率通过缩小每个基学习器的贡献,避免模型在每轮更新时发生过大的变化。通常来说,较小的学习率需要更多的基学习器(即更多的迭代次数)来收敛,但可以有效减少每个基学习器对最终结果的影响,从而降低过拟合的风险。

3. 控制训练过程的收敛速度

学习率对模型的收敛速度有很大的影响。较大的学习率可以使模型快速收敛,但可能导致震荡或过拟合;而较小的学习率使模型收敛较慢,但通常会得到更加平滑和稳健的结果。合理选择学习率,可以在优化过程的初期实现快速的方向调整,而在后期逐渐精细化模型。

4. 改进模型的稳定性

加入学习率可以帮助模型在训练过程中避免跳跃式的大幅更新。每个基学习器的调整幅度得到控制,使得模型更新更为平稳,从而使得训练过程更加稳定,减少了由于每个学习器的过度调整带来的不稳定性。

数学解释:
在训练过程中,每一轮训练的目标是通过最小化损失函数来拟合前一轮累积模型的残差。对于每一轮的弱学习器,其目标是拟合当前模型残差的负梯度。加入学习率 lr 后,训练过程中的每个弱学习器的输出会乘以该学习率,从而调节每个学习器对模型更新的贡献。
具体来说,假设当前模型的输出为 F m − 1 ( x ) F_{m-1}(x) Fm1(x),而第 m m m 轮的弱学习器的目标是拟合该模型的残差。使用学习率 lr 后,更新步骤变为:

F m ( x ) = F m − 1 ( x ) + l r ∗ h m ( x ) F_m(x) = F_{m-1}(x) + lr*h_m(x) Fm(x)=Fm1(x)+lrhm(x)
这里, h m ( x ) h_m(x) hm(x) 是第 m m m 轮弱学习器的输出。通过学习率 lr,我们可以控制每个弱学习器的输出对最终模型的贡献。

本文参考:
https://borgwang.github.io/ml/2019/04/12/gradient-boosting.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/65953.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小米vela系统(基于开源nuttx内核)——如何使用信号量进行PV操作

如何使用信号量进行PV操作 前言信号量1. 信号量简介2. NuttX中信号量的创建与使用2.1 Nuttx信号量的初始化和销毁2.2 信号量的等待和发布 3. 信号量的实际应用:下载任务示例3.1 实际代码3.2 代码说明3.3 执行说明 4. 信号量的优势与应用场景5. 常见应用场景&#xf…

CMake学习笔记(2)

1. 嵌套的CMake 如果项目很大,或者项目中有很多的源码目录,在通过CMake管理项目的时候如果只使用一个CMakeLists.txt,那么这个文件相对会比较复杂,有一种化繁为简的方式就是给每个源码目录都添加一个CMakeLists.txt文件&#xff…

【C++】size_t究竟是什么?全面解析与深入拓展

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯一、什么是size_t?为什么需要size_t? 💯二、size_t的特性与用途1. size_t是无符号类型示例: 2. size_t的跨平台适应性示例对…

【物流管理系统 - IDEAJavaSwingMySQL】基于Java实现的物流管理系统导入IDEA教程

有问题请留言或私信 步骤 下载项目源码:项目源码 解压项目源码到本地 打开IDEA 左上角:文件 → 新建 → 来自现有源代码的项目 找到解压在本地的项目源代码文件,点击确定,根据图示步骤继续导入项目 查看项目目录&#xff…

ssh2-sftp-client和ssh2配合使用js脚本快速部署项目到服务器

有时候因为服务器不能实现github或者gitlab的自动部署服务,所以就需要使用脚本来实现自动部署,可以省时省力,一劳永逸。这里就使用ssh2-sftp-client和ssh2来实现,即便是需要sudo权限,也是可以的。 1.先将本地打包后的…

深度解析Linux中的调试器gdb/cgdb的使用

Linux下我们编译好的代码,无法直接调试 gcc/g默认的工作模式是realse模式 程序要调试的话,必须是debug模式,也就是说编译的时候要加-g选项 gdb携带调试信息的exe 我们现在在文件夹里面创建一个文件lesson11 里面创建一个累加的代码&…

【Maui】动态菜单实现(绑定数据视图)

前言 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架,用于使用 C# 和 XAML 创建本机移动和桌面应用。 使用 .NET MAUI,可从单个共享代码库开发可在 Android、iOS、macOS 和 Windows 上运行的应用。 .NET MAUI 是一款开放源代码应用,是 X…

RNN之:LSTM 长短期记忆模型-结构-理论详解-及实战(Matlab向)

0.前言 递归!循环神经网络Recurrent Neural Network 循环神经网络(又称递归神经网络,Recurrent Neural Network,RNN)。是一种用于处理序列数据的神经网络结构,具有记忆功能,能够捕捉序列中的时…

泛目录和泛站有什么差别

啥是 SEO 泛目录? 咱先来说说 SEO 泛目录是啥。想象一下,你有一个巨大的图书馆,里面的书架上摆满了各种各样的书,每一本书都代表着一个网页。而 SEO 泛目录呢,就像是一个超级图书管理员,它的任务就是把这些…

【Vue】全局/局部组件使用流程(Vue2为例)

全局组件和局部组件区别 如何使用 全局组件:全局注册后,可以在任意页面中直接使用。局部组件:在页面中需要先导入子组件路径,注册组件才能使用。 适用场景 全局组件:适用于高频使用的组件,如导航栏、业…

【Pytorch实用教程】PyTorch 中如何输出模型参数:全面指南

文章目录 PyTorch 中如何输出模型参数:全面指南1. 为什么需要输出模型参数?2. PyTorch 中输出模型参数的方法2.1 使用 `model.parameters()` 输出所有参数2.2 使用 `model.named_parameters()` 输出参数名称和值2.3 使用 `model.state_dict()` 输出模型的参数字典2.4 输出特定…

1、docker概念和基本使用命令

docker概念 微服务:不再是以完整的物理机为基础的服务软件,而是借助于宿主机的性能。以小量的形式,单独部署的应用。 docker:是一个开源的应用容器引擎,基于go语言开发的,使用时apache2.0的协议。docker是…

Genymotion配套VirtualBox所在地址

在 Genymotion打开虚拟机前需要先打开VirtualBox中的虚拟机 C:\Program Files\Oracle\VirtualBox\VirtualBox.exe 再开启genymotion中的虚拟机开关

【Linux】深刻理解软硬链接

一.软硬链接操作 1.软连接 touch 创建一个文件file.txt ,对该文件创建对应的软链接改怎么做呢? ln -s file.txt file-soft.link .给对应文件创建软连接。 软连接本质就是一个独立的文件,因为我们对应的软连接有独立的inode,他…

第三十六章 Spring之假如让你来写MVC——拦截器篇

Spring源码阅读目录 第一部分——IOC篇 第一章 Spring之最熟悉的陌生人——IOC 第二章 Spring之假如让你来写IOC容器——加载资源篇 第三章 Spring之假如让你来写IOC容器——解析配置文件篇 第四章 Spring之假如让你来写IOC容器——XML配置文件篇 第五章 Spring之假如让你来写…

快速上手 HarmonyOS 应用开发

一、DevEco Studio 安装与配置 1. DevEco Studio 简介 DevEco Studio 是 HarmonyOS 的一站式集成开发环境(IDE),提供了丰富的工具和功能,支持 HarmonyOS 应用开发的全流程。 2. DevEco Studio 下载与安装 下载地址&#xff1a…

Java Web开发进阶——错误处理与日志管理

错误处理和日志管理是任何生产环境中不可或缺的一部分。在 Spring Boot 中,合理的错误处理机制不仅能够提升用户体验,还能帮助开发者快速定位问题;而有效的日志管理能够帮助团队监控应用运行状态,及时发现和解决问题。 1. 常见错误…

图解Git——分支的新建与合并《Pro Git》

⭐分支的新建与合并 先引入一个实际开发的工作流: 开发某个网站。为实现某个新的需求,创建一个分支。在这个分支上开展工作。 正在此时,你突然接到一个电话说有个很严重的问题需要紧急修补。你将按照如下方式来处理: 切换到你…

【数据可视化-12】数据分析岗位招聘分析

🧑 博主简介:曾任某智慧城市类企业算法总监,目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

excel仅复制可见单元格,仅复制筛选后内容

背景 我们经常需要将内容分给不同的人,做完后需要合并 遇到情况如下 那是因为直接选择了整列,当然不可以了。 下面提供几种方法,应该都可以 直接选中要复制区域然后复制,不要选中最上面的列alt;选中可见单元格正常复制&#xff…