Solução Final - ML Olympiad [1º lugar]

Confira a estratégia aplicada para esta competição

Fellipe Gomes

5 minute read

Introdução

O TFUG - TensorFlow Users Group de São Paulo lançou uma nova competição no Kaggle onde o objetivo era desenvolver modelos para previsão de diagnóstico de síndromes respiratórias, que é um tema relacionado com um dos 17 tópicos de Desenvolvimento Sustentável das Nações Unidas - Boa saúde e bem-estar.

Como um cientista de dados, acredito que seja muito importante continuarmos aprimorando nossas habilidades e conhecimentos. Competições como essa são muito divertidas e possibilitam que testemos nossos limites em um ambiente competitivo e colaborativo, além de ser uma grande oportunidade para nos desafiarmos e aprender uns com os outros.

Tive o enorme prazer de conquistar o primeiro lugar, dessa vez com meu grande amigo Kaike, parceiro de competições de longa data que trouxe grande sinergia para a solução final com a contribuição de seu modelo (compartilhado abertamente no Kaggle).

Aqui estão alguns dos prêmios recebidos:

Como nesta competição havia bastante trabalho a ser feito e tivemos apenas 1 mês para trabalhar na solução, foi preciso fazer uma boa gestão do código e do tempo de desenvolvimento.

Definição do problema de negócio

O objetivo desta competição consistiu em predizer qual o agente causador da síndrome respiratória aguda grave com base nos dados e sintomas dos pacientes.

Esta tarefa pode ser enquadrada como um problema supervisionado de classificação multinomial (com múltiplos outputs) na qual as previsões são, de certa forma, dependentes da entrada umas das outras (o paciente só pode ter registrado uma das doenças).

A validação da solução foi feita utilizando a métrica Macro (or Mean) F1-Score, que é basicamente a média do F1 calculado sobre as previsões de cada nota.

Soluções

Ambas soluções (minha e do Kaike) foram compartilhadas no Kaggle:

Disponibilizamos também a solução em formato de vídeo, gravado em um meetup com duração de 1 hora e meia para o canal do TensorFlow UGSP no Youtube no link: https://youtu.be/6HPJn38NF3w

Estratégia analítica

Nas seções abaixo apresento o racional por trás da minha solução, como chegamos nos 5 melhores modelos individuais (para cada doença respiratória) que utilizei em um ensemble para chegar ao primeiro lugar, bem como a estratégia de pós processamento que com que o score melhorasse significativamente.

Decisões sobre a target

A primeira decisão importante era definir como enquadrar o problema; se utilizaríamos 1 modelo multiclasse ou diferentes modelos para cada classe.

Em todos os testes que fizemos, os modelos individuais superaram o F1-Score Macro de um modelo único. Como 3 das classes eram bastante desbalanceadas, acredito que modelos especializados nesses casos conseguiram captar melhor suas nuances.

Processamento dos Dados

Como optamos por unificar os resultados apenas na reta final, meu pré-processamento foi muito diferente do feito pelo Kaike e isso foi fundamental para que as estimativas dos nossos modelos tivessem baixa correlação. Não focarei aqui no meu pré-processamento, pois não acho que foi o diferencial para atingir um score superior a 0.6 (quem tiver curiosidade está tudo bem documentado nos notebooks compartilhados).

Dados Externos

O fato de não termos as informações do ano em que esses dados foram coletados dificultou na busca de bases externas, pois indicadores socioeconômicos e de saúde variam bastante ao longo do tempo.

Fizemos alguns testes utilizando o Atlas do Desenvolvimento Humano (ADH), mas não tivemos muito sucesso, pois esses dados estão muito defasados (1991-2010). Também tentamos acrescentar a informação de latitude e longitude de cada município, mas isso não trouxe uma melhora substancial no nosso score.

Feature Engineering

Outra etapa em que investimos bastante tempo foi para criar novas variáveis.

Novamente, nossa engenharia de recursos foi feita de maneira separada para que nossos modelos aprendessem aspectos diferentes dos dados. Abaixo, compartilho algumas das features que desenvolvi apenas para o meu modelo:

  • Presença de sintomas relacionados à Target;
  • Se tomografia era típica do COVID;
  • Intervalo de idade com mais casos;
  • Idade discretizada;
  • Diferença entre a semana de notificação e primeiros sintomas;
  • Novas features baseadas nas contagens de algumas features categóricas;
  • etc.

Modelos

Além de pré-processamentos e feature engineering diferentes, também utilizamos modelos e mecanismos de tunning diferentes, o que ajudou para que nossas estimativas tivessem baixa correlação. Eu usei o Catboost como modelo final, já o Kaike optou por um LightGBM com tuning de hiperparametros.

Ensemble

Calculamos a média das probabilidades previstas de cada modelo para cada classe antes de selecionar a classe que tivesse a maior probabilidade.

Como nossas previsões tinham baixa correlação, conseguimos ser bem sucedidos no ensemble combinando nossas submissões com score ~0.6 alcançando ~0.61 na tabela pública.

Post Processing

Acredito que o diferencial dessa competição estava no pós processamento.

Quando avaliamos o score do modelo de cada classe, também calculamos um threshold que maximizava os respectivos F1.

Observamos que nosso modelo para a classe 5 apresentava um F1 muito superior às demais classes com esse threshold otimizado, então fizemos o seguinte:

  1. Calculamos as probabilidades individuais para cada classe;
  2. Selecionamos a classe que tinha maior probabilidade estimada em cada instância;
  3. Pegamos a classificação binária da classe 5 com o threshold otimizado e aplicamos a seguinte condição: Se o modelo da classe 5 estimou que y5[i]==1, então yfinal[i] é 5, caso contrário, use a classe de maior probabilidade entre as outras 4. (Em outras palavras: np.where(y5_test_class==1, 5, sub.CLASSI_FIN))

Considerações Finais

Foi uma competição muito interessante e desafiadora. Agradeço imensamente ao TFUG por organizar o evento e a todos os participantes que contribuíram para o aprendizado coletivo.Foi uma ótima oportunidade de aprendizado e troca de experiências.

Espero que minha solução possa ser útil para outros projetos e desafios futuros.

Sobre o Autor

Me chamo Fellipe Gomes, sou cientista de dados e apaixonado por aprendizado de máquina. Compartilho meu conhecimento por meio de artigos, tutoriais e projetos de código aberto. Se quiser saber mais sobre meu trabalho, sinta-se à vontade para conferir meu LinkedIn e GitHub.

comments powered by Disqus