Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Cross-validate depois do GridSearchCV

Mesmo depois de assistir as aulas e ler outros tópicos como esse https://cursos.alura.com.br/forum/topico-tempo-de-execucao-106231, ainda não entendi por que devemos fazer um cross-validate depois do GridSearchCV.

Pelo o que eu entendi, o GridSearchCV vai me retornar a melhor combinação de Hyper Parâmetros do modelo. E no processo pra chegar nessa conclusão, ele já vai fazer um cross-validate (KFold, 5 splits).

search = GridSearchCV(RandomForestClassifier(), parameter_space, cv=KFold(n_splits=5, shuffle=True))

Então minhas dúvidas são:

  • Por que precisamos fazer outro cross-validate após o GridSearchCV, sendo que já fizemos isso?
  • Por que o código do cross_val_score demora tanto, sendo que já sabemos qual é a melhor combinação de parâmetros pro modelo? Ele não deveria demorar menos que o GridSearch, sendo que vai usar apenas uma configuração (ao invés de n combinações definidas no GridSearchCV)?
  • Por que passamos "search" (o objeto GridSearchCV) como parâmetro do cross_val_score ao invés de "search.best_estimator_" (apenas o melhor estimator)? (Código abaixo)
    scores = cross_val_score(search, x_bad_luck, y_bad_luck, cv = KFold(n_splits = 5, shuffle = True))
    VS
    scores = cross_val_score(search, x_bad_luck, y_bad_luck, cv = KFold(n_splits = 5, shuffle = True))
4 respostas

Olá Richard.

  • O GridsearchCV vai sim retornar a melhor combinação de parâmetros para o modelo com base nos critérios definidos, contudo, para alcançar esses resultados ele treina o modelo com essas combinações de Hiperparâmetros. Então, quando você recebe esse output do melhor modelo e já realiza um predict, o resultado pode ser otimista, pois o modelo treinou com esses mesmos dados, podendo ocasionar apenas o "decorar dos dados" e não gerando uma generalização. A generalização é fundamental para o modelo realizar predições com dados que nunca viu, por isso usamos novamente um cross_val_score() para garantir a generalização do modelo.
  • Em relação a passar o search ao invés do search.best_estimator_ está relacionado ao próprio funcionamento interno do cross_val_score(), que usa o método predict() por "trás dos panos", vide a documentação do GridSearchCV, ele já realiza a predição se utilizando do modelo com a melhor combinação de parâmetros, portanto usar o best_estimator_ se torna uma redundância.
  • Já o GridSearchCV ser menos lento que o cross_val_score é uma dúvida pertinente. O GridSearchCV pode utilizar paralelização para rodar o algoritmo pelos dados, diminuindo seu tempo de processamento. Mas ainda desconheço se é o suficiente para o deixar mais lento que o cross_val_score com apenas um modelo, desculpe-me não poder colaborar com este tópico.

Bons estudos. :)

Obrigado pela resposta detalhada, Lucas!

Sobre search ou search.best_estimator_, compreendi.

Sobre o cross-validate após o GridSearchCV, acho que estou quase compreendendo mas ainda não 100%. O que ainda me deixa confuso é que no GridSearchCV a gente já faz um cross-validate, e não entendi como fazer outro cross-validate (cros_val_score) ajudaria.

Por exemplo, temos 100 valores que são divididos 5 vezes pelo KFold. Usamos esses 100 valores e suas permutações para obter os melhores hiperparâmetros através do GridSearchCV. Ao rodar o cross_val_score, a gente ainda vai continuar usando esses mesmos 100 valores, divididos novamente 5 vezes, para avaliar nosso modelo. O risco dos dados serem decorados não continua o mesmo, sendo que são os mesmo dados?

Mais uma vez obrigado pela ajuda!

solução!

Olá Richard, fico feliz em poder ajudar.

  • Em conjunto de dados menores, o Nested Cross Validation, a ação de realizar um cross_val_score() após iterações pela busca dos melhores parâmetros com o GridSearchCV, a diferença de score é ínfima, como demonstrada por essa publicação do Scikit-Learn nesse link. Perceba que nessa publicação, com os dados utilizados, já houve um pequeno ganho de generalização em relação a não usar o Nested Cross Validation. Ou seja, em conjunto de dados maiores, a melhora vai ser significativa.

  • O risco de overfit não é o mesmo?: se utilizarmos todo o conjunto de dados para a busca pelos hiperparâmetros e para o testar com cross_val_score(), a generalização realmente não seria adequada, como você percebeu. Portanto, surge uma alternativa que explica melhor o uso do Nested Cross Validation: a divisão dos dados em treino e validação.

Outra abordagem:

  • Vamos separar os dados em treino e validação, usando apenas os dados de treino para a busca pelos melhores hiperparâmetros, separando a validação como dados que o "modelo nunca viu". Aqui está uma imagem do Scikit-Learn para exemplificar:

A publicação por inteiro da abordagem está nesse link.

Perceba aqui que o conjunto de dados chamado Test Data não foi utilizado para treino. Então, quando for realizar este cross_val_score() após o GridSearchCV, irá ser avaliado realmente a capacidade de generalização do modelo.

Espero que as visualizações e documentações tenham te ajudado a entender o porquê de utilizar o Nested Cross Validation.

Perfeito, compreendi agora.

A fonte da minha confusão estava no fato de que no curso, até o momento em que usamos o GridSearchCV, nós só dividimos os dados em treino e teste. Apenas mais adiante vamos dividir os dados em treino, teste e validação.

Mais uma vez obrigado pelas explicações detalhadas, Lucas.

E fica a sugestão para a Alura considerar uma revisão nessa parte do curso.