A precisão da máquina de aumento de gradiente diminui à medida que o número de iterações aumenta

15

Estou experimentando o algoritmo da máquina de aumento de gradiente através do caretpacote em R.

Usando um pequeno conjunto de dados de admissões de faculdade, executei o seguinte código:

library(caret)

### Load admissions dataset. ###
mydata <- read.csv("http://www.ats.ucla.edu/stat/data/binary.csv")

### Create yes/no levels for admission. ### 
mydata$admit_factor[mydata$admit==0] <- "no"
mydata$admit_factor[mydata$admit==1] <- "yes"             

### Gradient boosting machine algorithm. ###
set.seed(123)
fitControl <- trainControl(method = 'cv', number = 5, summaryFunction=defaultSummary)
grid <- expand.grid(n.trees = seq(5000,1000000,5000), interaction.depth = 2, shrinkage = .001, n.minobsinnode = 20)
fit.gbm <- train(as.factor(admit_factor) ~ . - admit, data=mydata, method = 'gbm', trControl=fitControl, tuneGrid=grid, metric='Accuracy')
plot(fit.gbm)

e descobri, para minha surpresa, que a precisão da validação cruzada do modelo diminuiu em vez de aumentar à medida que o número de iterações de aumento aumentou, atingindo uma precisão mínima de cerca de 0,59 em ~ 450.000 iterações.

insira a descrição da imagem aqui

Eu implementei o algoritmo GBM incorretamente?

EDIT: Seguindo a sugestão do Underminer, executei novamente o caretcódigo acima , mas foquei em executar de 100 a 5.000 iterações de aprimoramento:

set.seed(123)
fitControl <- trainControl(method = 'cv', number = 5, summaryFunction=defaultSummary)
grid <- expand.grid(n.trees = seq(100,5000,100), interaction.depth = 2, shrinkage = .001, n.minobsinnode = 20)
fit.gbm <- train(as.factor(admit_factor) ~ . - admit, data=mydata, method = 'gbm', trControl=fitControl, tuneGrid=grid, metric='Accuracy')
plot(fit.gbm)

O gráfico resultante mostra que a precisão atinge o pico de aproximadamente 0,705 a ~ 1.800 iterações:

insira a descrição da imagem aqui

O curioso é que a precisão não alcançou ~ 0,70, mas declinou após 5.000 iterações.

RobertF
fonte

Respostas:

14

Em geral, o erro de aumento pode aumentar com o número de iterações, especificamente quando os dados são barulhentos (por exemplo, casos com erros de etiqueta). Esse pode ser o seu problema, mas eu não poderia dizer sem saber mais sobre seus dados

Basicamente, o aumento pode 'focar' na previsão correta de casos que contêm informações erradas e, no processo, deteriora o desempenho médio em outros casos mais substanciais.

Esse link ( Boosting and Noise ) mostra uma descrição melhor do que eu posso fornecer sobre o problema.

Este artigo ( Ruído de classificação aleatória ) de Long e Servedio fornece mais detalhes técnicos do problema.

Minador
fonte
16

O que você exibiu é um exemplo clássico de sobreajuste. O pequeno aumento no erro vem do desempenho inferior na parte de validação do seu conjunto de dados com validação cruzada. Mais iterações quase sempre melhoram o erro no conjunto de treinamento, mas o oposto é verdadeiro para o conjunto de validação / teste.

Ryan Zotti
fonte
Então, overfits de aumento de gradiente com base no número de iterações de aumento? Interessante. Eu pensei que a precisão teria atingido o nível máximo depois de atingir o número ideal de iterações.
precisa saber é o seguinte
4
Está correto. No aumento de gradiente, cada árvore subsequente é construída a partir dos resíduos das árvores anteriores, portanto o GBM continuará tentando eliminar o erro restante no conjunto de dados de treinamento, mesmo com o custo de poder generalizar para conjuntos de validação / teste. É por isso que você executar a validação cruzada - porque o algoritmo de ajuste não nativamente saber quando parar
Ryan Zotti
11
O Gradient Boosting é inspirado no AdaBoost. O AdaBoost muito raramente se adapta e, quando isso acontece, é apenas um pouco e depois de muitas, muitas iterações. Eu acho que a explicação do @Underminer é mais provável que seja representativa do que está acontecendo do que este comentário, especialmente considerando que não há referências neste comentário.
Ricardo Cruz
2
@RicardoCruz Eu acho interessante que você raramente tenha visto um super ajuste de gradiente. Ao longo dos quatro anos em que o uso, vi o oposto - muitas árvores levam ao sobreajuste. Certa vez, tive que provar algo semelhante a um colega e pude reduzir o erro no conjunto de treinamento para quase zero, mas o erro de validação aumentou significativamente mais do que o do GBM sem ajuste excessivo. Ainda acho que o aumento de gradiente é um ótimo algoritmo. É geralmente o primeiro uso algoritmo I - você apenas tem que ter cuidado com muitas árvores, que você pode acompanhar via validação cruzada
Ryan Zotti
2
@RyanZotti Estou corrigido então. Li vários artigos sobre o AdaBoost de Schapire et al., Porque desfruto de sua bela e forte base teórica. Os autores argumentam que impulsionar é propenso a sobreajuste, mas que é extremamente difícil. Eu não tenho muita experiência em usá-lo, e eles não têm uma base teórica sólida para argumentar sobre isso, e, é claro, autores são autores, eles são naturalmente zelosos de sua invenção, portanto, se você tiver experiência em contrário , Eu estou corrigido.
Ricardo Cruz
4

Códigos para reproduzir um resultado semelhante, sem pesquisa na grade,

mod = gbm(admit ~ .,
      data = mydata[,-5],
      n.trees=100000,
      shrinkage=0.001,
      interaction.depth=2,
      n.minobsinnode=10,
      cv.folds=5,
      verbose=TRUE,
      n.cores=2)

best.iter <- gbm.perf(mod, method="OOB", plot.it=TRUE, oobag.curve=TRUE, overlay=TRUE)
print(best.iter)
[1] 1487
pred = as.integer(predict(mod, newdata=mydata[,-5], n.trees=best.iter) > 0)
y = mydata[,1]
sum(pred == y)/length(y)
[1] 0.7225
horaceT
fonte
3

O pacote gbm tem uma função para estimar o número ideal de iterações (= número de árvores ou número de funções básicas),

gbm.perf(mod, method="OOB", plot.it=TRUE, oobag=TRUE, overlay=TRUE)

Você não precisa do trem de interdição para isso.

horaceT
fonte
Não sei se isso resolve o problema que estou tendo - parece que o número ideal de iterações é 5.000 no meu caso, onde a precisão é mais alta, perto de 0,70 (o primeiro ponto de dados no meu gráfico). Mas isso parece errado. Mais iterações devem levar a uma maior precisão, não menor, certo?
precisa saber é o seguinte
11
@RobertF Primeiro, acho que você não precisa transformar admitir em um fator. Funciona da mesma forma: mod = gbm (admitir ~., Dados = mydata [, - 5], n.trees = 100000, encolhimento = 0,001, interação.depth = 2, n.minobsinnode = 10, cv.folds = 5 , detalhado = TRUE, n.cores = 2). Você pode ver onde o gbm escolhe o iter ideal: best.iter <- gbm.perf (mod, método = "OOB", plot.it = TRUE, oobag.curve = TRUE, overlay = TRUE). Ou seja, quando a mudança no desvio se torna negativa (veja o gráfico gerado a partir disso).
precisa saber é o seguinte
11
@RobertF Mais uma coisa. Ao especificar n.trees = (um milhão) na chamada gbm, você executaria todos os números de iterações de 1 a 1.000.000. Então você não precisa de sinal de intercalação para fazer isso por você.
precisa saber é
11
@RobertF Mais acompanhamento. Acabei de executar 100k árvores / iterações. A precisão que obtive ao escolher a melhor iteração com gbm.perf é 0,7225, o que é bastante próximo do seu executando uma grade completa de iterações.
precisa saber é o seguinte