Introdução ao Tidymodels em R para quem conhece Scikit-learn

Celso M. Cantanhede Silva
Data Hackers
Published in
6 min readJul 12, 2020
C’est ne pas un pipe

Por muitos anos, o pacote caret (Classification And REgression Training) foi a principal referência em Machine Learning para aqueles que, rebeldes, continuam a tomar o lado da linguagem R na disputa mais perene da comunidade de ciência de dados.

Agora, um novo passo se forma desse lado das trincheiras, com o lançamento em abril do site tidymodels.org. O tidymodels busca ser uma evolução do Caret, propondo-se como um framework de diferentes pacotes para modelagem de machine learning que, crucialmente, aderem aos princípios do tidyverse.

O que diabos é Tidyverse?

Brevemente, para os não iniciados, o Tidyverse é um conjunto de pacotes para ciência de dados que possuem gramática, estrutura de dados e principalmente, uma filosofia em comum. A filosofia é de trabalhar sempre com dados tidy (arrumados) e ter todas as ferramentas para transformar os dados que tivermos em tidy. Como definido em paper na Journal of Statistical Software em 2013, os dados são considerados tidy quando respeitam três regras simples:

  1. Cada variável tem uma coluna própria e única
  2. Cada observação forma uma linha
  3. Cada unidade observacional (conjunto de variáveis e observações) formam uma tabela.

A ideia é evitar problemas comuns para análise como variáveis múltiplas guardadas nas mesmas colunas, múltiplos tipos de observações na mesma tabela ou as mesmas observações espalhadas entre diversas tabelas. Essas três regras simples deram origem ao conjunto gigantesco de ferramentas em R para manipulação e visualização de dados que facilitam imensamente a vida dos analistas e cientistas de dados que é o tidyverse.

O impacto do tidyverse é tamanho que não é difícil encontrar em blogs especializados o debate sobre se é preferível usar o tidyverse ou utilizar as funções tradicionais da linguagem, o chamado base R. Certamente que esse impacto é expandido pelo fato de que o tidyverse é mantido e impulsionado pela empresa por detrás da principal IDE de R no mercado, a RStudio PBC.

Devido a esse impacto, a necessidade de ferramentas de Machine Learning que conversassem bem com o tidyverse era óbvia, e por melhor que fosse o caret, ele realmente não foi construído sob aqueles princípios. Nasce, então, o tidymodels.

Mais uma vez, o Titanic…

Para demonstrar um pouco como funciona o tidymodels para um público acostumado ao Python, resolvi fazer uma comparação com um modelo simples. Minha ideia foi a seguinte: um dos melhores tutoriais para os absolutamente iniciantes em ML no Brasil está disponível, gratuitamente, no canal do Youtube do Mario Filho; uma demonstração bem crua de aplicação de Random Forests e Regressões Logísticas sobre um dos conjuntos de dados mais batidos, o Titanic, dataset tutorial do Kaggle. Como não poderia deixar de ser, é um tutorial em Python, usando as bibliotecas pandas e scikit-learn.

Minha ideia aqui não é repassar o código do Mario; isso pode ser conferido nos vídeos referenciados. Quero simplesmente mostrar como fazer os mesmos passos realizados em Python usando o tidymodels. Seria um cenário hipotético: e se o Mario Filho preferisse R e tivesse feito o tutorial nele? Espero, assim, estimular a curiosidade tanto de usuários da linguagem R pelo tidymodels quanto de usuários de Python pela linguagem R em geral e pelo universo tidy em particular.

Tidy Titanic

Antes de tudo, vamos repassar brevemente os passos que iremos realizar. O modelo servirá para acharmos as características dos passageiros que nos permitem saber se ele sobreviveu ou não ao desastroso naufrágio do Titanic. A métrica que utilizaremos para julgar nosso modelo é a acurácia dessa classificação.

Seguindo, portanto, o tutorial, iremos:

  1. Construir e selecionar as variáveis que utilizaremos a partir do dataset original train.csv disponível na página do desafio Titanic, no Kaggle;
  2. Aplicar dois modelos de classificação sobre as variáveis, Random Forest e Regressão Logística, e avaliar usando de validação cruzada
  3. Investigar, com os resultados dos folds (os subconjuntos de dados criados na validação cruzada), quais dos dois modelos nos parece melhor, usando, como dissemos, a acurácia.

Começaremos carregando os pacotes relevantes e lendo o arquivo CSV:

Depois, passaremos às transformações das variáveis. No tutorial, a primeira transformação de todas é transformar a variável Sex, que é categórica, em binária. Em seguida, ele criou colunas dummy para a variável Embarked. Também criou uma coluna que registrava quando a feature Cabin estava nula, e, por fim, criou colunas dummy a partir do Name, para identificar quando o nome possuía algum honorífico que poderia ser relevante (Mr., Ms., Master, etc.).

No tidymodels, há o conceito de recipes. A ideia é construir um fluxo de transformação de dados que seja reutilizável, facilitando o teste de modelos diferentes. Essas recipes podem ser combinadas junto com os modelos em workflows, que são então aplicados sobre os datasets.

Faremos então um recipe que transforme os dados da mesma forma como apresentado no tutorial. Note que fazemos todas as transformações e seleção de variáveis no próprio recipe, assim como cuidamos de preencher os dados nulos como -1 , da mesma forma como foi realizado no tutorial.

Mostramos esse recipe de uma única vez, mas assim como as features foram progressivamente alteradas e selecionadas no tutorial, num tutorial de tidymodel também passaríamos um bom tempo experimentando e reconstruindo-o.

Concluído o recipe, podemos passar para os modelos. Para isso, juntaremos os recipes aos modelos que testaremos em workflows específicos:

Agora, faremos a validação cruzada. No tidymodels, usamos a função vfold_cv() (V-fold Cross Validation). Por que V-fold em vez de K-fold? Bem, por que K-Fold, usuários de Python? Pois é.

Notem que os parâmetros são os mesmos usados no tutorial, divisão em duas partes com 10 repetições.

Agora poderemos aplicar a função fit_resamples(), para aplicar os workflows definidos e extrair as métricas que nos interessam. O parâmetro control serve para garantir que o dataframe de resultado irá conter uma coluna .predictions que tem as predições para cada um dos folds. Por padrão, o fit_resamples guardar apenas as métricas de resultado.

Agora, precisamos extrair o array de valores obtidos para a acurácia para os diversos folds, como obtivemos em python. O resultado da fit_resamples() é uma lista, um objeto que pode conter objetos de outros tipos. No caso, temos uma lista de dataframes, e podemos juntar todos os dataframes de uma lista com a função bind_rows() do tidyverse. Depois, selecionamos apenas a coluna .estimate para obter o valor.

Assim, podemos visualizar a acurácia dos modelos em cada fold num mesmo histograma:

Histograma da acurácia obtida em cada um dos folds para os modelos testados.

Dessa forma, pelo menos para esses parâmetros, percebemos que os modelos oscilam entre 0.79 e 0.85 de acurácia, com um viés mais favorável para o de regressão logística. Obviamente que há muito que poderia ser melhorado em engenharia de variáveis (feature engineering), seleção de outros modelos e melhoria de hiperparâmetros, mas, para uma primeira tentativa, já nos permite entender bem o uso do tidymodels.

Em conclusão…

Com isso, esperamos ter demonstrado como realizar uma análise no tidymodels. O que achamos que há de mais interessante nesse framework é o foco em reusabilidade, facilitando a iteração e exploração de modelos. O pacote, por ser muito recente e ainda estar na versão 0.1.0, ainda tem muito a desenvolver, mas espero que seja uma ferramenta que dê muita liberdade de construção e experimentação aos cientistas de dados, comparável ao que já temos no ambiente Python.

Finalizo com agradecimentos ao Mario Filho pelo fenomenal trabalho pedagógico para a comunidade de Data Science do Brasil e à Julia Silge e ao Diego Usai, que tem feito uma relevante contribuição à comunidade com seus artigos e, no caso da Julia, um curso online gratuito do Tidymodels. São recursos essenciais nesses primeiros momentos, em que o Stack Overflow ainda está raso para esse pacote.

--

--