Seleção de modelos e validação cruzada: o caminho certo

34

Existem vários threads no CrossValidated no tópico seleção de modelo e validação cruzada. Aqui estão alguns:

No entanto, as respostas para esses encadeamentos são bastante genéricas e destacam principalmente os problemas com abordagens específicas para validação cruzada e seleção de modelos.

Para tornar as coisas o mais concretas possível , digamos, por exemplo, que estamos trabalhando com um SVM com um kernel RBF: , e que Eu tenho um conjunto de dados dos recursos X e os rótulos y e queroK(x,x)=(γ|xx|)2

  1. Encontre os melhores valores possíveis do meu modelo ( eγC )
  2. Treinar o SVM com meu conjunto de dados (para implantação final)
  3. Estime o erro de generalização e a incerteza (variação) em torno desse erro

Para fazer isso, eu pessoalmente faria uma pesquisa em grade, por exemplo, tento todas as combinações possíveis de e . Para simplificar, podemos assumir os seguintes intervalos:Cγ

  • C{10,100,1000}
  • γ{0.1,0.2,0.5,1.0}

Mais especificamente, usando meu conjunto de dados completo, faço o seguinte:

  1. Para cada par ( , ), faço repetidas iterações (por exemplo, 100 repetições aleatórias) da validação cruzada de fold (por exemplo, ), no meu conjunto de dados, ou seja, treino meu SVM nas dobras e avalio o erro na dobra esquerda, repetindo todas as dobras. No geral, coleciono 100 x 10 = 1000 erros de teste.CγK = 10 K - 1 KKK=10K-1 1K
  2. Para cada par ( , ), calculo a média e a variação desses 1000 erros de teste .γ μ M , σ MCγμM,σM

Agora, quero escolher o melhor modelo (os melhores parâmetros do kernel) que eu usaria para treinar meu SVM final no conjunto de dados completo. Meu entendimento é que escolher o modelo com a menor média de erro e variância e seria a escolha certa, e que o modeloσ M μ MμMσMμM são são minhas melhores estimativas do viés e variância do erro de generalização do modelo ao treinar com o conjunto de dados completo.σM

MAS, depois de ler as respostas nos tópicos acima, estou tendo a impressão de que esse método para escolher o melhor SVM para implantação e / ou para estimar seu erro (desempenho de generalização) é defeituoso e que existem maneiras melhores de escolher o melhor SVM e relatando seu erro. Se sim, o que são? Estou procurando uma resposta concreta, por favor.

Mantendo esse problema, como posso escolher o melhor modelo e estimar adequadamente seu erro de generalização ?

Amelio Vazquez-Reina
fonte
Para tornar as coisas o mais concretas possível, diga-nos: Quantos casos estatisticamente independentes você tem em seu conjunto de dados? Qual é a função de destino que você avalia para otimização / Que tipo de medida de erro você usa? Você realmente observa um comportamento consistente da medida de erro escolhida em sua grade de parâmetros? Caso você esteja falando sobre classificação e sua medida de erro permita: como os resultados iterados da validação cruzada se comparam à variação que você espera (mas não pode medir) devido ao tamanho finito da amostra?
Cbeleites suporta Monica
Um artigo que você pode achar interessante: optimalprediction.com/files/pdf/V2A5.pdf
user31256
2
+1 para perguntas muito claras e detalhadas, bem como questões muito relevantes para a comunidade de ciência de dados em geral.
NickBraunagel

Respostas:

20

Meu artigo no JMLR aborda essa questão exata e demonstra por que o procedimento sugerido na pergunta (ou pelo menos um muito parecido) resulta em estimativas de desempenho otimistas e tendenciosas:

Gavin C. Cawley, Nicola LC Talbot, "Sobre adaptação na seleção de modelos e viés de seleção subsequente na avaliação de desempenho", Journal of Machine Learning Research, 11 (julho): 2079-2107, 2010. ( www )

O importante a lembrar é que a validação cruzada é uma técnica para estimar o desempenho da generalização de um método de geração de um modelo, e não do próprio modelo. Portanto, se a escolha de parâmetros do kernel fizer parte do processo de geração do modelo, você também precisará validar cruzadamente o processo de seleção do modelo, caso contrário, você terá uma estimativa de desempenho otimizada e tendenciosa (como acontecerá com o procedimento proposto).

Suponha que você tenha uma função fit_model, que aceita um conjunto de dados que consiste nos atributos X e nas respostas desejadas Y e que retorna o modelo ajustado para esse conjunto de dados, incluindo o ajuste de hiperparâmetros (neste caso, kernel e parâmetros de regularização). Esse ajuste de hiperparâmetros pode ser realizado de várias maneiras, por exemplo, minimizando o erro de validação cruzada sobre X e T.

Etapa 1 - Ajuste o modelo a todos os dados disponíveis, usando a função fit_model. Isso fornece o modelo que você usará em operação.

Etapa 2 - Avaliação de desempenho. Execute a validação cruzada repetida usando todos os dados disponíveis. Em cada dobra, os dados são particionados em um conjunto de treinamento e um conjunto de testes. Ajuste o modelo usando o conjunto de treinamento (registre valores de hiperparâmetros para o modelo ajustado) e avalie o desempenho no conjunto de teste. Use a média em todos os conjuntos de testes como uma estimativa de desempenho (e talvez observe também a distribuição de valores).

Etapa 3 - Variabilidade das configurações de hiperparâmetros - realize a análise dos valores de hiperparâmetros coletados na etapa 3. No entanto, devo salientar que não há nada de especial nos hiperparâmetros, eles são apenas parâmetros do modelo que foram estimados (indiretamente ) dos dados. Eles são tratados como hiperparâmetros em vez de parâmetros para conveniência computacional / matemática, mas esse não precisa ser o caso.

O problema com o uso da validação cruzada aqui é que os dados de treinamento e teste não são amostras independentes (pois compartilham dados), o que significa que é provável que a estimativa da variação da estimativa de desempenho e dos hiperparâmetros seja tendenciosa (isto é, menor do que seria para amostras de dados genuinamente independentes em cada dobra). Em vez de validação cruzada repetida, eu provavelmente usaria bootstrapping e agruparia os modelos resultantes se isso fosse viável computacionalmente.

O ponto principal é que, para obter uma estimativa de desempenho imparcial, qualquer procedimento usado para gerar o modelo final (fit_model) deve ser repetido por inteiro, independentemente, em cada dobra do procedimento de validação cruzada.

Dikran Marsupial
fonte
Esta é uma ótima resposta. Quando você diz rather than repeated cross-validation you would go for bootstrapping- Qual é exatamente a diferença? Ambos envolvem várias repetições de divisão dos dados traine, em testseguida, treinam traine avaliam test, não é?
21413 Josh
4
O bootstrapping (amostragem com substituição) parece uma maneira mais natural de executar um grande número de novas amostragens, pois é mais aleatório do que a validação cruzada repetida. Para inicializar, o uso de conjuntos ensacados é um recurso interessante, com o erro fora da bolsa como uma estimativa de desempenho. Não há uma quantidade enorme para escolher entre os dois.
Dikran Marsupial
Obrigado @Dikran - Isso me fez pensar, supondo que alguém use, por exemplo, bootstrapping, como você escolheria um bom modelo considerando o média e a variação entre as repetições? (ou seja, qual protocolo de seleção de modelo você seguiria). Esta questão coloca exatamente essa questão. Colocar sua opinião sobre esse segmento seria extremamente valioso!
21713 Josh
@DikranMarsupial Você poderia postar código (por exemplo, Python ou R) para as etapas 1 a 3? Acho muito mais fácil entender esses procedimentos ao ver um código concreto.
tobip
11
Mensagem principal: "O ponto principal é que, para obter uma estimativa de desempenho imparcial, qualquer procedimento usado para gerar o modelo final (fit_model) deve ser repetido na íntegra independentemente, em cada dobra do procedimento de validação cruzada." Esta mensagem exacta também é transportado nos elementos de aprendizagem estatística (ver secção 7.10.2): web.stanford.edu/~hastie/Papers/ESLII.pdf
NickBraunagel
0

γC

Um procedimento que otimiza esses hiperparâmetros e treina um SVM com eles também é apenas um algoritmo de aprendizado de máquina . Em vez de otimizar apenas os parâmetros internos do SVM (os vetores de suporte), ele também otimiza os hiperparâmetros.

Agora você tem dois problemas [que podem ser resolvidos independentemente]:

Leia Uso indevido de validação cruzada (relatando desempenho para obter o melhor valor de hiperparâmetro) para garantir que você não os misture.


Uma solução específica (provavelmente não ótima) para o problema concreto da sua pergunta:

k = 5
loss_CV = zeros(k)
for i in 1:k 
    Xi_train, Xi_test = folds(X,k)[i]
    loss = zeros((3,3))
    for lambda in {0.1,0.2,0.5,1.0}
        for C in {10,100,1000}
            for j in 1:k
                Xj_train, Xj_test = folds(Xi_train,k)[j]
                model = SVM(Xj_train,lambda, C)
                loss[lambda,C] += test_error(model,Xj_test)
    lambda, C = argmax(loss)
    model = SVM(Xi_train,lambda, C)
    loss_CV += test_error(model,Xi_test)

loss = zeros((3,3))
for lambda in {0.1,0.2,0.5,1.0}
    for C in {10,100,1000}
        for j in 1:k
            Xj_train, Xj_test = folds(Xi_train,k)[j]
            model = SVM(Xj_train,lambda, C)
            loss[lambda,C] += test_error(model,Xj_test)
lambda, C = argmax(loss)
model = SVM(Xi_train,lambda, C)

Aqui, modelseria o seu "melhor modelo" e loss_CVuma "estimativa adequada do seu erro de generalização" (embora inclinado para cima, mas você não pode ter o bolo e comê-lo também).

jan-glx
fonte