前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >为什么梯度提升表现如此出色?

为什么梯度提升表现如此出色?

作者头像
磐创AI
发布2024-04-22 11:17:14
730
发布2024-04-22 11:17:14
举报

在这里,我们将了解为什么使用简单的基础函数来解决复杂问题是一个强大的概念。

诸如xgboost之类的梯度提升算法是表格数据中表现最佳的模型之一。与其他模型(如随机森林)一样,梯度提升属于集成模型的范畴。该名称来源于该范畴的一个核心特征:它们不适应单个大模型,而是适应一个由多个模型组成的整体模型集合。集成模型与基础函数的概念密切相关。两者都使用较简单的构建块,这些构建块组合在一起以解决更复杂的问题。

在本文中,我将首先介绍基础函数的概念,然后展开基础函数如何应用于梯度提升模型。最后,我将详细阐述一个关键的洞察力:梯度提升中的基础函数需要相对简单,以使算法有效地工作。

本文在很大程度上受到Hastie等人所著的优秀书籍《统计学习的基础》(EOSL)第8至10章的启发。因此,如果您想进行更深入的讨论,包括所有数学内容,我愿意将读者引荐给这本书。

https://hastie.su.domains/Papers/ESLII.pdf

从单一函数到基础函数

在其最基本的形式中,任何监督学习算法都试图在特征和标签之间拟合一个函数。与其使用一个大函数不如使用许多较小的基础函数来构造这个函数。在下面的例子中,我想说明基础函数的概念。目标是使用正弦波来重构时序函数。以下是由5 Hz和2 Hz信号组合而成的基础“真实”函数comb,以及我们从中获取的观测值(黑点):

代码语言:javascript
复制
import numpy as np
import pandas as pd
from plotnine import *

np.random.seed(1234)

time_step = 0.02
time_vec = np.arange(0, 5, time_step)
sine_wave = np.sin(2 * np.pi * 5 * time_vec)
sine_wave2 = np.sin(2 * np.pi * 2 * time_vec)

reference_data = pd.DataFrame({'5hz': sine_wave, '2hz': sine_wave2, 'comb': sine_wave + sine_wave2, 'time': time_vec})
observations = reference_data.sample(100)
(
    ggplot(aes(x='time')) 
      + geom_point(observations, aes(y='comb')) 
      + geom_line(reference_data.melt(id_vars='time',  value_vars=['5hz', '2hz', 'comb']), aes(y='value', color='variable'))
      + facet_wrap('~variable', ncol=1)
)

重构我们的基础函数comb的一个简单方法是使用单个正弦函数:我们可以改变正弦波的频率和幅度。但是,无论我们做什么,没有单个正弦波可以完美地拟合这些观测值。这是合理的,因为这些观测值来自组合的5 Hz和2 Hz线。

为了获得良好的拟合,我们需要拟合一个结合了2Hz和5Hz函数的模型。在这种情况下,2Hz和5Hz函数是我们构建整体函数的基础函数。可以使用傅里叶分析来确定哪些基础函数适用于这个信号。从某种意义上说,我们使用一系列正弦函数来构建一个整体更复杂的函数。除了傅里叶变换外,基础函数还用于小波、神经网络、主成分分析和泰勒展开。

基础函数需要简单

梯度提升模型中使用的基础函数是小型决策树。第一个基础函数是最佳单节点树,即模型由单个是/否决策树组成(EOSL,第360页)。连续的基础函数采用𝐽J大小的树形式,并构建在先前拟合的基础函数的残差上。

因此,第一个子树解释了数据中一点点的方差,而每个附加的子树都解释了越来越多的数据方差。每个单独的子树在对数据建模方面并不是很有效,就像我们在2Hz和5Hz的示例中所看到的那样,因此被认为是一个弱学习器。然而,弱学习器的集合却是一个非常强大的学习器,这是梯度提升成功的核心机制。

请注意,我们通过限制子树的大小为𝐽J来刻意创建弱学习器(EOSL,第361页,第10.11节)。这样可以防止第一批树变得非常大,限制了我们在拟合后续子树时的灵活性。我们希望子树相对较弱,让提升算法在使用大型单个子树的情况下承担大部分工作。这与神经网络解决问题的方式非常一致:使用非常简单的数学运算,在大量的集成中解决复杂的问题。复杂的解决方案是从底层简单的基础函数中产生的紧急行为。

梯度提升中的梯度

梯度提升机器在每个子树之后如何计算残差进一步阐明了为什么弱学习器不是一个缺陷而是一个特征。我在这里的解释受到了这篇SO文章的很大启发,其中有一些数学内容,所以请跟着我一起来理解。

让我们假设对于给定的观测,我们有一个真实值𝑦和一个值𝑦̂,它包含了我们已经拟合的所有先前子树的总预测。接下来,我们构造一个新的子树,产生一个结果𝑧,从而得到新的总预测𝑦̂ +𝑧。新的子树应该最小化𝑦̂ +𝑧与𝑦之间的损失。实质上,𝑧=𝑦−𝑦̂ 将给出我们完美的答案。

如果我们将均方误差(MSE)作为损失函数(𝐿=1/2(𝑦−𝑦̂ )^2),那么相对于新的预测,损失函数的梯度是𝑦−𝑦̂ =−∂𝐿/∂𝑦̂ 。我们已经表明𝑦−𝑦̂ 是最佳答案,因此该梯度也提供了最佳答案。通过将此梯度用作新子树应拟合的残差,我们实际上在𝑦̂ 的预测空间中执行了梯度下降:哪个最小的𝑦̂ 改变会导致损失函数最大地减少。这就是梯度提升中的“梯度”所指的:使用一系列逐渐构建出一个良好整体模型的弱学习器。每个子树提供了最好的步骤,以最小化我们的损失,即在提升过程的该步骤中解决模型所遇到的最大问题。我在这个链接中提供了更多关于梯度提升中这个属性的数学推导。

在提升过程中,保持预测空间中的步骤较小,即使用小的子树,可以确保我们慢慢地探测预测空间的表面,不会陷入局部最小值。此外,使用小的子树确保我们连续的基础函数可以专门用于解决特定的挑战性观测。使用非常大的树会促使关注整体平均性能,而不是专注于较小的细节。使用小树,从而使用弱学习器,使得梯度提升在如何解决给定问题方面非常灵活。

结论:弱学习器的集成

梯度提升的核心概念是通过选择最小化与真实值之间损失的下一个弱学习器,来增强一系列连续(或集成)的弱学习器的效果。集成中的每个子树都需要相对较弱,以使梯度下降能够灵活地朝着良好的解决方案发展。这使得梯度提升成为一种非常有效的方法,通常在不需要进行大量调整的情况下就能够非常好地工作。

这篇文章也可以在GitHub上阅读,包括所有的代码。

https://github.com/PaulHiemstra/ensemble_model_article/blob/main/ensemble_model_article.ipynb

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 磐创AI 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 从单一函数到基础函数
  • 基础函数需要简单
  • 梯度提升中的梯度
  • 结论:弱学习器的集成
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档