Como obter hiper parâmetros na validação cruzada aninhada?


16

Li as seguintes postagens para validação cruzada aninhada e ainda não tenho 100% de certeza do que devo fazer com a seleção de modelo com validação cruzada aninhada:

Para explicar minha confusão, deixe-me tentar percorrer a seleção do modelo com o método de validação cruzada aninhada passo a passo.

  1. Crie um loop de CV externo com o K-Fold. Isso será usado para estimar o desempenho dos hiperparâmetros que "venceram" cada loop interno do CV.
  2. Use o GridSearchCV para criar um loop CV interno, onde, em cada loop interno, o GSCV percorre todas as combinações possíveis do espaço de parâmetros e cria o melhor conjunto de parâmetros.
  3. Depois que o GSCV encontrou os melhores parâmetros no loop interno, ele é testado com o conjunto de testes no loop externo para obter uma estimativa do desempenho.
  4. O loop externo é atualizado para a próxima dobra como conjunto de teste e o restante como conjunto de treinamento, e 1-3 repetições. O total possível de parâmetros "vencedores" é o número de dobras designadas no loop externo. Portanto, se o loop externo tiver 5 dobras, você terá uma estimativa de desempenho de um algoritmo com 5 conjuntos diferentes de hiper parâmetros, NÃO o desempenho de um conjunto específico de hiper parâmetros.

Essa abordagem é ilustrada na página de exemplo do SKLearn: http://scikit-learn.org/stable/auto_examples/model_selection/plot_nested_cross_validation_iris.html

Pergunta: Após 4. , como você determina quais hiper parâmetros funcionaram melhor? Entendo que você deseja treinar seu algoritmo (por exemplo, regressão logística, floresta aleatória etc.) com o conjunto de dados COMPLETO no final. Mas como você determina quais hiper parâmetros funcionaram melhor em sua validação cruzada aninhada? Meu entendimento é que, para cada loop interno, um conjunto diferente de hiper parâmetros vencerá. E para o loop externo, você está obtendo uma estimativa do desempenho do GridSearchCV, mas não está obtendo nenhum conjunto específico de hiper parâmetros. Então, na criação do modelo final, como você sabe quais hiper parâmetros usar? Essa é a lógica que falta, que tenho dificuldade em entender de outras etapas.

Agradecemos antecipadamente por qualquer dica, especialmente se @Dikran Marsupial e @cbeleites puderem participar!

Editar: se puder, em sua resposta, use termos como "algoritmo" e "hiper parâmetros". Eu acho que uma fonte de confusão para mim é quando as pessoas usam o termo "modelo" ou "seleção de modelo". Fico confuso se eles estão falando sobre a seleção de qual algoritmo usar ou quais hiper parâmetros usar.

Edit 2: Criei um notebook que mostra duas maneiras de fazer a validação cruzada aninhada. A primeira maneira é a mostrada no exemplo do SKLearn, e a outra mais longa é a que escrevi. A maneira mostrada no SKLearn não expõe os hiperparâmetros "vencedores", mas a minha maneira mais longa sim. Mas a questão permanece a mesma. Depois de concluir a validação cruzada aninhada, mesmo com os hiperparâmetros expostos, o que faço agora? Como você pode ver pelos hiperparâmetros no final do notebook, eles variam bastante.


1
+1 para o notebook. Esta pergunta também é interessante para mim e continuará.
Arnold Klein

Respostas:


6

(Tenho certeza de que já escrevi a maior parte disso em alguma resposta - mas não consigo encontrá-la agora. Se alguém se deparar com essa resposta, vincule-a). Eu vejo duas abordagens ligeiramente diferentes aqui, que eu acho que são sensatas.

Mas primeiro alguma terminologia:

  • Vindo de um campo aplicado, um modelo (equipado / treinado) para mim é um pronto para uso. Ou seja, o modelo contém todas as informações necessárias para gerar previsões para novos dados. Assim, o modelo também contém os hiperparâmetros . Como você verá, esse ponto de vista está intimamente relacionado à abordagem 2 abaixo.
  • OTOH, na minha experiência , o algoritmo de treinamento não está bem definido no seguinte sentido: para obter o modelo (ajustado), não apenas o - vamos chamá-lo de "ajuste primário" - dos parâmetros do modelo "normal" precisa ser feito, mas também os hiperparâmetros precisam ser corrigidos. Do meu ponto de vista da aplicação, não há realmente muita diferença entre parâmetros e hiperparâmetros: ambos fazem parte do modelo e precisam ser estimados / decididos durante o treinamento.
    Eu acho que a diferença entre eles está relacionada à diferença entre alguém que desenvolve novos algoritmos de treinamento que normalmente descrevem uma classe de algoritmos de treinamento junto com alguns parâmetros de direção (os hiperparâmetros) que são difíceis / impossíveis de corrigir (ou pelo menos para corrigir como devem ser decididos / estimados) sem o conhecimento do aplicativo / domínio.

Abordagem 1: exigir resultados de otimização estáveis

Com essa abordagem, o "treinamento do modelo" é o ajuste dos parâmetros do modelo "normal" e são fornecidos hiperparâmetros . Uma validação cruzada interna, por exemplo, cuida da otimização do hiperparâmetro.

A etapa / suposição crucial aqui para resolver o dilema cujo conjunto de hiperparâmetros deve ser escolhido é exigir que a otimização seja estável . A validação cruzada para fins de validação pressupõe que todos os modelos substitutos sejam suficientemente semelhantes ao modelo final (obtido pelo mesmo algoritmo de treinamento aplicado a todo o conjunto de dados) para permitir tratá-los como iguais (entre si e com o modelo final). Se essa suposição se quebrar e

  1. Como os modelos substitutos ainda são iguais (ou equivalentes) entre si, mas não ao modelo final, estamos falando do conhecido viés pessimista da validação cruzada.

  2. Se também o modelo substituto não é igual / equivalente um ao outro, temos problemas com instabilidade .

Para os resultados de otimização do loop interno, isso significa que, se a otimização for estável, não haverá conflito na escolha de hiperparâmetros . E se uma variação considerável for observada nos resultados da validação cruzada interna, a otimização não será estável . As situações instáveis ​​de treinamento têm problemas muito piores do que apenas a decisão de qual parâmetro é escolhido, e eu realmente recomendo dar um passo atrás nesse caso e iniciar o processo de modelagem novamente.

Há uma exceção aqui: porém, pode haver vários mínimos locais na otimização, produzindo desempenho igual para fins práticos. Exigir também que a escolha entre eles seja estável pode ser um forte requisito desnecessário - mas não sei como sair desse dilema.

Observe que se nem todos os modelos produzirem o mesmo conjunto de parâmetros vencedor, você não deve usar estimativas de loop externo como erro de generalização aqui:

  • p
  • Mas, a menos que não haja decisão envolvida, pois todas as divisões produziram os mesmos parâmetros, isso quebrará a independência no loop externo: os dados de teste de cada divisão já entraram na decisão de qual conjunto de parâmetros vence, pois treinavam dados em todas as outras divisões e, portanto, utilizados para otimizar os parâmetros.

Abordagem 2: trate o ajuste do hiperparâmetro como parte do treinamento do modelo

Essa abordagem une as perspectivas do "desenvolvedor do algoritmo de treinamento" e do usuário aplicado do algoritmo de treinamento.

O desenvolvedor do algoritmo de treinamento fornece um algoritmo de treinamento "nu" model = train_naked (trainingdata, hyperparameters). Como o usuário aplicado precisa, tunedmodel = train_tuned (trainingdata)ele também cuida da fixação dos hiperparâmetros.

train_tunedpode ser implementado, por exemplo, envolvendo um otimizador baseado em validação cruzada em torno do algoritmo de treinamento nu train_naked.

train_tunedpode então ser usado como qualquer outro algoritmo de treinamento que não exija entrada de hiperparâmetro, por exemplo, sua saída tunedmodelpode ser submetida a validação cruzada. Agora, os hiperparâmetros são verificados quanto à estabilidade, assim como os parâmetros "normais" devem ser verificados quanto à estabilidade como parte da avaliação da validação cruzada.

Na verdade, é isso que você faz e avalia na validação cruzada aninhada se você mediar o desempenho de todos os modelos vencedores, independentemente de seus conjuntos de parâmetros individuais.


Qual é a diferença?

Possivelmente, acabamos com diferentes modelos finais seguindo essas 2 abordagens:

  • o modelo final na abordagem 1 será train_naked (all data, hyperparameters from optimization)
  • enquanto a abordagem 2 usará train_tuned (all data)e - conforme isso executa a otimização do hiperparâmetro novamente no conjunto de dados maior - isso pode acabar com um conjunto diferente de hiperparâmetros.

Mas, novamente, a mesma lógica se aplica: se acharmos que o modelo final possui parâmetros substancialmente diferentes dos modelos substitutos de validação cruzada, esse é um sintoma da suposição 1 sendo violada. Então, IMHO, novamente não temos um conflito, mas sim uma verificação se nossas suposições (implícitas) são justificadas. E, se não estiverem, não devemos apostar demais em ter uma boa estimativa do desempenho desse modelo final.


Tenho a impressão (também de ver o número de perguntas / confusões semelhantes aqui no CV) que muitas pessoas pensam em validação cruzada aninhada fazendo a abordagem 1. Mas o erro de generalização geralmente é estimado de acordo com a abordagem 2, então esse é o caminho a seguir. modelo final também.


Exemplo de íris

Resumo: a otimização é basicamente inútil. O tamanho da amostra disponível não permite distinções entre o desempenho de qualquer um dos conjuntos de parâmetros aqui.

Do ponto de vista da aplicação, no entanto, a conclusão é que não importa qual dos quatro conjuntos de parâmetros você escolhe - o que não é uma má notícia: você encontrou um platô de parâmetros comparativamente estável. Aí vem a vantagem da validação aninhada adequada do modelo ajustado: enquanto você não é capaz de afirmar que é o modelo ideal, você ainda pode afirmar que o modelo construído em todos os dados usando a abordagem 2 terá aproximadamente 97% de precisão (intervalo de confiança de 95% para 145 casos corretos em 150 testes: 92 - 99%)

Observe que a abordagem 1 também não está tão longe quanto parece - veja abaixo: sua otimização acidentalmente perdeu um "vencedor" relativamente claro por causa de laços (na verdade, esse é outro sintoma muito revelador do problema do tamanho da amostra).

Embora eu não tenha profundidade suficiente nos SVMs para "ver" que C = 1 deve ser uma boa opção aqui, eu usaria o kernel linear mais restritivo. Além disso, como você fez a otimização, não há nada errado em escolher o conjunto de parâmetros vencedor, mesmo que você saiba que todos os conjuntos de parâmetros levam a um desempenho praticamente igual.

No futuro, no entanto, considere se sua experiência gera estimativas aproximadas de qual desempenho você pode esperar e aproximadamente qual modelo seria uma boa escolha. Em seguida, construa esse modelo (com hiperparâmetros corrigidos manualmente) e calcule um intervalo de confiança para seu desempenho. Use isso para decidir se a tentativa de otimizar é sensata. (Devo acrescentar que estou trabalhando principalmente com dados em que não é fácil obter mais 10 casos independentes - se você estiver em um campo com grandes tamanhos de amostras independentes, as coisas parecerão muito melhores para você)

versão longa:

Quanto aos resultados de exemplo no irisconjunto de dados. iristem 150 casos, é considerado o SVM com uma grade de 2 x 2 parâmetros (2 núcleos, 2 ordens de grandeza para a penalidade C).

O loop interno possui divisões de 129 (2x) e 132 (6x) casos. O "melhor" conjunto de parâmetros é indeciso entre o kernel linear ou rbf, ambos com C = 1. No entanto, as exatidões do teste interno são todas (incluindo o C = 10 sempre perdedor) dentro de 94 - 98,5% da precisão observada. A maior diferença que temos em uma das divisões é de 3 vs. 8 erros para rbf com C = 1 vs. 10.

Não há como essa diferença significativa. Não sei como extrair as previsões para casos individuais no currículo, mas mesmo assumindo que os 3 erros foram compartilhados, e o modelo C = 10 cometeu 5 erros adicionais:

> table (rbf1, rbf10)
         rbf10
rbf1      correct wrong
  correct     124     5
  wrong         0     3

> mcnemar.exact(rbf1, rbf10)

    Exact McNemar test (with central confidence intervals)

data:  rbf1 and rbf10
b = 5, c = 0, p-value = 0.0625
alternative hypothesis: true odds ratio is not equal to 1

Lembre-se de que existem 6 comparações pareadas na grade 2 x 2; portanto, precisamos corrigir várias comparações também.


Abordagem 1

Em 3 das 4 divisões externas em que rbf "venceu" o kernel linear, elas realmente tinham a mesma precisão estimada (acho que min em caso de empate retorna o primeiro índice adequado).

Alterando a grade para params = {'kernel':['linear', 'rbf'],'C':[1,10]} rendimentos

({'kernel': 'linear', 'C': 1}, 0.95238095238095233, 0.97674418604651159)
({'kernel': 'rbf', 'C': 1}, 0.95238095238095233, 0.98449612403100772)
({'kernel': 'linear', 'C': 1}, 1.0, 0.97727272727272729)
({'kernel': 'linear', 'C': 1}, 0.94444444444444442, 0.98484848484848486)
({'kernel': 'linear', 'C': 1}, 0.94444444444444442, 0.98484848484848486)
({'kernel': 'linear', 'C': 1}, 1.0, 0.98484848484848486)
({'kernel': 'linear', 'C': 1}, 1.0, 0.96212121212121215)

Abordagem 2:

Aqui clfestá o seu modelo final. Com random_state = 2, rbf com C = 1 ganha:

In [310]: clf.grid_scores_
[...snip warning...]
Out[310]: 
[mean: 0.97333, std: 0.00897, params: {'kernel': 'linear', 'C': 1},
 mean: 0.98000, std: 0.02773, params: {'kernel': 'rbf', 'C': 1},
 mean: 0.96000, std: 0.03202, params: {'kernel': 'linear', 'C': 10},
 mean: 0.95333, std: 0.01791, params: {'kernel': 'rbf', 'C': 10}]

(acontece cerca de 1 em 5 vezes, 1 em 6 vezes lineare rbfcom C = 1empate no ranking 1)


4
Obrigado @cbeleites! Também li suas respostas em outros tópicos e esperava que você respondesse minha pergunta. Sua resposta é muito profunda, mas o que minha pergunta está realmente focada é como analisar os resultados de um CV aninhado; Ainda estou um pouco incerto quanto ao "o que fazer depois de aninhar o CV". Você pode dar uma olhada no caderno que eu criei (perto do final do meu post) e, no termo do leigo, explicar o que fazer, pois dois conjuntos diferentes de hiperparâmetros foram identificados como ótimos em um currículo aninhado? É um caderno muito curto, eu prometo!
Respiração pesada

@HeavyBreathing Eu li a resposta e ainda não sou tão claro sobre 'o que fazer depois de aninhar o CV'. Você já descobriu isso claramente?
stackunderflow

0

Li sua pergunta e a resposta acima duas vezes (primeira vez há 3 meses). Estou interessado e também quero encontrar a maneira absolutamente apropriada de validação cruzada para meus dados. Depois de muito pensar e ler, parece que encontro os buracos e aqui está minha solução:

Para explicar minha confusão, deixe-me tentar percorrer a seleção do modelo com o método de validação cruzada aninhada passo a passo.

  1. Crie um loop de CV externo com o K-Fold. Isso será usado para estimar o desempenho dos hiperparâmetros que "venceram" cada loop interno do CV.
  2. Use o GridSearchCV para criar um loop CV interno, onde, em cada loop interno, o GSCV percorre todas as combinações possíveis do espaço de parâmetros e cria o melhor conjunto de parâmetros. (Nota: aqui eu assumo: dados para o loop interno = dados de treinamento para o loop externo. Você pode perguntar: por quê? Resposta: /programming/42228735/scikit-learn-gridsearchcv-with-multiple-repetitions/ # 42230764, leia a seção de respostas de Vivek Kumar, etapa 4)
  3. Depois que o GSCV encontrou os "melhores parâmetros" no loop interno (vamos chamá-lo de vencedor interno), ele é testado com o conjunto de testes no loop externo para obter uma estimativa do desempenho (vamos chamá-lo de outer_fold_score1).
  4. O loop externo é atualizado para a próxima dobra como conjunto de teste e o restante como conjunto de treinamento (para avaliar o "vencedor interno" no loop externo), o "vencedor interno" é testado novamente com o novo conjunto de testes (outer_fold_score2). Então, novamente, o loop externo é atualizado para a próxima dobra até que o loop seja concluído. As pontuações de cada dobra (outer_fold_score 1,2 ..) serão médias para obter a pontuação do "vencedor interno" para o loop externo (outer_score)
  5. O loop externo é atualizado para a próxima dobra como o conjunto de teste e o restante como conjunto de treinamento (para encontrar o próximo "vencedor interno" e 1 a 4 repetições) . Observe que, quando repetimos 1, não criamos o novo K- vezes, mas sempre usamos o mesmo Kfold externo) . Em cada um dos ciclos de 1 a 4, obtemos um "melhor parâmetro" (ou "vencedor interno") com um outer_score. Aquele com o melhor outer_score será o vencedor do vencedores

Raciocínio:

  • Basicamente, sua pergunta diz respeito à existência de muitos "parâmetros vencedores" para o loop externo. O problema é que você não concluiu o loop externo para avaliar e encontrar o "vencedor externo". Seu quarto passo apenas avalia o "vencedor interno" em 1 dobra no loop externo, mas você não "loop". Portanto, preciso substituí-lo pelo meu 4º passo - "loop" o passo de avaliação no loop externo e obter a pontuação externa (por média)
  • Seu quinto passo fez o trabalho de "loop" no loop externo, mas é apenas para criar outro "vencedor interno". Ele não repetiu a "avaliação" desse "vencedor interno" no loop externo

Isso realmente responde à pergunta?
Michael R. Chernick

0

Você não usa a validação cruzada aninhada para selecionar os hiper parâmetros do algoritmo; esse método é usado para estimar o erro de generalização do seu procedimento de construção de modelo . Onde, pelo procedimento de construção do modelo, pretendo todas as etapas que você aplicou para alcançar o modelo final que você usará em campo.
Um procedimento de criação de modelo pode ser composto pelas regras que você aplicou para decidir qual pré-processamento aplicar aos dados, qual recurso usar e, finalmente, quais hiperparâmetros usar. Pense nisso como uma espécie de "meta-algoritmo" que recebe como entrada um conjunto de dados específicoDe produz como saída um "algoritmo", composto por um conjunto fixo de transformações de pré-processamento, recursos e, finalmente, valores de hiper parâmetros.

Por exemplo, digamos que você tenha X,ycomo matriz de design e destino e você deseja treinar um classificador:
1. que use apenas o primeirox recursos em X que têm maior correlação com y.
2. você escolhe os valores dos hiperparâmetros minimizando uma estimativa de erro de validação cruzada de 10 vezes.

Se você aplicar essas duas etapas a um par específico de X,y você obterá um algoritmo específico com um conjunto definido de recursos e hiper parâmetros fixos que não serão necessariamente os mesmos que você obteria para X,yembora o procedimento de criação do modelo seja idêntico, isto é: etapas 1 + 2 que não estão vinculadas a nenhum conjunto de dados específico.
Digamos que você tenha feito tudo o que precede sem ter dividido seus dados em teste de trem porque possui um pequeno conjunto de dados, como estima o erro de generalização do classificador que você acabou de criar? Você pode usar o melhor erro encontrado na validação cruzada na etapa 2?
Não , o primeiro grande problema está na etapa 1, na qual você usa todos os dados para selecionar os recursos a serem usados. Portanto, mesmo quando você faz a validação cruzada na etapa 2, os recursos já terão visto e lembrado de algumas informações presentes na dobra de teste a cada execução de validação cruzada. O resultado será uma estimativa excessivamente otimista do erro de teste e isso é chamadoapresentam polarização selecção à sua disposição; portanto, em certo sentido, você está ajustando os hiper parâmetros aos seus dados com o risco de superajustá-los, e isso é chamado de viés de seleção de modelo. Para explicar isso em sua estimativa, você precisaria colocar a etapa de seleção de recurso dentro do loop de validação cruzada da etapa 2.
Ok, agora estamos bem? O melhor erro encontrado na validação cruzada com a etapa de seleção de recurso dentro do loop é uma estimativa justa do erro de generalização?
Em teoria, a resposta ainda é não , o problema é que seus hiper parâmetros foram escolhidos para minimizar o erro de validação cruzada no número de conjunto de dados específico de hiper parâmetros a serem ajustados é relativamente grande. Para explicar isso ao estimar o erro de generalização, você aplicaria uma validação cruzada aninhada conforme descrito, que forneceria uma estimativa correta do seu erro de generalização.. Mas isso é uma preocupação na prática? Depende da aplicação específica: é provável que se torne mais severo, como um ajuste excessivo no treinamento, quando o conjunto de dados é pequeno e o
Finalmente, para responder à sua última pergunta, depois de ter uma estimativa justa do seu erro de generalização de "procedimento de construção de modelo" com uma validação cruzada aninhada, você simplesmente aplicaria o procedimento (etapa 1 + 2) a todo o conjunto de dados, obtendo um modelo com um conjunto fixo de recurso e definir valores de hiper parâmetros, mas lembre-se de que o erro que esperamos que este modelo tenha em dados não vistos é a estimativa de validação cruzada aninhada .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.