8  Regressão por máquinas de reforço de gradiente

Autor

Robson Bruno Dutra Pereira

8.1 Máquinas de reforço de gradiente

As máquinas de reforço de gradiente (gradient boosting machines - GBM) foram propostas por Gerome Friedman e consistem em um método de aprendizado por reforço que visa aproximar o gradiente da função perda, ou de forma mais simples, visa aproximar o erro de previsão e diminuir este a cada iteração do método. O conceito de aprendizado por reforço está relacionado ao fato de o método de certa forma aprender através do erro, uma vez que vai melhorando a previsão a cada tentativa ou iteração a partir dos valores residuais ou de erro observados. O gradiente ou erro é gradativamente reduzido aproximando-o de forma iterativa considerando uma taxa de aprendizagem. O método foi proposto inicialmente considerando árvores de decisão ou regressão, mas poderia ser utilizado também no caso de regressão por mínimos quadrados.

Um algoritmo GBM simplista do método GBM para regressão é apresentado à seguir:

  1. Defina \(\hat{f}(\mathbf{x})=0\) e \(\varepsilon_i = y_i\) para todos dados de treino.
  2. Para \(m=1,...,M\):
  1. Estime uma árvore, \(\hat{f}_m\), para os dados de treino \((\mathbf{x}_i,\varepsilon_i)\), \(i=1,...,N\);
  2. Atualize \(\hat{f}(\mathbf{x})\) adicionando a árvore de regressão obtida multiplicada por uma taxa de aprendizagem \(\lambda\), isto é, \(\hat{f}(\mathbf{x}) \leftarrow \hat{f}(\mathbf{x}) + \lambda\hat{f}_m(\mathbf{x})\);
  3. Atualize os resíduos, isto é \(\varepsilon_i \leftarrow \varepsilon_i - \lambda\hat{f}_m(\mathbf{x}_i)\), \(i=1,...,N\);
  1. Atualize o modelo “impulsionado” ou “reforçado”: \(\hat{f}(\mathbf{x}) = \sum_{m=1}^M\lambda\hat{f}_m(\mathbf{x})\)

O número de iterações ou árvores consideradas, \(M\), pode ser definido por validação cruzada. A taxa de aprendizado, \(\lambda\), geralmente é um valor real muito pequeno, por exemplo 0,01 ou 0,001 e define a taxa que o modelo por refroço aprende, isto é, melhora sua previsão. Quanto menor \(\lambda\), maior o número de árvores, \(M\), necessário para uma boa aproximação.

Geralmente \(\hat{f}_m(\mathbf{x})\) é um modelo de árvore com apenas uma partição e portanto dois nós terminais ou regiões, sendo portanto um aprendiz fraco (weak leaner). Em alguns casos pode ser interessante modelos com árvores com duas partições, o que de certa forma implica em modelos com interação.

Considerando a função perda quadrática comumente usada em problemas de regressão:

\[ \begin{aligned} L = \frac{1}{2}(y - \hat{f}(\mathbf{x}))^2 \end{aligned} \]

A divisão por 2 viabiliza facilitar os cálculos no algoritmo de boosting. Tomando a derivada de \(L\) em relação a \(f\) obtém-se o valor residual ou erro em relação à resposta de interesse, conforme Equação 8.1.

\[ \begin{aligned} \frac{\partial L}{\partial f} = y - \hat{f}(\mathbf{x}) = \varepsilon \end{aligned} \tag{8.1}\]

Portanto, em cada iteração, o algoritmo GBM, ao aproximar uma árvore considerando \(N\) observações das variáveis regressoras, \(\mathbf{x}_i\), em relação à \(N\) valores residuais, \(\varepsilon_i\), \(i=1,...,N\), aproxima o gradiente da função perda que, no caso da função perda quadrática, é o valor residual ou erro, \(\varepsilon\).

8.1.1 Implementação simplista passo a passo do GBM para regressão

Para entender melhor o algoritmo GBM, considere o conjunto arbitrário de dados de treino da Tabela 8.1, com duas variáveis independentes, \(x_1\) e \(x_2\), e uma dependente contínua, \(y\).

Tabela 8.1: Conjunto de dados arbitrário para regressão
x1 x2 y
-0.08 1.24 2.34
0.84 2.29 2.76
-0.46 2.42 2.34
-0.55 0.71 1.68
0.74 2.07 3.01
-0.11 1.19 1.84
-0.17 3.51 2.61
-1.09 1.73 2.38
-3.01 3.56 2.10
-0.59 1.76 1.75

Consideremos para fins didáticos uma taxa de aprendizagem alta, \(\lambda\) = 0,5, e um número pequeno de iterações, \(M = 4\) árvores. O algoritmo inicia fazendo \(\hat{f}(x_1,x_2)=0\) e \(\varepsilon_i = y_i\), isto é (a penúltima coluna seriam os valores previstos do modelo inicial, \(\hat{f} = f\), e a última coluna seria o erro, \(\varepsilon = e\)), conforme Tabela 8.2.

Tabela 8.2: Previsão e resíduos iniciais do GBM
x1 x2 y f e
-0.08 1.24 2.34 0 2.34
0.84 2.29 2.76 0 2.76
-0.46 2.42 2.34 0 2.34
-0.55 0.71 1.68 0 1.68
0.74 2.07 3.01 0 3.01
-0.11 1.19 1.84 0 1.84
-0.17 3.51 2.61 0 2.61
-1.09 1.73 2.38 0 2.38
-3.01 3.56 2.10 0 2.10
-0.59 1.76 1.75 0 1.75

Fazendo \(m=1\), estima-se a primeira árvore, \(\hat{f} = T\), para os resíduos em função das variáveis independentes, \((x_1,x_2,\varepsilon)_i\), \(i=1,...,N\), conforme segue.

node), split, n, deviance, yval
      * denotes terminal node

1) root 10 1.7560 2.281  
  2) x2 < 1.915 5 0.4505 1.998 *
  3) x2 > 1.915 5 0.5049 2.564 *

O modelo obtido é usado para atualizar os valores previstos, \(\hat{f}(x_1,x_2)\leftarrow \hat{f}(x_1,x_2) + \lambda\hat{f}_1(x_1,x_2)\) e os resíduos, \(\varepsilon_i \leftarrow \varepsilon_i - \lambda\hat{f}_1(x_1,x_2)\), conforme Tabela 8.3.

Tabela 8.3: Previsão e resíduos da primeira iteração do GBM
x1 x2 y f e
-0.08 1.24 2.34 0.999 1.341
0.84 2.29 2.76 1.282 1.478
-0.46 2.42 2.34 1.282 1.058
-0.55 0.71 1.68 0.999 0.681
0.74 2.07 3.01 1.282 1.728
-0.11 1.19 1.84 0.999 0.841
-0.17 3.51 2.61 1.282 1.328
-1.09 1.73 2.38 0.999 1.381
-3.01 3.56 2.10 1.282 0.818
-0.59 1.76 1.75 0.999 0.751

Tomando \(m=2\), repete-se o processo, obtendo-se uma nova árvore para os resíduos e atualizando as previsões e os resíduos, conforme Tabela 8.4.

node), split, n, deviance, yval
      * denotes terminal node

1) root 10 1.1560 1.1400  
  2) x1 < -0.315 5 0.3261 0.9378 *
  3) x1 > -0.315 5 0.4187 1.3430 *
Tabela 8.4: Previsão e resíduos da segunda iteração do GBM
x1 x2 y f e
-0.08 1.24 2.34 1.6706 0.6694
0.84 2.29 2.76 1.9536 0.8064
-0.46 2.42 2.34 1.7509 0.5891
-0.55 0.71 1.68 1.4679 0.2121
0.74 2.07 3.01 1.9536 1.0564
-0.11 1.19 1.84 1.6706 0.1694
-0.17 3.51 2.61 1.9536 0.6564
-1.09 1.73 2.38 1.4679 0.9121
-3.01 3.56 2.10 1.7509 0.3491
-0.59 1.76 1.75 1.4679 0.2821

Para \(m=3\), tem-se os resultados resumidos na Tabela 8.5.

node), split, n, deviance, yval
      * denotes terminal node

1) root 10 0.8475 0.5702  
  2) x2 < 1.915 5 0.4252 0.4490 *
  3) x2 > 1.915 5 0.2753 0.6915 *
Tabela 8.5: Previsão e resíduos da terceira iteração do GBM
x1 x2 y f e
-0.08 1.24 2.34 1.89511 0.44489
0.84 2.29 2.76 2.29934 0.46066
-0.46 2.42 2.34 2.09664 0.24336
-0.55 0.71 1.68 1.69241 -0.01241
0.74 2.07 3.01 2.29934 0.71066
-0.11 1.19 1.84 1.89511 -0.05511
-0.17 3.51 2.61 2.29934 0.31066
-1.09 1.73 2.38 1.69241 0.68759
-3.01 3.56 2.10 2.09664 0.00336
-0.59 1.76 1.75 1.69241 0.05759

Finalmente, para \(m=4\), obtém-se o modelo “reforçado” final que consiste na soma ponderada pela taxa de aprendizagem de todos os modelos, isto é, \(\hat{f}(\mathbf{x}) = \sum_{m=1}^M\lambda\hat{f}_m(\mathbf{x})\), com resultados resumidos na Tabela 8.6.

node), split, n, deviance, yval
      * denotes terminal node

1) root 10 0.7372 0.2851  
  2) x1 < -0.315 5 0.3436 0.1959 *
  3) x1 > -0.315 5 0.3140 0.3744 *
Tabela 8.6: Previsão e resíduos da quarta iteração do GBM
x1 x2 y f e
-0.08 1.24 2.34 2.082286 0.257714
0.84 2.29 2.76 2.486516 0.273484
-0.46 2.42 2.34 2.194589 0.145411
-0.55 0.71 1.68 1.790359 -0.110359
0.74 2.07 3.01 2.486516 0.523484
-0.11 1.19 1.84 2.082286 -0.242286
-0.17 3.51 2.61 2.486516 0.123484
-1.09 1.73 2.38 1.790359 0.589641
-3.01 3.56 2.10 2.194589 -0.094589
-0.59 1.76 1.75 1.790359 -0.040359

Obviamente, o processo poderia seguir para melhorar as previsões. Conforme já elucidado, pode-se definir o número de iterações por validação cruzada. Quanto maior o número de árvores estipulado, recomenda-se que menor seja a taxa de aprendizagem.

Seja um conjunto de dados para prever o rendimento de indivíduos considerando anos de experiência, ocupação, se ele trabalha ou não na indústria, escolaridade, além de fatores sócio-geográficos. Considerando um modelo obtido via GBM com 8000 árvores e \(\lambda = 0,1\), pode-se plotar um gráfico de superfície considerando como variáveis independentes a escolaridade e anos de experiência conforme Figura 8.1.

Figura 8.1: Gráfico de superfície de um modelo GBM para prever rendimento em função da experiência e escolaridade

8.2 Implementações em R

A seguir serão expostas as implementações necessárias para obter os resultados do capítulo.

8.2.1 GBM para regressão passo a passo

Carregando pacotes.

library(AER)
library(gbm)
library(tree)
library(GGally)
library(modelsummary)
library(tidyverse)
library(kernlab)

Entendendo as máquinas de reforço de gradiente com um exemplo arbitrário com 10 observações de treino, duas variáveis independentes, \(x_1\) e \(x_2\), e uma dependente contínua, \(y\).

set.seed(8)
x1 <- rnorm(10)
x2 <- rnorm(10, 2)
y <- 0.3*x1+sqrt(x2)+rnorm(10,1,0.2)

dat <- round(data.frame(x1,x2,y),2)

dat

Seja a taxa de aprendizagem \(\lambda\) = 0.5 e \(M = 4\) árvores ou iterações. A previsão inicial é nula e os resíduos recebem os valores observados da resposta:

dat$f <- 0
dat$e <- dat$y

lambda <- 0.5

dat

Estimanado a primeira árvore para os resíduos.

tree1 <- tree(e ~ x1+x2, dat)
tree1

Atualizando os valores previstos e os resíduos.

pred1 <- predict(tree1, dat)

dat$f <- dat$f + lambda*pred1

dat$e <- dat$e -lambda*pred1

dat

Na segunda iteração, repete-se o processo, obtendo-se uma nova árvore para os resíduos e atualizando as previsões e os resíduos. Pode-se constatar que a cada iteração vamos melhorando os valores previstos e, portanto, diminuindo os valores residuais.

tree2 <- tree(e ~ x1+x2, dat)
tree2
pred2 <- predict(tree2, dat)

dat$f <- dat$f + lambda*pred2

dat$e <- dat$e -lambda*pred2

dat

Na terceira iteração, tem-se:

tree3 <- tree(e ~ x1+x2, dat)
tree3
pred3 <- predict(tree3, dat)

dat$f <- dat$f + lambda*pred3

dat$e <- dat$e -lambda*pred3

dat

Finalmente, na quara e última iteração, obtém-se o modelo “reforçado” final que consiste na soma ponderada pela taxa de aprendizagem de todos os modelos.

tree4 <- tree(e ~ x1+x2, dat)
tree4
pred4 <- predict(tree4, dat)

dat$f <- dat$f + lambda*pred4

dat$e <- dat$e -lambda*pred4

dat

8.2.2 Previsão do rendimento em função da escolaridade, experiência e outras variáveis sócio-geográficas

Seja um conjunto de dados para prever o rendimento de indivíduos considerando anos de experiência, ocupação, se ele trabalha ou não na indústria, escolaridade, além de fatores sócio-geográficos.

data(PSID7682)
# ?PSID7682
dados <- PSID7682
dados <- dados[,-c(13:14)]

library(modelsummary)
datasummary_skim(dados)
Unique Missing Pct. Mean SD Min Median Max Histogram
experience 51 0 19.9 11.0 1.0 18.0 51.0
weeks 41 0 46.8 5.1 5.0 48.0 52.0
education 14 0 12.8 2.8 4.0 12.0 17.0
wage 1017 0 882.9 442.8 100.0 800.0 5100.0
N %
occupation white 2036 48.9
blue 2129 51.1
industry no 2518 60.5
yes 1647 39.5
south no 2956 71.0
yes 1209 29.0
smsa no 1442 34.6
yes 2723 65.4
married no 773 18.6
yes 3392 81.4
gender male 3696 88.7
female 469 11.3
union no 2649 63.6
yes 1516 36.4
ethnicity other 3864 92.8
afam 301 7.2

Separando metade das observações para treino do modelo.

set.seed(78)
tr <- round(0.5*nrow(dados))
treino <- sample(nrow(dados), tr, replace = F)

Obtendo um modelo via GBM com 10000 árvores e \(\lambda = 0,1\).

boost1 <- gbm(log(wage)~., data = dados, distribution = "gaussian", 
              n.trees = 10000, bag.fraction = 0.7, 
              interaction.depth =  2, shrinkage = 0.1)
summary(boost1)

                  var   rel.inf
experience experience 29.285767
education   education 23.061164
weeks           weeks 16.194209
gender         gender  6.516940
smsa             smsa  4.849954
occupation occupation  4.713714
union           union  4.660501
south           south  3.456731
industry     industry  3.010622
married       married  2.534908
ethnicity   ethnicity  1.715492
metrics <- function(obs, pred) {
  
  RSE <- sum((obs - pred)^2)
  SST <- sum((obs - mean(obs))^2)
  R2 <- 1 - RSE/SST 
  
  MAE <-  mean(abs(obs - pred))
  
  RMSE <- sqrt(mean((obs - pred)^2))
  
  return(
    data.frame(RMSE = RMSE,
               MAE = MAE,
               R2 = R2))
}

Desempenho de treino.

pred <- predict(boost1, dados[treino,])
Using 10000 trees...
metrics(log(dados$wage[treino]),pred)
       RMSE       MAE        R2
1 0.2803965 0.2171146 0.6402183

Testando o modelo.

pred1 <- predict(boost1, dados[-treino,])
Using 10000 trees...
metrics(log(dados$wage[-treino]),pred1)
       RMSE       MAE        R2
1 0.2752103 0.2104087 0.6347375

Referências

Hastie, T., Tibshirani, R., Friedman, J. H., & Friedman, J. H. (2009). The elements of statistical learning: data mining, inference, and prediction (Vol. 2, pp. 1-758). New York: springer.

Gareth, J., Daniela, W., Trevor, H., & Robert, T. (2013). An introduction to statistical learning: with applications in R. Spinger.