Sim, o Test-Driven Development é útil em Data Science

Vindo de uma experiência em análise e ciência de dados, costumava ver a redação de testes como algo doloroso. Eu sabia que era importante, mas nunca sabia por onde começar e sempre procrastinava até o final do projeto. O que é mais chato do que testar um código que já funciona?
Recentemente, comecei a ver as coisas ao contrário. Eu descobri o Test-Driven Development: escreva seus testes antes de realmente codificar a parte funcional do código. É uma boa prática em engenharia de software que merece ser aplicada com mais frequência em projetos de ciência de dados.
O que é Desenvolvimento Orientado a Testes (TDD)?

Uma maneira simples de colocá-lo é através da estrutura Red/Green/Refactor . Sempre que quiser adicionar funcionalidade ao código, você pode seguir um ciclo de três etapas:
- Vermelho . Crie um teste que falhe. ou seja, escreva as necessidades funcionais do seu código
- Verde . Escreva o código de produção que faz o teste passar. ou seja, atender às necessidades funcionais do código
- Refatorar. Limpe a bagunça que você acabou de fazer. ou seja, limpe seu código sem alterar a funcionalidade
Vamos ilustrar isso com um exemplo da vida real. Como uma etapa de pós-processamento para um projeto de Reconhecimento de Entidade Nomeada , queremos construir uma função de processamento para extrair a unidade de duração (dia/semana/mês/..) e o valor de duração em um texto.
- Vamos escrever um teste de unidade que atenda às necessidades funcionais e uma função vazia.


2. Escrevemos um código que passa no teste.

O teste é VERDE Viva!! Espere ... temos certeza de que é SECO, SÓLIDO, pep8 ??
3. Refatoramos a função, para garantir as melhores práticas de codificação.

Aqui adicionamos anotações de tipo, criamos uma função genérica para converter o número da letra em float (com seu próprio teste de unidade também) e refatoramos como preenchemos o dicionário.
Onde podemos aplicar o Test-Driven Development em Data Science?
O Test Driven Development não é relevante em todas as etapas de um projeto de ciência de dados. Por exemplo, não vale a pena durante explorações de dados ou modelos em que você não tem certeza do que está procurando: escrever testes sem saber o resultado esperado provavelmente é um exagero.
Torna-se muito útil sempre que você precisa construir pipelines de produção robustos .
Neste contexto, precisamos implementar vários tipos de testes:
- Testes de unidade: um teste para cada pedaço de código do projeto
- Testes de modelo : certifique-se de que o modelo tenha bom desempenho e se comporte corretamente
- Testes de integração : garantindo que haja uma boa ligação entre cada parte do código
Para testes de modelo , deve ser usado com cuidado. Ao lidar com modelos preditivos, estamos lidando com incertezas . De fato, muitos algoritmos de aprendizado de máquina são inerentemente aleatórios – várias execuções usando as mesmas entradas podem produzir resultados ligeiramente diferentes a cada vez. Isso pode levar a testes inconsistentes : um teste que às vezes passa e às vezes falha, apesar de nenhuma alteração no código ou no próprio teste. Se formos muito específicos nos casos de teste durante um primeiro desenvolvimento orientado a testes, é muito provável que alguns testes sejam interrompidos na próxima iteração. Um novo modelo pode se comportar de maneira diferente em alguns casos, embora tenha um desempenho melhor globalmente. Portanto, é melhor incluir nos testes do modelo apenas os casos básicos que são necessários para o projeto.
Por fim, para testes de integração , ele se aplica bem a trechos de código que não incluem previsões de modelo. Se incluir previsão de modelo, é melhor testar o formato da saída do que a saída real.
Uma boa prática é incluir esses testes no CI/CD do seu projeto. Portanto, sempre que uma nova proposta de funcionalidade é feita, é garantido que nenhuma outra funcionalidade seja quebrada.
Por que é uma mudança de jogo?
Adotar o Test-Driven Development realmente muda a maneira como você organiza suas sessões de codificação e traz muitos benefícios:
- Ele valida instantaneamente as especificações comerciais e técnicas . Também é uma ótima documentação para um cientista de dados que descobre o projeto e precisa entender como o projeto funciona.
- Dá confiança no código . Cada caso de uso é coberto por um teste e você ou seus colegas de equipe podem adicionar funcionalidades adicionais sem medo de quebrar tudo o que já foi feito.
- É economia de tempo . Pode-se ver isso como algo que está retardando o desenvolvimento. Mas não é, obriga você a pensar antecipadamente nas necessidades funcionais e antecipar os casos extremos. Acredite em mim, no final das contas, isso economiza muito tempo de depuração e iteração.
- Até torna o desenvolvimento mais divertido ! Ele divide o código em pequenos desafios de resolução de problemas. E é um ajuste perfeito para codificação de pares.