O desempenho da validação cruzada será uma indicação precisa para prever o verdadeiro desempenho em um conjunto de dados independente?

9

Sinto que esta questão está relacionada à teoria por trás da validação cruzada. Apresento aqui minha descoberta empírica e escrevi uma pergunta relacionada à teoria da validação cruzada .

Eu tenho dois modelos M1 e M2, uso o mesmo conjunto de dados para treiná-los e execute a validação cruzada usando o mesmo conjunto de dados para encontrar os parâmetros ideais para cada modelo. Digamos que, eventualmente, eu descobri que M1 sob seu parâmetro ideal, tem um desempenho melhor que M2 sob seu parâmetro ideal em termos de 10 vezes a pontuação de validação cruzada. Agora, se eu tiver outro conjunto de dados de teste independente com preditores e rótulos e esse conjunto de dados de teste for gerado a partir da mesma distribuição do meu conjunto de dados de treinamento, antes de aplicar esses dois modelos bem ajustados nesse novo conjunto de dados de teste, posso reivindicar ou devo esperar que o M1 ainda tenha um desempenho melhor que o M2 nesse novo conjunto de dados de teste?

Eu estava jogando o exemplo do Kaggle Titanic. Eu tenho 2 modelo xgboost, M1 está bem ajustado e M2 está menos bem ajustado, no sentido de que M1 tem uma melhor validação cruzada de 10 vezes, realizada no conjunto de dados de treinamento. Porém, quando enviei os dois, descobri que o modelo menos ajustado realmente tem melhores pontuações no conjunto de dados de teste. Como poderia ser? E se for verdade, o que devemos procurar quando ajustamos os dados em diferentes modelos e ajustamos os parâmetros do modelo?

Aqui estão meus resultados de envio específicos: fiz uma pesquisa em grade aleatória

params_fixed = {'silent': 1,'base_score': 0.5,'reg_lambda': 1,
'max_delta_step': 0,'scale_pos_weight':1,'nthread': 4,
'objective': 'binary:logistic'}
params_grid = {'max_depth': list(np.arange(1,10)),
'gamma': [0,0.05,0.1,0.3, 0.5,0.7,0.9],
'n_estimators':[1,2,5,7,10,15,19,25,30,50], 
'learning_rate': [0.01,0.03,0.05,0.1,0.3,0.5,0.7,0.9,1],
'subsample': [0.5,0.7,0.9], 'colsample_bytree': [0.5,0.7,0.9], 
'min_child_weight': [1,2,3,5], 'reg_alpha': [1e-5, 1e-2, 0.1, 0.5,1,10]
}
rs_grid = RandomizedSearchCV(
          estimator=XGBClassifier(**params_fixed, seed=seed),
          param_distributions=params_grid,
          n_iter=5000,   
          cv=10,
          scoring='accuracy',
          random_state=seed
)

Cada vez que eu mudo a variável n_iter. Primeiro, eu defino n_iter=10, ele me fornece um conjunto de valores desses hiper parâmetros, vamos chamar esse vetorα1e a pontuação cv (taxa de precisão) é 0,83389 , então eu usoα1para treinar meu modelo e gerar previsão no conjunto de dados de teste independente e, quando envio ao Kaggle, ele gera uma precisão verdadeira no conjunto de dados de teste 0.79426

Segundo, defino n_iter=100, isso me dáα2e o escore cv é 0,83614 , ou seja, maior que o primeiro, faz sentido, mas quando me submeto a Kaggle, 0,78469 , menor que o primeiro.

Terceiro, defino n_iter = 1000, isso me dáα3e a pontuação cv é 0,83951 , ou seja, maior que o segundo, faz sentido, mas quando me submeto ao Kaggle, 0,77990 , menor que o segundo.

Quarto, eu defino n_iter = 5000, isso me dáα4e a pontuação cv é 0,84512 , ou seja, maior que o terceiro, faz sentido, mas quando me submeto a Kaggle, 0,72249 , menor que o terceiro.

Isso é realmente frustrado. O modelo está cada vez melhor na pontuação de validação cruzada, mas quando executado em um conjunto de dados independente real, seu desempenho está ficando cada vez pior. Interpretei as pontuações do CV da maneira exatamente oposta? Vejo algum artigo mencionado que a pontuação do CV pode ser otimista demais para inferir a verdadeira pontuação do teste. No entanto, mesmo que isso seja verdade, acho que as pontuações de CV para todos os meus quatro modelos devem ser otimistas quanto à sua própria pontuação de teste, ou seja, a ordem deve preservar. Mas, ao aplicar no conjunto de dados de teste real, a ordem foi revertida.

A única razão pela qual posso imaginar seria que o conjunto de dados de teste tem uma distribuição diferente do conjunto de dados de treinamento. No entanto, se for esse o caso, acredito que não exista um método sob o sol que possa curar esse problema.

KevinKim
fonte

Respostas:

3

Primeiro, uma resposta pragmática: não descarte a possibilidade de que o conjunto de testes venha de uma distribuição um pouco diferente do conjunto de dados que você está usando para treinamento e validação cruzada. Você pode pensar que isso não deveria acontecer, mas na prática parece ocorrer.

Dito isso, vamos prosseguir com sua hipótese e assumir que o conjunto de testes vem exatamente da mesma distribuição que o restante dos seus dados. Nesse caso, é possível que a validação cruzada o desvie de qual modelo é melhor, se você estiver usando a validação cruzada para selecionar hiperparâmetros.

Você pode usar a validação cruzada para (a) selecionar hiperparâmetros ou (b) estimar a precisão do seu modelo - mas não os dois ao mesmo tempo.

Parece que você está usando a validação cruzada para selecionar os hiperparâmetros ideais: você tenta várias opções diferentes para os hiperparâmetros, para cada estimativa estimar a precisão dessa escolha usando a validação cruzada e seleciona a melhor opção. Quando você faz isso, não há garantia de que a precisão resultante (com o melhor parâmetro) seja preditiva do desempenho no conjunto de testes - pode ser uma superestimação (devido ao excesso de ajuste). Se é mais uma superestimação para M1 que M2, então você pode ver o que viu.

Se você deseja selecionar hiperparâmetros e estimar a precisão, sugiro que você tenha um conjunto de validação independente separado para estimar a precisão ou use a validação cruzada aninhada. Consulte https://stats.stackexchange.com/q/65128/2921 e http://scikit-learn.org/stable/auto_examples/model_selection/plot_nested_cross_validation_iris.html .

DW
fonte
Você conhece outra referência mais teórica (do lado da teoria das probabilidades) que explica por que um CV aninhado é necessário que um CV simples para a seleção de modelos? Eu quero entender o mecanismo subjacente que leva ao problema que eu encontrei
KevinKim
1
Sugiro também o uso de validação cruzada aninhada. se você estiver criando um CV externo de 3 vezes e um CV interno de 10 vezes, poderá testar os 3 modelos que você treina durante os CV internos em três conjuntos de dados diferentes; isso lhe dará uma melhor compreensão de como o processo de criação do modelo terminará quando encontrar conjuntos de dados diferentes.
DarXider # 27/17
@darXider Eu li alguns dos CV aninhados, parece que ele é usado para comparar duas classes de modelos, por exemplo, RF e GBT, de modo que, no CV interno, ele escolhe os "melhores" (menores erros de CV) dos hiperparâmetros RF e GBT respectivamente, depois no CV externo, calcula o erro de generalização de RF e GBT com os hiperparâmetros escolhidos pelo CV interno. No meu caso, eu só tenho uma classe de modelo, GBT, quero executar o ajuste de hiperparâmetro. Como o cested aninhado me ajuda a fazer isso?
KevinKim
@KevinKim AFAIK, o objetivo do CV aninhado é dar uma idéia de como o processo de construção do modelo será generalizado e não comparar diferentes classes de modelos. Como seu objetivo final é usar o modelo treinado (RF ou XGB) em dados futuros / não vistos, você poderá entender melhor seu desempenho se usar o CV aninhado. Obviamente, você também faz o ajuste de hiperparâmetro no seu CV aninhado 3x10; no final, você terá, digamos, três modelos XGB equivalentes entre si (observe que você não deve escolher um dos três, mas pode combiná-los, digamos, usando vários métodos de montagem).
DarXider # 29/17
1

posso reivindicar ou devo esperar que o M1 ainda tenha um desempenho melhor que o M2 nesse novo conjunto de dados de teste?

Sim você deveria. Claro que sob as condições que

  1. os dados de teste provêm do mesmo processo de geração que os dados de treinamento e validação, e
  2. você tem dados suficientes em cada conjunto para tornar improváveis ​​as flutuações estatísticas.

O modelo está cada vez melhor na pontuação de validação cruzada, mas quando executado em um conjunto de dados independente real, seu desempenho está ficando cada vez pior.

Eu posso pensar em duas razões:

  1. O conjunto de dados de teste não é realmente gerado da mesma maneira. Portanto, é melhor não confiar no conjunto de testes Kaggle ao qual você não tem acesso. Use os dados que você possui.

  2. Você está em excesso, o que significa que não está executando a validação cruzada corretamente. Certifique-se de que o treinamento dos parâmetros ocorra nos dados do treinamento e, ao mesmo tempo, que a validação ocorra nos dados que você não usou para o treinamento. Compare os histogramas das perdas de treinamento e as perdas de validação. As perdas de treinamento devem ser consistentemente menores que as perdas de validação. Faça o mesmo com as perdas nos dados de teste para obter uma imagem consistente.

Nota final e final: Espera-se que o desempenho no conjunto de testes seja inferior ao desempenho no conjunto de validação. Isso ocorre porque o modelo é escolhido com base no conjunto de validação. Portanto, é tendencioso para esse conjunto de dados.

Ytsen de Boer
fonte
Eu tenho o código no meu post, acho que não utilizei mal o procedimento CV (você encontrou algo errado com o meu código?). E eu realmente vi que o erro de treinamento é muito menos e estável (com std pequeno) do que o erro de validação. Entendo que o verdadeiro erro de teste será maior que o erro de validação, mas espero que isso também aconteça com todo o meu modelo (refiro-me ao XBGT com diferentes valores dos hiperparâmetros). Pelo que vi, parece que alguns modelos acontecem menos do que outros, o que cria esse "fenômeno reverso". Então, eu não sei que direção Estou procurando sintonizar hyperpara
KevinKim
Eu já vi muitas pessoas sugerirem quebrar o Dem 3 partes, treinamento, validação e teste e depois de ajustar o hyperP no conjunto de validação, aplique o modelo no conjunto de testes para ver como esse modelo será executado em um teste real (como a etapa de validação também possui algum viés). Depois do teste, pare de ajustar o hyperP, como se você fizer isso, ele também começará a sofrer viés (como no conjunto de validação). Entendi. Mas se, após o teste, ainda estiver insatisfeito com o desempenho do meu modelo, o que devo fazer?
KevinKim
Penso que, na prática, embora vivamos em um mundo de "big data", o número de recursos também está aumentando. Como temos a maldição da dimensão, é muito provável que tenhamos um grande número de linhas, ainda para cada parte do espaço de recursos, ainda não temos pontos de dados suficientes. Então a flutuação estatística está sempre lá. Então, estou questionando se esse procedimento de ajuste de hiperP ainda está correto ou útil para obter um modelo com bom desempenho no conjunto de dados de teste real? Se o CV não for útil para executar esta tarefa, qual é o procedimento correto?
KevinKim
Verifique se as perdas de treinamento no seu procedimento de validação são comparáveis ​​entre si, ou seja, consistentes. Caso contrário, tente outra seleção de modelo / recurso. Não continue até que você tenha esse direito. Em seguida, faça o mesmo por suas perdas de validação. Se não forem comparáveis, tente outro método de seleção / modelo de validação / modelo. Quando estiverem, prossiga para o conjunto de testes. Se a perda não satisfizer você, rejeite o procedimento completo e tente outra coisa. Se você começar a otimizar usando o conjunto de testes, não poderá confiar na performance ao vivo, pois ela será influenciada pelo conjunto de testes.
Ytsen de Boer
0

É possível. Pense em um cenário simples em que o modelo M1aprendeu melhor a variação do conjunto de dados de treinamento do Dque o modelo, M2pois seus parâmetros são melhor ajustados. Isso significa um M1desempenho melhor Dque M2.

Mas quando os testamos no conjunto de testes T, é possível que ele tenha um M2desempenho melhor, pois M1pode estar se ajustando excessivamente Denquanto M2não estava. Portanto, M1executa pior Tque M2.

Isso pode ser devido ao fato de você ter realizado sua validação cruzada no mesmo conjunto de dados em vez de um conjunto de validação. Se você treinar e validar no mesmo conjunto, é provável que perca o fato de que isso pode estar se adaptando demais. Portanto, é sempre melhor treinar, validar e testar em diferentes conjuntos de dados. Então o fluxo deve ser

  1. Treine modelos diferentes no mesmo conjunto de treinamento
  2. Validado no conjunto de validação
  3. Escolha o melhor desempenho com base no modelo no conjunto de validação
  4. Use-o para pontuar seu conjunto de testes.
Santoshi M
fonte
Embora a validação cruzada no conjunto de dados Djá tenha levado em conta os problemas de sobreajuste. Entendo que, se você não realizar a validação cruzada, ou seja, basta ajustar o modelo no conjunto de dados De resolver o problema de otimização e obter os parâmetros ideais, esse modelo terá o menor erro de trem e é muito provável um sobreajuste. Nesse caso, concordo que esse optimizedmodelo tenderá a ter um desempenho ruim em um conjunto de dados de teste independente. Mas acho que esse problema foi tratado pela validação cruzada no conjunto de dados D, não é?
KevinKim
1
Especificamente, quando você cria um CV de 10 vezes D, primeiro você corta aleatoriamente Dem aproximadamente 10 pedaços de tamanho igual e, em cada iteração, ajusta M1 e M2 no mesmo 9/10 de D, em seguida, aplica-os da mesma maneira 1 / 10 Dpara obter o seu test error, em seguida, repita esse processo 10 vezes e a cada vez, o conjunto de trens e o conjunto de testes são diferentes da iteração anterior. Depois de 10 iterações, você calcula a média do erro de teste para M1 e M2, e descobre que M1 tem menos erro de teste. Não basta concluir que M1 é melhor que M2 e esse procedimento parece já ter
resolvido o excesso de ajuste
Sim, basta concluir que "M1 é melhor que M2". Porém, se o procedimento de seleção do modelo se resumir à seleção de M1 com base no desempenho da validação , sua escolha do melhor modelo (M1 neste caso) será influenciada pelo conjunto de validação. Daí a necessidade de uma verificação final no conjunto de testes, para obter uma indicação de quão bem ele será executado nos dados ativos.
Ytsen de Boer
@YtsendeBoer Finalmente me convenci do que você disse. Concordo. Mas se, em outro conjunto de testes independente, eu descobrir que M1 é pior que M2 (lembre-se de que M1 é melhor que M2 no conjunto de validação), nesse caso, devo escolher M1 ou M2 como meu modelo final para fazer previsões reais no futuro? Se eu escolher M1, então claramente o resultado do teste será M1. Mas se eu escolher o M2, o M2 também não se ajustaria neste conjunto de dados de teste específico? ou seja, da mesma maneira que o ajuste M1 no conjunto de validação específico?
precisa saber é o seguinte
Sim, é exatamente por isso que você não deve fazer a seleção de modelos no conjunto de testes. Você escolheu M1 no procedimento de seleção de modelo usando o conjunto de validação. Em seguida, você executa M1 no conjunto de testes e decide se o resultado é bom o suficiente. Esqueça o M2 neste momento, mesmo que tenha um desempenho melhor em outro conjunto de testes. Se, no entanto, você tiver dúvidas sobre seus resultados, adicione seu "outro conjunto de testes independente" ao restante dos dados (mais dados são melhores), inicie o procedimento novamente e siga-o .
Ytsen de Boer
0

A teoria por trás da validação cruzada (validação cruzada em V) foi abordada em muitos artigos. Há uma prova disso em um conjunto de documentos publicados de 2003 a 2007. Por favor, consulte: - oracle selector. 2006 - super aprendiz 2007 - super aprendiz na previsão 2010 - validação cruzada unificada 2003

Bashar Haddad
fonte