Gradient Boosting

Visão geral

O impulsionamento por gradiente (gradient boosting) é um poderoso método de ensemble (ensemble method) que constrói um modelo preditivo forte ao combinar muitos modelos fracos—mais comumente Árvores de Decisão—de forma sequencial. Cada novo modelo é treinado para corrigir os erros cometidos pelo ensemble existente, com o objetivo geral de minimizar uma função de perda escolhida (por exemplo, erro quadrático para regressão, perda logarítmica para classificação).

Na prática, “impulsionamento por gradiente” frequentemente se refere especificamente a Árvores de Decisão com Impulsionamento por Gradiente (Gradient-Boosted Decision Trees, GBDTs), que estão entre os modelos de uso geral mais fortes para dados tabulares (tabular data) (dados estruturados com atributos heterogêneos, valores ausentes, interações não lineares etc.). Implementações modernas populares incluem XGBoost, LightGBM e CatBoost.

O impulsionamento por gradiente está intimamente relacionado a outros ensembles de árvores como Florestas Aleatórias e Árvores Extra (Árvores Extremamente Aleatorizadas), mas difere em um ponto-chave: florestas aleatórias fazem a média de muitas árvores treinadas independentemente (bagging), enquanto o impulsionamento por gradiente adiciona árvores sequencialmente para reduzir uma perda (boosting).

Ideia central: modelagem aditiva + descida do gradiente no espaço de funções

O impulsionamento por gradiente constrói um modelo aditivo:

[ F_M(x) = \sum_{m=0}^{M} \nu , f_m(x) ]

  • (x): atributos de entrada
  • (F_M(x)): função de predição final após (M) rodadas de boosting
  • (f_m(x)): aprendiz fraco (weak learner) na iteração (m) (frequentemente uma pequena árvore de decisão)
  • (\nu): taxa de aprendizado (learning rate) (um fator de encolhimento, tipicamente (0.01)–(0.2))

A percepção-chave (Friedman, 2001) é que o boosting pode ser visto como descida do gradiente no espaço de funções (gradient descent in function space): em vez de otimizar parâmetros (\theta), otimizamos sobre funções (F(x)).

De resíduos a gradientes

A cada passo de boosting, queremos reduzir o risco empírico:

[ \min_F \sum_{i=1}^{n} L(y_i, F(x_i)) ]

O impulsionamento por gradiente faz isso ao:

  1. Calcular o gradiente negativo (negative gradient) da perda com respeito às predições atuais (F_{m-1}(x_i))
  2. Ajustar um aprendiz fraco (f_m(x)) para aproximar esse gradiente negativo
  3. Adicionar o aprendiz fraco ao modelo (com taxa de aprendizado)

Em muitos textos, os valores do gradiente negativo são chamados de pseudo-resíduos (pseudo-residuals):

[ r_{im} = -\left[\frac{\partial L(y_i, F(x_i))}{\partial F(x_i)}\right]{F=F{m-1}} ]

Em seguida, ajusta-se uma árvore de regressão (f_m) para prever (r_{im}) a partir de (x_i), e atualiza-se:

[ F_m(x) = F_{m-1}(x) + \nu , f_m(x) ]

Intuição

  • O ensemble atual faz predições (F_{m-1}(x)).
  • A função de perda nos diz o quão “ruins” essas predições são.
  • O gradiente nos diz a direção para mudar as predições a fim de reduzir a perda.
  • A próxima árvore é treinada para produzir essa mudança.

É por isso que o impulsionamento por gradiente é mais geral do que “ajustar resíduos”: o ajuste de resíduos é o caso especial para erro quadrático, em que os gradientes são literalmente resíduos.

Esboço do algoritmo (GBDT)

Uma formulação comum:

  1. Inicialize o modelo com uma predição constante: [ F_0(x) = \arg\min_c \sum_i L(y_i, c) ]
  2. Para (m = 1 \dots M):
    • Calcule os pseudo-resíduos: [ r_{im} = -\left[\frac{\partial L(y_i, F(x_i))}{\partial F(x_i)}\right]{F=F{m-1}} ]
    • Ajuste uma árvore de regressão (f_m(x)) a ({(x_i, r_{im})})
    • Atualize: [ F_m(x) = F_{m-1}(x) + \nu f_m(x) ]

Em algumas variantes, também há uma etapa de busca linear (line search) para encontrar um multiplicador ótimo para cada árvore (ou cada folha), mas a maioria das bibliotecas modernas de GBDT incorpora isso de forma eficiente.

Funções de perda: regressão, classificação e além

O impulsionamento por gradiente suporta muitas perdas porque a “direção de melhoria” vem do gradiente da perda escolhida.

Regressão (erro quadrático)

Para (L(y, F)=\frac{1}{2}(y-F)^2):

[ \frac{\partial L}{\partial F} = F-y \quad \Rightarrow \quad r = y - F ]

Assim, os pseudo-resíduos são apenas os familiares resíduos (residuals). Cada nova árvore ajusta os resíduos do modelo atual.

Classificação binária (perda logarítmica)

Para classificação binária, frequentemente modelamos logits (F(x)), com probabilidade (p(x) = \sigma(F(x))). Com perda logarítmica:

[ L(y, F)= -y \log p - (1-y)\log(1-p) ]

O gradiente produz pseudo-resíduos relacionados a (y - p). Na prática, cada iteração de boosting ajusta os logits para que as probabilidades previstas se aproximem dos rótulos verdadeiros.

Outras tarefas

Frameworks modernos de GBDT suportam objetivos adicionais, por exemplo:

  • classificação multiclasse (softmax)
  • regressão robusta (Huber, quantílica)
  • dados de contagem (Poisson, Tweedie)
  • perdas de ranqueamento (objetivos no estilo LambdaRank em alguns sistemas)

O mecanismo permanece o mesmo: computar gradientes (e às vezes Hessianas) e ajustar árvores a eles.

Por que árvores de decisão funcionam bem como aprendizes fracos

Árvores de decisão são aprendizes-base comuns porque:

  • modelam naturalmente não linearidades (nonlinearities) e interações entre atributos (feature interactions)
  • lidam com escalas mistas de atributos sem normalização
  • conseguem capturar efeitos de limiar (threshold) comuns em dados tabulares
  • funcionam bem com valores ausentes (especialmente na lógica de divisão no estilo LightGBM/XGBoost)

No impulsionamento por gradiente, as árvores geralmente são mantidas pequenas (por exemplo, profundidade 3–8) para que cada árvore faça uma correção modesta. A força vem de adicionar muitas dessas correções.

Principais hiperparâmetros (e como eles interagem)

Embora as implementações difiram, a maioria dos modelos GBDT compartilha alguns controles críticos.

Taxa de aprendizado (`learning_rate`, `eta`)

A taxa de aprendizado (\nu) escala o quanto cada árvore contribui.

  • Taxa de aprendizado menor:
    • precisa de mais árvores
    • frequentemente generaliza melhor
    • treina mais lentamente
  • Taxa de aprendizado maior:
    • precisa de menos árvores
    • pode superajustar ou se tornar instável com mais facilidade

Uma regra prática comum: escolher uma taxa de aprendizado pequena (por exemplo, 0.03–0.1) e depender de parada antecipada (early stopping) para determinar o número de árvores.

Número de árvores (`n_estimators`, `num_boost_round`)

Mais árvores aumentam a capacidade. Muitas árvores podem superajustar, especialmente com árvores profundas ou taxas de aprendizado altas.

Na prática, você raramente escolhe isso isoladamente—use validação + Parada Antecipada.

Complexidade da árvore (`max_depth`, `num_leaves`, `min_child_weight`, …)

O tamanho da árvore controla quão complexa cada correção incremental pode ser:

  • max_depth (comum em XGBoost/sklearn): limita a profundidade da árvore.
  • num_leaves (LightGBM): controla diretamente o número de folhas (o crescimento folha-a-folha pode criar árvores profundas se não houver restrição).
  • Mínimo de dados/peso por folha (min_samples_leaf, min_child_weight): evita divisões excessivamente específicas.

Árvores mais profundas/maiores:

  • ajustam interações complicadas mais rapidamente
  • superajustam com mais facilidade
  • podem reduzir o número de árvores necessário

Árvores mais rasas:

  • frequentemente são mais robustas
  • exigem mais rodadas de boosting

Subamostragem (linhas e colunas)

Muitas implementações de impulsionamento por gradiente adicionam aleatoriedade para regularização:

  • Subamostragem de linhas (row subsampling) (subsample): usa uma fração das linhas de treinamento por árvore.
  • Subamostragem de colunas (column subsampling) (colsample_bytree, colsample_bylevel): usa uma fração dos atributos.

Isso às vezes é chamado de impulsionamento por gradiente estocástico (stochastic gradient boosting), e frequentemente melhora a generalização de maneira semelhante ao bagging.

Regularização e restrições

Especialmente em XGBoost/LightGBM:

  • regularização L2/L1 nos pesos das folhas (lambda, alpha)
  • penalidades por criar mais folhas (gamma no XGBoost)
  • restrições monotônicas (úteis em modelos de risco/crédito)
  • parâmetros de número máximo de bins / histograma (afetam velocidade e às vezes a acurácia)

Exemplo prático: boosting como “ajustar resíduos” (regressão)

Aqui está uma ilustração mínima usando o GBDT moderno baseado em histogramas do scikit-learn:

import numpy as np
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.ensemble import HistGradientBoostingRegressor
from sklearn.metrics import mean_squared_error

X, y = fetch_california_housing(return_X_y=True)
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)

model = HistGradientBoostingRegressor(
    learning_rate=0.05,
    max_depth=6,
    max_iter=200,          # number of boosting rounds (trees)
    early_stopping=True,   # uses an internal validation split by default
    random_state=42
)

model.fit(X_train, y_train)
pred = model.predict(X_val)
rmse = mean_squared_error(y_val, pred, squared=False)
print("RMSE:", rmse)

Notas:

  • learning_rate e max_iter fazem trade-off entre si.
  • early_stopping=True evita “chutar” o melhor número de árvores.

Relação com Florestas Aleatórias e Árvores Extra

O impulsionamento por gradiente, Florestas Aleatórias e Árvores Extra (Árvores Extremamente Aleatorizadas) combinam muitas árvores de decisão, mas suas dinâmicas de treinamento e o comportamento viés/variância diferem.

Bagging (Florestas Aleatórias / Árvores Extra)

Florestas aleatórias e árvores extra são métodos de agregação por bootstrap (bagging):

  • As árvores são treinadas independentemente (em paralelo).
  • Cada árvore vê uma amostra bootstrap diferente (RF) e/ou divisões aleatorizadas (Árvores Extra).
  • As predições são promediadas (regressão) ou votadas (classificação).

Isso reduz principalmente a variância (variance) e costuma ser robusto “pronto para uso”, com menos hiperparâmetros sensíveis.

Boosting (Impulsionamento por Gradiente)

O impulsionamento por gradiente é um método de impulsionamento (boosting):

  • As árvores são treinadas sequencialmente, cada uma corrigindo o ensemble atual.
  • O foco é reduzir a perda—frequentemente reduzindo o viés (bias) (enquanto controla a variância via encolhimento/regularização).

Consequências:

  • Em geral alcança maior acurácia em muitos problemas tabulares (com ajuste).
  • É mais sensível a hiperparâmetros (taxa de aprendizado, profundidade, regularização).
  • É menos paralelizável entre árvores (embora cada árvore possa ser construída com paralelismo internamente).

Quando preferir cada um

  • Prefira florestas aleatórias / árvores extra quando você quer:
    • um baseline forte com ajuste mínimo
    • bom desempenho em conjuntos de dados menores
    • paralelismo mais simples e menor risco de superajuste
  • Prefira impulsionamento por gradiente quando você quer:
    • desempenho de ponta em aprendizado supervisionado tabular
    • objetivos flexíveis (perdas customizadas, ranqueamento)
    • forte capacidade de lidar com interações complexas entre atributos

Implementações populares: XGBoost, LightGBM, CatBoost

Bibliotecas modernas adicionam melhorias importantes além da formulação original do impulsionamento por gradiente.

XGBoost

O XGBoost (“Extreme Gradient Boosting”) popularizou GBDTs escaláveis com:

  • otimização de segunda ordem (usa tanto gradientes quanto Hessianas)
  • regularização explícita (L1/L2, penalidades de split)
  • tratamento eficiente de esparsidade e valores ausentes
  • forte suporte a parada antecipada e ferramentas de importância de atributos

Um trecho comum de treinamento:

import xgboost as xgb

dtrain = xgb.DMatrix(X_train, label=y_train)
dval = xgb.DMatrix(X_val, label=y_val)

params = {
    "objective": "reg:squarederror",
    "eta": 0.05,
    "max_depth": 6,
    "subsample": 0.8,
    "colsample_bytree": 0.8,
    "lambda": 1.0,
}

bst = xgb.train(
    params,
    dtrain,
    num_boost_round=5000,
    evals=[(dval, "val")],
    early_stopping_rounds=50,
    verbose_eval=False
)

LightGBM

O LightGBM é otimizado para velocidade e grandes conjuntos de dados:

  • divisões baseadas em histogramas (rápido, eficiente em memória)
  • crescimento de árvore folha-a-folha (leaf-wise) (pode ser mais preciso, mas precisa de restrições como num_leaves)
  • tratamento embutido de valores ausentes
  • forte desempenho em conjuntos de dados “largos”

Como o crescimento folha-a-folha pode criar estruturas muito profundas, é importante controlar a complexidade via num_leaves, min_data_in_leaf e max_depth.

CatBoost

O CatBoost foi projetado para se destacar com atributos categóricos (categorical features) e reduzir vazamento do alvo:

  • tratamento categórico embutido via estatísticas-alvo ordenadas
  • “boosting ordenado” para mitigar deslocamento de predição
  • frequentemente forte desempenho com menos pré-processamento

Se seu conjunto de dados tem muitos categóricos (especialmente de alta cardinalidade), o CatBoost pode ser uma primeira escolha.

Aplicações práticas

O impulsionamento por gradiente é amplamente usado em:

  • pontuação de risco de crédito e detecção de fraude
  • previsão de churn e modelagem de valor do tempo de vida do cliente
  • previsão de taxa de cliques (com cuidado com vazamento)
  • precificação, previsão de demanda (regressão tabular)
  • modelos de risco médico e triagem (com ferramentas de interpretabilidade)
  • muitas competições tabulares no estilo Kaggle

Em muitos pipelines do mundo real, GBDTs são um benchmark forte antes de tentar arquiteturas mais pesadas de aprendizado profundo, especialmente quando os dados não são imagem/texto/áudio.

Fluxo de avaliação e ajuste do modelo

Uma abordagem prática de ajuste:

  1. Comece com um baseline robusto (profundidade moderada, alguma subamostragem).
  2. Use um esquema de validação que corresponda ao problema:
    • divisão aleatória para dados i.i.d.
    • divisão baseada em tempo para dados temporais
    • divisões agrupadas quando entidades se repetem (clientes, dispositivos)
      Veja Validação Cruzada.
  3. Use parada antecipada para encontrar o número efetivo de árvores.
  4. Ajuste:
    • Se houver subajuste: aumente profundidade/folhas, aumente árvores, reduza regularização
    • Se houver superajuste: reduza profundidade/folhas, aumente regularização, adicione subamostragem, diminua a taxa de aprendizado

Uma “região de bons padrões” comum (varia por biblioteca/dados):

  • taxa de aprendizado: 0.03–0.1
  • profundidade: 4–8 (ou folhas: 31–255)
  • subsample/colsample: 0.7–1.0
  • parada antecipada: paciência de 25–200 rodadas dependendo do ruído

Interpretabilidade: importância de atributos, dependência parcial, SHAP

Modelos de boosting com árvores são mais interpretáveis do que muitos modelos profundos, mas menos transparentes do que modelos lineares.

Ferramentas comuns:

  • importância de atributos por split/ganho (split/gain feature importance): rápida, mas pode ser enviesada (por exemplo, em direção a atributos de alta cardinalidade)
  • dependência parcial / ICE (partial dependence / ICE): mostram efeitos marginais (cuidado com atributos correlacionados)
  • valores SHAP (SHAP values): amplamente usados para explicações locais/globais; frequentemente os mais informativos
    Veja SHAP e Importância de Atributos.

Armadilhas e cuidados práticos

  • Vazamento de dados (data leakage): o boosting pode explorar agressivamente sinais mínimos de vazamento. Seja rigoroso com as divisões de validação.
  • Superajuste com árvores profundas: árvores profundas + muitas rodadas podem memorizar; controle profundidade/folhas e use parada antecipada.
  • Calibração ruim de probabilidades (probability calibration): probabilidades de modelos boosted podem estar mal calibradas; considere técnicas de calibração se limiares de decisão importarem (veja Calibração).
  • Tratamento de categóricos:
    • one-hot encoding pode explodir a dimensionalidade para atributos de alta cardinalidade
    • CatBoost frequentemente simplifica isso; caso contrário, considere codificação cuidadosa
  • Extrapolação: modelos de árvore geralmente não extrapolam suavemente fora do intervalo de treinamento.

Resumo

O impulsionamento por gradiente constrói um ensemble sequencialmente, adicionando aprendizes fracos para minimizar uma função de perda via descida do gradiente no espaço de funções. Com árvores de decisão como aprendizes fracos, isso se torna GBDT—uma das famílias de modelos mais eficazes para ML tabular.

Principais pontos:

  • Pense em modelo aditivo: cada árvore é um passo corretivo.
  • Os principais controles de ajuste são taxa de aprendizado, número de árvores e complexidade da árvore.
  • Em comparação com Florestas Aleatórias e Árvores Extra (Árvores Extremamente Aleatorizadas), o impulsionamento por gradiente geralmente é mais preciso, mas mais sensível a ajuste e validação.
  • Implementações modernas (XGBoost, LightGBM, CatBoost) fornecem treinamento de GBDT escalável, regularizado e rico em recursos, dominando muitas tarefas reais com dados estruturados.