Viés aditivo no xgboost (e sua correção?)

9

Estou participando de uma competição no momento. Sei que é meu trabalho fazer isso bem, mas talvez alguém queira discutir meu problema e sua solução aqui, pois isso também pode ser útil para outras pessoas em seu campo.

Treinei um modelo xgboost (um modelo baseado em árvore e um linear e um conjunto dos dois). Como já discutido aqui, o erro médio absoluto (MAE) no conjunto de treinamento (onde eu fiz a validação cruzada) foi pequeno (aprox. 0,3) e, no conjunto de testes, o erro foi de cerca de 2,4. Então a competição começou e o erro foi em torno de 8 (!) E, surpreendentemente, a previsão sempre foi aproximadamente 8-9 acima do valor real !! Veja a região circulada em amarelo na figura:

insira a descrição da imagem aqui

Devo dizer que o período dos dados de treinamento terminou em outubro de 15 e a competição começou agora (abril de 16 com um período de teste de aproximadamente 2 semanas em março).

Hoje, apenas subtraí os valores constantes de 9 da minha previsão e o erro caiu para 2 e consegui o número 3 na tabela de classificação (neste dia). ;) Esta é a parte direita da linha amarela.

Então, o que eu gostaria de discutir:

  • Como o xgboost reage ao adicionar um termo de interceptação à equação do modelo? Isso pode levar a um viés se o sistema mudar muito (como aconteceu no meu caso de 15 de outubro a 16 de abril)?
  • Um modelo xgboost sem interceptação poderia ser mais robusto para mudanças paralelas no valor alvo?

Vou continuar subtraindo meu viés de 9 e, se alguém estiver interessado, eu poderia mostrar o resultado. Seria mais interessante obter mais informações aqui.

Ric
fonte
Parece que você alterou seu modelo manualmente com base nos dados do teste, portanto, é melhor, mas não é reproduzível. Seu modelo está correspondendo muito bem à curvatura dos dados, o motivo do erro nessa região parece estar no início, quando a linha vermelha cai enquanto a linha azul aumenta. Eu tentaria descobrir como modelar esse comportamento.
Winks
@ Winks obrigado por voltar para mim! Devo dizer que houve um período de teste antes da competição e mesmo houve o erro 8-9 e sempre positivo ... portanto, não é apenas a mudança no início da captura de tela, mas aparentemente todo o sistema mudou. Outros concorrentes parecem acertar desde o início ... então sim, talvez eu seja tão ruim ... ou eles usam dados melhores. Fiquei surpreso ao ver esse erro grave agora, enquanto tudo estava tão robusto nos dados de treinamento (e divisão de treinamento / teste e validação x ...).
Ric

Respostas:

3

Vou responder a mim mesmo e informar minhas descobertas caso alguém esteja interessado.

Primeiro o viés: reservei um tempo para coletar todos os dados recentes e formatá-los corretamente, e assim por diante. Eu deveria ter feito isso muito antes. A imagem é a seguinte:

insira a descrição da imagem aqui

Você vê os dados do final de 2015 e 16 de abril. O nível de preços é totalmente diferente. Um modelo treinado em dados de 2015 não pode de forma alguma receber essa alteração.

Segundo: O ajuste do xgboost. Gostei muito da configuração a seguir. O erro train e test está muito próximo agora e ainda é bom:

xgb_grid_1 <- expand.grid(
    nrounds = c(12000),
    eta = c(0.01),
    max_depth = c(3),
    gamma = 1,
    colsample_bytree = c(0.7),
    min_child_weight = c(5) 
  )

  xgb_train_1 <- train(
    x = training,y = model.data$Price[inTrain],
    trControl = ctrl,
    tuneGrid = xgb_grid_1,
    method="xgbTree" 
   ,subsample = 0.8
    )

Portanto, eu uso muitas árvores e todas elas têm no máximo 3 divisões (como recomendado aqui ). Fazendo isso, o cálculo é rápido (o tamanho da árvore aumenta em um fator de 2 a cada divisão) e o super ajuste parece reduzido.

Meu resumo: use árvores com um pequeno número de folhas, mas muitas delas, e procure dados recentes. Para a competição, isso foi uma má sorte para mim ...

Ric
fonte
Obrigado por compartilhar isso (+1). Apenas para perguntar o óbvio em relação ao seu código: você claramente não pesquisa ao longo de uma grade aqui. Apenas treine (e obtenha estatísticas de reamostragem) para uma única configuração de parâmetro. Você se deparou com o "3" usando diferentes valores de parâmetros? O "3" foi ideal com base no RMSE ou em algum outro critério?
precisa saber é o seguinte
@ usεr11852 Nos meus "primeiros dias" com o xgoost, escolhi max_depth muito grande. Se você seguir o link na minha resposta ("aqui"), verá uma discussão. Por fim, acabei de escolher 3. Como indicado no código acima, você pode usar o pacote de interpolação para fazer uma pesquisa em grade; em alternativa, lembro-me de que você pode usar algumas rotinas no xgboost diretamente e recentemente comecei a usar o mlr, que faz o mesmo. Quanto mais ruído você tiver, menor é a profundidade (geralmente apenas 1 ou 2).
Ric
Obrigado pela resposta, mas não é o que estou perguntando no meu comentário: D. Eu li o link ("aqui") antes do meu comentário, mas você não comentou qual a profundidade ideal, com base no seu critério (MAE?), Apenas que " Eu segui seu conselho ... para 3, mas ... ". Então o "3" foi o ideal com base no seu erro RMSE / MAE ou o que mais (discrepância mínima entre teste / erro de treinamento)? Por exemplo, eu rotineiramente pesquiso diretamente a profundidade da árvore, mas talvez você ainda não tenha usado o "3"?
precisa saber é o seguinte
Estritamente em termos de comentários, por que você mudou de caretpara mlr? Para mim, eles parecem comprar bastante sobrepostos, talvez eu esteja perdendo outra coisa.
usεr11852
@ usεr11852 para o primeiro comentário: se esta é uma competição de ML, provavelmente você deve pesquisar a profundidade da grade. Esta foi uma competição de previsão com um sinal claro e, em minha opinião, a escolha de boas características (variáveis ​​climáticas, por exemplo) foi mais crucial. Como o alvo executou uma troca de regime, eu não tinha dados representativos suficientes durante o período perioperatório, então, apenas tomei uma profundidade de três.
Ric